* Re: [PATCH 11/16] netvm: Propagate page->pfmemalloc from skb_alloc_page to skb
From: Sebastian Andrzej Siewior @ 2012-06-26 20:13 UTC (permalink / raw)
To: Mel Gorman
Cc: Andrew Morton, Linux-MM, Linux-Netdev, LKML, David Miller,
Neil Brown, Peter Zijlstra, Mike Christie, Eric B Munson,
Eric Dumazet
In-Reply-To: <1340375443-22455-12-git-send-email-mgorman@suse.de>
On Fri, Jun 22, 2012 at 03:30:38PM +0100, Mel Gorman wrote:
> drivers/net/ethernet/chelsio/cxgb4/sge.c | 2 +-
> drivers/net/ethernet/chelsio/cxgb4vf/sge.c | 2 +-
> drivers/net/ethernet/intel/igb/igb_main.c | 2 +-
> drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 4 +-
> drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c | 3 +-
> drivers/net/usb/cdc-phonet.c | 2 +-
> drivers/usb/gadget/f_phonet.c | 2 +-
You did not touch all drivers which use alloc_page(s)() like e1000(e). Was
this on purpose?
Sebastian
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply
* Re: [PATCH net-next] em_canid: Ematch rule to match CAN frames according to their CAN IDs
From: Oliver Hartkopp @ 2012-06-26 20:07 UTC (permalink / raw)
To: Rostislav Lisovy, Eric Dumazet; +Cc: netdev, linux-can, lartc, pisa, sojkam1
In-Reply-To: <1340022131-7827-1-git-send-email-lisovy@gmail.com>
Hello Rostislav,
thanks for the new patch. It got indeed pretty short now :-)
I found some time for a review. See details inline ...
On 18.06.2012 14:22, Rostislav Lisovy wrote:
>
> With no extra filter/qdisc configured, median of the time spent in can_send()
> was about 27 us -- with prio qdisc with 5 bands and 5 appropriate cls_can
> filters (previous patch), it was about 30 us -- with prio qdisc with 5 bands
> and 5 appropriate em_can filters (this patch), it was about 34 us.
Hm that's more than twice the time consumed for classification ...
cls_can: 3 us more
em_can: 7 us more
@Eric: Is this still the better approach then?
> diff --git a/net/sched/Kconfig b/net/sched/Kconfig
> index 75b58f8..bc0ceab 100644
> --- a/net/sched/Kconfig
> +++ b/net/sched/Kconfig
> @@ -485,6 +485,16 @@ config NET_EMATCH_TEXT
> To compile this code as a module, choose M here: the
> module will be called em_text.
>
> +config NET_EMATCH_CANID
> + tristate "CAN ID"
i would prefer
tristate "Controller Area Network Identifier"
or at least
tristate "CAN Identifier"
> + depends on NET_EMATCH && CAN
> + ---help---
> + Say Y here if you want to be able to classify CAN frames based
> + on CAN ID.
"on the CAN Identifier."
(..)
> +#include <net/pkt_cls.h>
> +#include <linux/can.h>
> +
> +#define EM_CAN_RULES_SIZE 32
Reduce the gap before '32' to one single space.
(..)
> +static int em_canid_match(struct sk_buff *skb, struct tcf_ematch *m,
> + struct tcf_pkt_info *info)
> +{
> + struct canid_match *cm = em_canid_priv(m);
> + canid_t can_id;
> + unsigned int match = false;
You use test_bit() below which returns an int.
Better use int instead of unsigned int ...
int match = 0;
> + int i;
> +
> + can_id = em_canid_get_id(skb);
> +
> + if (can_id & CAN_EFF_FLAG) {
> + can_id &= CAN_EFF_MASK;
> +
> + for (i = 0; i < cm->eff_rules_count; i++) {
> + if (!(((cm->rules_raw[i].can_id ^ can_id) &
> + cm->rules_raw[i].can_mask) & CAN_EFF_MASK)) {
Looks really tricky. I'm still pondering if it does what it should do ...
> + match = true;
match = 1;
> + break;
> + }
> + }
> + } else { /* SFF */
> + can_id &= CAN_SFF_MASK;
> + match = test_bit(can_id, cm->match_sff);
> + }
> +
return match;
> + if (match)
> + return 1;
> +
> + return 0;
> +}
> +
> +static int em_canid_change(struct tcf_proto *tp, void *data, int len,
> + struct tcf_ematch *m)
> +{
> + struct can_filter *conf = data; /* Array with rules,
> + * fixed size EM_CAN_RULES_SIZE
> + */
> + struct canid_match *cm;
> + int err;
> + int i;
> +
> + if (len < sizeof(struct can_filter))
> + return -EINVAL;
if (len % sizeof(struct can_filter))
return -EINVAL;
if (len > sizeof(struct can_filter) * EM_CAN_RULES_SIZE)
return -EINVAL;
All checks done before kzalloc() => no need for error cleanups at the end of
the function.
> +
> + err = -ENOBUFS;
remove
> + cm = kzalloc(sizeof(*cm), GFP_KERNEL);
> + if (cm == NULL)
if (!cm)
return -ENOMEM;
> + goto errout;
The only user of errout - to be removed.
> +
> + cm->sff_rules_count = 0;
> + cm->eff_rules_count = 0;
> + cm->rules_count = len/sizeof(struct can_filter);
> + err = -EINVAL;
remove
> +
> + /* Be sure to fit into the array */
> + if (cm->rules_count > EM_CAN_RULES_SIZE)
> + goto errout_free;
already checked before => remove
> +
> + /*
> + * We need two for() loops for copying rules into
> + * two contiguous areas in rules_raw
> + */
> +
> + /* Process EFF frame rules*/
> + for (i = 0; i < cm->rules_count; i++) {
> + if ((conf[i].can_id & CAN_EFF_FLAG) &&
> + (conf[i].can_mask & CAN_EFF_FLAG)) {
> + memcpy(cm->rules_raw + cm->eff_rules_count,
Oops. Shouldn't this be
cm->rules_raw + cm->eff_rules_count * sizeof(struct can_filter),
???
> + &conf[i],
> + sizeof(struct can_filter));
> +
> + cm->eff_rules_count++;
> + } else {
> + continue;
> + }
omit { } around continue
> + }
> +
> + /* Process SFF frame rules */
> + for (i = 0; i < cm->rules_count; i++) {
> + if ((conf[i].can_id & CAN_EFF_FLAG) &&
> + (conf[i].can_mask & CAN_EFF_FLAG)) {
What if CAN_EFF_FLAG is set in can_id but not in can_mask ?
> + continue;
> + } else {
> + memcpy(cm->rules_raw
> + + cm->eff_rules_count
> + + cm->sff_rules_count,
dito
cm->rules_raw + (cm->eff_rules_count + cm->sff_rules_count) * sizeof(struct
can_filter),
???
> + &conf[i], sizeof(struct can_filter));
> +
> + cm->sff_rules_count++;
> +
> + em_canid_sff_match_add(cm,
> + conf[i].can_id, conf[i].can_mask);
> + }
> + }
> +
> + m->datalen = sizeof(*cm);
> + m->data = (unsigned long) cm;
> +
> + return 0;
> +
> +errout_free:
> + kfree(cm);
> +errout:
> + return err;
error handling can be removed with the above changes.
> +}
> +
> +static void em_canid_destroy(struct tcf_proto *tp, struct tcf_ematch *m)
> +{
> + struct canid_match *cm = em_canid_priv(m);
> +
Check for cm == NULL not needed ?
> + kfree(cm);
> +}
> +
> +static int em_canid_dump(struct sk_buff *skb, struct tcf_ematch *m)
> +{
> + struct canid_match *cm = em_canid_priv(m);
> +
Check for cm == NULL not needed ?
Can a dump happen before the matches are added??
> + /*
> + * When configuring this ematch 'rules_count' is set not to exceed
> + * 'rules_raw' array size
> + */
> + if (nla_put_nohdr(skb, sizeof(cm->rules_raw[0]) * cm->rules_count,
better sizeof(struct can_filter) instead of sizeof(cm->rules_raw[0]) ??
> + &cm->rules_raw) < 0)
> + goto nla_put_failure;
> +
> + return 0;
> +
> +nla_put_failure:
> + return -1;
> +}
> +
> +static struct tcf_ematch_ops em_canid_ops = {
> + .kind = TCF_EM_CANID,
> + .change = em_canid_change,
> + .match = em_canid_match,
> + .destroy = em_canid_destroy,
> + .dump = em_canid_dump,
> + .owner = THIS_MODULE,
> + .link = LIST_HEAD_INIT(em_canid_ops.link)
> +};
> +
> +static int __init init_em_canid(void)
> +{
> + return tcf_em_register(&em_canid_ops);
> +}
> +
> +static void __exit exit_em_canid(void)
> +{
> + tcf_em_unregister(&em_canid_ops);
> +}
> +
> +MODULE_LICENSE("GPL");
> +
> +module_init(init_em_canid);
> +module_exit(exit_em_canid);
> +
> +MODULE_ALIAS_TCF_EMATCH(TCF_EM_CANID);
Regards,
Oliver
^ permalink raw reply
* [RFC] iwmc3200top: remove driver for unavailable hardware
From: John W. Linville @ 2012-06-26 19:53 UTC (permalink / raw)
To: netdev-u79uwXL29TY76Z2rM5mHXA
Cc: samuel.ortiz-ral2JQCrhuEAvxtiuMwx3w,
inaky.perez-gonzalez-ral2JQCrhuEAvxtiuMwx3w,
linux-wireless-u79uwXL29TY76Z2rM5mHXA, John W. Linville
From: "John W. Linville" <linville-2XuSBdqkA4R54TAoqtyWWQ@public.gmane.org>
This hardware never became available to normal humans. Leaving this
driver imposes unwelcome maintenance costs for no clear benefit.
Signed-off-by: John W. Linville <linville-2XuSBdqkA4R54TAoqtyWWQ@public.gmane.org>
---
Can't remove this just yet, as it is selected by the i2400m wimax
driver. The 3200 bits of that driver seem a bit intertwined with the
rest of the driver.
Are there any other SDIO parts for i2400m? Does anyone have any other
guidance on how I can safely make i2400m be independent of iwmc3200
support?
drivers/misc/Kconfig | 1 -
drivers/misc/Makefile | 1 -
drivers/misc/iwmc3200top/Kconfig | 20 -
drivers/misc/iwmc3200top/Makefile | 29 --
drivers/misc/iwmc3200top/debugfs.c | 137 -------
drivers/misc/iwmc3200top/debugfs.h | 58 ---
drivers/misc/iwmc3200top/fw-download.c | 358 -----------------
drivers/misc/iwmc3200top/fw-msg.h | 113 ------
drivers/misc/iwmc3200top/iwmc3200top.h | 205 ----------
drivers/misc/iwmc3200top/log.c | 348 -----------------
drivers/misc/iwmc3200top/log.h | 171 ---------
drivers/misc/iwmc3200top/main.c | 662 --------------------------------
12 files changed, 2103 deletions(-)
delete mode 100644 drivers/misc/iwmc3200top/Kconfig
delete mode 100644 drivers/misc/iwmc3200top/Makefile
delete mode 100644 drivers/misc/iwmc3200top/debugfs.c
delete mode 100644 drivers/misc/iwmc3200top/debugfs.h
delete mode 100644 drivers/misc/iwmc3200top/fw-download.c
delete mode 100644 drivers/misc/iwmc3200top/fw-msg.h
delete mode 100644 drivers/misc/iwmc3200top/iwmc3200top.h
delete mode 100644 drivers/misc/iwmc3200top/log.c
delete mode 100644 drivers/misc/iwmc3200top/log.h
delete mode 100644 drivers/misc/iwmc3200top/main.c
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index 2661f6e..154f3ef 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -511,7 +511,6 @@ config USB_SWITCH_FSA9480
source "drivers/misc/c2port/Kconfig"
source "drivers/misc/eeprom/Kconfig"
source "drivers/misc/cb710/Kconfig"
-source "drivers/misc/iwmc3200top/Kconfig"
source "drivers/misc/ti-st/Kconfig"
source "drivers/misc/lis3lv02d/Kconfig"
source "drivers/misc/carma/Kconfig"
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index 456972f..b88df7a 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -36,7 +36,6 @@ obj-$(CONFIG_EP93XX_PWM) += ep93xx_pwm.o
obj-$(CONFIG_DS1682) += ds1682.o
obj-$(CONFIG_TI_DAC7512) += ti_dac7512.o
obj-$(CONFIG_C2PORT) += c2port/
-obj-$(CONFIG_IWMC3200TOP) += iwmc3200top/
obj-$(CONFIG_HMC6352) += hmc6352.o
obj-y += eeprom/
obj-y += cb710/
diff --git a/drivers/misc/iwmc3200top/Kconfig b/drivers/misc/iwmc3200top/Kconfig
deleted file mode 100644
index 9e4b88f..0000000
--- a/drivers/misc/iwmc3200top/Kconfig
+++ /dev/null
@@ -1,20 +0,0 @@
-config IWMC3200TOP
- tristate "Intel Wireless MultiCom Top Driver"
- depends on MMC && EXPERIMENTAL
- select FW_LOADER
- ---help---
- Intel Wireless MultiCom 3200 Top driver is responsible for
- for firmware load and enabled coms enumeration
-
-config IWMC3200TOP_DEBUG
- bool "Enable full debug output of iwmc3200top Driver"
- depends on IWMC3200TOP
- ---help---
- Enable full debug output of iwmc3200top Driver
-
-config IWMC3200TOP_DEBUGFS
- bool "Enable Debugfs debugging interface for iwmc3200top"
- depends on IWMC3200TOP
- ---help---
- Enable creation of debugfs files for iwmc3200top
-
diff --git a/drivers/misc/iwmc3200top/Makefile b/drivers/misc/iwmc3200top/Makefile
deleted file mode 100644
index fbf53fb..0000000
--- a/drivers/misc/iwmc3200top/Makefile
+++ /dev/null
@@ -1,29 +0,0 @@
-# iwmc3200top - Intel Wireless MultiCom 3200 Top Driver
-# drivers/misc/iwmc3200top/Makefile
-#
-# Copyright (C) 2009 Intel Corporation. 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 Street, Fifth Floor, Boston, MA
-# 02110-1301, USA.
-#
-#
-# Author Name: Maxim Grabarnik <maxim.grabarnink-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
-# -
-#
-#
-
-obj-$(CONFIG_IWMC3200TOP) += iwmc3200top.o
-iwmc3200top-objs := main.o fw-download.o
-iwmc3200top-$(CONFIG_IWMC3200TOP_DEBUG) += log.o
-iwmc3200top-$(CONFIG_IWMC3200TOP_DEBUGFS) += debugfs.o
diff --git a/drivers/misc/iwmc3200top/debugfs.c b/drivers/misc/iwmc3200top/debugfs.c
deleted file mode 100644
index 62fbaec..0000000
--- a/drivers/misc/iwmc3200top/debugfs.c
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * iwmc3200top - Intel Wireless MultiCom 3200 Top Driver
- * drivers/misc/iwmc3200top/debufs.c
- *
- * Copyright (C) 2009 Intel Corporation. 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 Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- *
- *
- * Author Name: Maxim Grabarnik <maxim.grabarnink-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
- * -
- *
- */
-
-#include <linux/kernel.h>
-#include <linux/slab.h>
-#include <linux/string.h>
-#include <linux/ctype.h>
-#include <linux/mmc/sdio_func.h>
-#include <linux/mmc/sdio.h>
-#include <linux/debugfs.h>
-
-#include "iwmc3200top.h"
-#include "fw-msg.h"
-#include "log.h"
-#include "debugfs.h"
-
-
-
-/* Constants definition */
-#define HEXADECIMAL_RADIX 16
-
-/* Functions definition */
-
-
-#define DEBUGFS_ADD(name, parent) do { \
- dbgfs->dbgfs_##parent##_files.file_##name = \
- debugfs_create_file(#name, 0644, dbgfs->dir_##parent, priv, \
- &iwmct_dbgfs_##name##_ops); \
-} while (0)
-
-#define DEBUGFS_RM(name) do { \
- debugfs_remove(name); \
- name = NULL; \
-} while (0)
-
-#define DEBUGFS_READ_FUNC(name) \
-ssize_t iwmct_dbgfs_##name##_read(struct file *file, \
- char __user *user_buf, \
- size_t count, loff_t *ppos);
-
-#define DEBUGFS_WRITE_FUNC(name) \
-ssize_t iwmct_dbgfs_##name##_write(struct file *file, \
- const char __user *user_buf, \
- size_t count, loff_t *ppos);
-
-#define DEBUGFS_READ_FILE_OPS(name) \
- DEBUGFS_READ_FUNC(name) \
- static const struct file_operations iwmct_dbgfs_##name##_ops = { \
- .read = iwmct_dbgfs_##name##_read, \
- .open = iwmct_dbgfs_open_file_generic, \
- .llseek = generic_file_llseek, \
- };
-
-#define DEBUGFS_WRITE_FILE_OPS(name) \
- DEBUGFS_WRITE_FUNC(name) \
- static const struct file_operations iwmct_dbgfs_##name##_ops = { \
- .write = iwmct_dbgfs_##name##_write, \
- .open = iwmct_dbgfs_open_file_generic, \
- .llseek = generic_file_llseek, \
- };
-
-#define DEBUGFS_READ_WRITE_FILE_OPS(name) \
- DEBUGFS_READ_FUNC(name) \
- DEBUGFS_WRITE_FUNC(name) \
- static const struct file_operations iwmct_dbgfs_##name##_ops = {\
- .write = iwmct_dbgfs_##name##_write, \
- .read = iwmct_dbgfs_##name##_read, \
- .open = iwmct_dbgfs_open_file_generic, \
- .llseek = generic_file_llseek, \
- };
-
-
-/* Debugfs file ops definitions */
-
-/*
- * Create the debugfs files and directories
- *
- */
-void iwmct_dbgfs_register(struct iwmct_priv *priv, const char *name)
-{
- struct iwmct_debugfs *dbgfs;
-
- dbgfs = kzalloc(sizeof(struct iwmct_debugfs), GFP_KERNEL);
- if (!dbgfs) {
- LOG_ERROR(priv, DEBUGFS, "failed to allocate %zd bytes\n",
- sizeof(struct iwmct_debugfs));
- return;
- }
-
- priv->dbgfs = dbgfs;
- dbgfs->name = name;
- dbgfs->dir_drv = debugfs_create_dir(name, NULL);
- if (!dbgfs->dir_drv) {
- LOG_ERROR(priv, DEBUGFS, "failed to create debugfs dir\n");
- return;
- }
-
- return;
-}
-
-/**
- * Remove the debugfs files and directories
- *
- */
-void iwmct_dbgfs_unregister(struct iwmct_debugfs *dbgfs)
-{
- if (!dbgfs)
- return;
-
- DEBUGFS_RM(dbgfs->dir_drv);
- kfree(dbgfs);
- dbgfs = NULL;
-}
-
diff --git a/drivers/misc/iwmc3200top/debugfs.h b/drivers/misc/iwmc3200top/debugfs.h
deleted file mode 100644
index 71d4575..0000000
--- a/drivers/misc/iwmc3200top/debugfs.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * iwmc3200top - Intel Wireless MultiCom 3200 Top Driver
- * drivers/misc/iwmc3200top/debufs.h
- *
- * Copyright (C) 2009 Intel Corporation. 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 Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- *
- *
- * Author Name: Maxim Grabarnik <maxim.grabarnink-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
- * -
- *
- */
-
-#ifndef __DEBUGFS_H__
-#define __DEBUGFS_H__
-
-
-#ifdef CONFIG_IWMC3200TOP_DEBUGFS
-
-struct iwmct_debugfs {
- const char *name;
- struct dentry *dir_drv;
- struct dir_drv_files {
- } dbgfs_drv_files;
-};
-
-void iwmct_dbgfs_register(struct iwmct_priv *priv, const char *name);
-void iwmct_dbgfs_unregister(struct iwmct_debugfs *dbgfs);
-
-#else /* CONFIG_IWMC3200TOP_DEBUGFS */
-
-struct iwmct_debugfs;
-
-static inline void
-iwmct_dbgfs_register(struct iwmct_priv *priv, const char *name)
-{}
-
-static inline void
-iwmct_dbgfs_unregister(struct iwmct_debugfs *dbgfs)
-{}
-
-#endif /* CONFIG_IWMC3200TOP_DEBUGFS */
-
-#endif /* __DEBUGFS_H__ */
-
diff --git a/drivers/misc/iwmc3200top/fw-download.c b/drivers/misc/iwmc3200top/fw-download.c
deleted file mode 100644
index e27afde..0000000
--- a/drivers/misc/iwmc3200top/fw-download.c
+++ /dev/null
@@ -1,358 +0,0 @@
-/*
- * iwmc3200top - Intel Wireless MultiCom 3200 Top Driver
- * drivers/misc/iwmc3200top/fw-download.c
- *
- * Copyright (C) 2009 Intel Corporation. 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 Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- *
- *
- * Author Name: Maxim Grabarnik <maxim.grabarnink-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
- * -
- *
- */
-
-#include <linux/firmware.h>
-#include <linux/mmc/sdio_func.h>
-#include <linux/slab.h>
-#include <asm/unaligned.h>
-
-#include "iwmc3200top.h"
-#include "log.h"
-#include "fw-msg.h"
-
-#define CHECKSUM_BYTES_NUM sizeof(u32)
-
-/**
- init parser struct with file
- */
-static int iwmct_fw_parser_init(struct iwmct_priv *priv, const u8 *file,
- size_t file_size, size_t block_size)
-{
- struct iwmct_parser *parser = &priv->parser;
- struct iwmct_fw_hdr *fw_hdr = &parser->versions;
-
- LOG_TRACE(priv, FW_DOWNLOAD, "-->\n");
-
- LOG_INFO(priv, FW_DOWNLOAD, "file_size=%zd\n", file_size);
-
- parser->file = file;
- parser->file_size = file_size;
- parser->cur_pos = 0;
- parser->entry_point = 0;
- parser->buf = kzalloc(block_size, GFP_KERNEL);
- if (!parser->buf) {
- LOG_ERROR(priv, FW_DOWNLOAD, "kzalloc error\n");
- return -ENOMEM;
- }
- parser->buf_size = block_size;
-
- /* extract fw versions */
- memcpy(fw_hdr, parser->file, sizeof(struct iwmct_fw_hdr));
- LOG_INFO(priv, FW_DOWNLOAD, "fw versions are:\n"
- "top %u.%u.%u gps %u.%u.%u bt %u.%u.%u tic %s\n",
- fw_hdr->top_major, fw_hdr->top_minor, fw_hdr->top_revision,
- fw_hdr->gps_major, fw_hdr->gps_minor, fw_hdr->gps_revision,
- fw_hdr->bt_major, fw_hdr->bt_minor, fw_hdr->bt_revision,
- fw_hdr->tic_name);
-
- parser->cur_pos += sizeof(struct iwmct_fw_hdr);
-
- LOG_TRACE(priv, FW_DOWNLOAD, "<--\n");
- return 0;
-}
-
-static bool iwmct_checksum(struct iwmct_priv *priv)
-{
- struct iwmct_parser *parser = &priv->parser;
- __le32 *file = (__le32 *)parser->file;
- int i, pad, steps;
- u32 accum = 0;
- u32 checksum;
- u32 mask = 0xffffffff;
-
- pad = (parser->file_size - CHECKSUM_BYTES_NUM) % 4;
- steps = (parser->file_size - CHECKSUM_BYTES_NUM) / 4;
-
- LOG_INFO(priv, FW_DOWNLOAD, "pad=%d steps=%d\n", pad, steps);
-
- for (i = 0; i < steps; i++)
- accum += le32_to_cpu(file[i]);
-
- if (pad) {
- mask <<= 8 * (4 - pad);
- accum += le32_to_cpu(file[steps]) & mask;
- }
-
- checksum = get_unaligned_le32((__le32 *)(parser->file +
- parser->file_size - CHECKSUM_BYTES_NUM));
-
- LOG_INFO(priv, FW_DOWNLOAD,
- "compare checksum accum=0x%x to checksum=0x%x\n",
- accum, checksum);
-
- return checksum == accum;
-}
-
-static int iwmct_parse_next_section(struct iwmct_priv *priv, const u8 **p_sec,
- size_t *sec_size, __le32 *sec_addr)
-{
- struct iwmct_parser *parser = &priv->parser;
- struct iwmct_dbg *dbg = &priv->dbg;
- struct iwmct_fw_sec_hdr *sec_hdr;
-
- LOG_TRACE(priv, FW_DOWNLOAD, "-->\n");
-
- while (parser->cur_pos + sizeof(struct iwmct_fw_sec_hdr)
- <= parser->file_size) {
-
- sec_hdr = (struct iwmct_fw_sec_hdr *)
- (parser->file + parser->cur_pos);
- parser->cur_pos += sizeof(struct iwmct_fw_sec_hdr);
-
- LOG_INFO(priv, FW_DOWNLOAD,
- "sec hdr: type=%s addr=0x%x size=%d\n",
- sec_hdr->type, sec_hdr->target_addr,
- sec_hdr->data_size);
-
- if (strcmp(sec_hdr->type, "ENT") == 0)
- parser->entry_point = le32_to_cpu(sec_hdr->target_addr);
- else if (strcmp(sec_hdr->type, "LBL") == 0)
- strcpy(dbg->label_fw, parser->file + parser->cur_pos);
- else if (((strcmp(sec_hdr->type, "TOP") == 0) &&
- (priv->barker & BARKER_DNLOAD_TOP_MSK)) ||
- ((strcmp(sec_hdr->type, "GPS") == 0) &&
- (priv->barker & BARKER_DNLOAD_GPS_MSK)) ||
- ((strcmp(sec_hdr->type, "BTH") == 0) &&
- (priv->barker & BARKER_DNLOAD_BT_MSK))) {
- *sec_addr = sec_hdr->target_addr;
- *sec_size = le32_to_cpu(sec_hdr->data_size);
- *p_sec = parser->file + parser->cur_pos;
- parser->cur_pos += le32_to_cpu(sec_hdr->data_size);
- return 1;
- } else if (strcmp(sec_hdr->type, "LOG") != 0)
- LOG_WARNING(priv, FW_DOWNLOAD,
- "skipping section type %s\n",
- sec_hdr->type);
-
- parser->cur_pos += le32_to_cpu(sec_hdr->data_size);
- LOG_INFO(priv, FW_DOWNLOAD,
- "finished with section cur_pos=%zd\n", parser->cur_pos);
- }
-
- LOG_TRACE(priv, INIT, "<--\n");
- return 0;
-}
-
-static int iwmct_download_section(struct iwmct_priv *priv, const u8 *p_sec,
- size_t sec_size, __le32 addr)
-{
- struct iwmct_parser *parser = &priv->parser;
- struct iwmct_fw_load_hdr *hdr = (struct iwmct_fw_load_hdr *)parser->buf;
- const u8 *cur_block = p_sec;
- size_t sent = 0;
- int cnt = 0;
- int ret = 0;
- u32 cmd = 0;
-
- LOG_TRACE(priv, FW_DOWNLOAD, "-->\n");
- LOG_INFO(priv, FW_DOWNLOAD, "Download address 0x%x size 0x%zx\n",
- addr, sec_size);
-
- while (sent < sec_size) {
- int i;
- u32 chksm = 0;
- u32 reset = atomic_read(&priv->reset);
- /* actual FW data */
- u32 data_size = min(parser->buf_size - sizeof(*hdr),
- sec_size - sent);
- /* Pad to block size */
- u32 trans_size = (data_size + sizeof(*hdr) +
- IWMC_SDIO_BLK_SIZE - 1) &
- ~(IWMC_SDIO_BLK_SIZE - 1);
- ++cnt;
-
- /* in case of reset, interrupt FW DOWNLAOD */
- if (reset) {
- LOG_INFO(priv, FW_DOWNLOAD,
- "Reset detected. Abort FW download!!!");
- ret = -ECANCELED;
- goto exit;
- }
-
- memset(parser->buf, 0, parser->buf_size);
- cmd |= IWMC_OPCODE_WRITE << CMD_HDR_OPCODE_POS;
- cmd |= IWMC_CMD_SIGNATURE << CMD_HDR_SIGNATURE_POS;
- cmd |= (priv->dbg.direct ? 1 : 0) << CMD_HDR_DIRECT_ACCESS_POS;
- cmd |= (priv->dbg.checksum ? 1 : 0) << CMD_HDR_USE_CHECKSUM_POS;
- hdr->data_size = cpu_to_le32(data_size);
- hdr->target_addr = addr;
-
- /* checksum is allowed for sizes divisible by 4 */
- if (data_size & 0x3)
- cmd &= ~CMD_HDR_USE_CHECKSUM_MSK;
-
- memcpy(hdr->data, cur_block, data_size);
-
-
- if (cmd & CMD_HDR_USE_CHECKSUM_MSK) {
-
- chksm = data_size + le32_to_cpu(addr) + cmd;
- for (i = 0; i < data_size >> 2; i++)
- chksm += ((u32 *)cur_block)[i];
-
- hdr->block_chksm = cpu_to_le32(chksm);
- LOG_INFO(priv, FW_DOWNLOAD, "Checksum = 0x%X\n",
- hdr->block_chksm);
- }
-
- LOG_INFO(priv, FW_DOWNLOAD, "trans#%d, len=%d, sent=%zd, "
- "sec_size=%zd, startAddress 0x%X\n",
- cnt, trans_size, sent, sec_size, addr);
-
- if (priv->dbg.dump)
- LOG_HEXDUMP(FW_DOWNLOAD, parser->buf, trans_size);
-
-
- hdr->cmd = cpu_to_le32(cmd);
- /* send it down */
- /* TODO: add more proper sending and error checking */
- ret = iwmct_tx(priv, parser->buf, trans_size);
- if (ret != 0) {
- LOG_INFO(priv, FW_DOWNLOAD,
- "iwmct_tx returned %d\n", ret);
- goto exit;
- }
-
- addr = cpu_to_le32(le32_to_cpu(addr) + data_size);
- sent += data_size;
- cur_block = p_sec + sent;
-
- if (priv->dbg.blocks && (cnt + 1) >= priv->dbg.blocks) {
- LOG_INFO(priv, FW_DOWNLOAD,
- "Block number limit is reached [%d]\n",
- priv->dbg.blocks);
- break;
- }
- }
-
- if (sent < sec_size)
- ret = -EINVAL;
-exit:
- LOG_TRACE(priv, FW_DOWNLOAD, "<--\n");
- return ret;
-}
-
-static int iwmct_kick_fw(struct iwmct_priv *priv, bool jump)
-{
- struct iwmct_parser *parser = &priv->parser;
- struct iwmct_fw_load_hdr *hdr = (struct iwmct_fw_load_hdr *)parser->buf;
- int ret;
- u32 cmd;
-
- LOG_TRACE(priv, FW_DOWNLOAD, "-->\n");
-
- memset(parser->buf, 0, parser->buf_size);
- cmd = IWMC_CMD_SIGNATURE << CMD_HDR_SIGNATURE_POS;
- if (jump) {
- cmd |= IWMC_OPCODE_JUMP << CMD_HDR_OPCODE_POS;
- hdr->target_addr = cpu_to_le32(parser->entry_point);
- LOG_INFO(priv, FW_DOWNLOAD, "jump address 0x%x\n",
- parser->entry_point);
- } else {
- cmd |= IWMC_OPCODE_LAST_COMMAND << CMD_HDR_OPCODE_POS;
- LOG_INFO(priv, FW_DOWNLOAD, "last command\n");
- }
-
- hdr->cmd = cpu_to_le32(cmd);
-
- LOG_HEXDUMP(FW_DOWNLOAD, parser->buf, sizeof(*hdr));
- /* send it down */
- /* TODO: add more proper sending and error checking */
- ret = iwmct_tx(priv, parser->buf, IWMC_SDIO_BLK_SIZE);
- if (ret)
- LOG_INFO(priv, FW_DOWNLOAD, "iwmct_tx returned %d", ret);
-
- LOG_TRACE(priv, FW_DOWNLOAD, "<--\n");
- return 0;
-}
-
-int iwmct_fw_load(struct iwmct_priv *priv)
-{
- const u8 *fw_name = FW_NAME(FW_API_VER);
- const struct firmware *raw;
- const u8 *pdata;
- size_t len;
- __le32 addr;
- int ret;
-
-
- LOG_INFO(priv, FW_DOWNLOAD, "barker download request 0x%x is:\n",
- priv->barker);
- LOG_INFO(priv, FW_DOWNLOAD, "******* Top FW %s requested ********\n",
- (priv->barker & BARKER_DNLOAD_TOP_MSK) ? "was" : "not");
- LOG_INFO(priv, FW_DOWNLOAD, "******* GPS FW %s requested ********\n",
- (priv->barker & BARKER_DNLOAD_GPS_MSK) ? "was" : "not");
- LOG_INFO(priv, FW_DOWNLOAD, "******* BT FW %s requested ********\n",
- (priv->barker & BARKER_DNLOAD_BT_MSK) ? "was" : "not");
-
-
- /* get the firmware */
- ret = request_firmware(&raw, fw_name, &priv->func->dev);
- if (ret < 0) {
- LOG_ERROR(priv, FW_DOWNLOAD, "%s request_firmware failed %d\n",
- fw_name, ret);
- goto exit;
- }
-
- if (raw->size < sizeof(struct iwmct_fw_sec_hdr)) {
- LOG_ERROR(priv, FW_DOWNLOAD, "%s smaller then (%zd) (%zd)\n",
- fw_name, sizeof(struct iwmct_fw_sec_hdr), raw->size);
- goto exit;
- }
-
- LOG_INFO(priv, FW_DOWNLOAD, "Read firmware '%s'\n", fw_name);
-
- /* clear parser struct */
- ret = iwmct_fw_parser_init(priv, raw->data, raw->size, priv->trans_len);
- if (ret < 0) {
- LOG_ERROR(priv, FW_DOWNLOAD,
- "iwmct_parser_init failed: Reason %d\n", ret);
- goto exit;
- }
-
- if (!iwmct_checksum(priv)) {
- LOG_ERROR(priv, FW_DOWNLOAD, "checksum error\n");
- ret = -EINVAL;
- goto exit;
- }
-
- /* download firmware to device */
- while (iwmct_parse_next_section(priv, &pdata, &len, &addr)) {
- ret = iwmct_download_section(priv, pdata, len, addr);
- if (ret) {
- LOG_ERROR(priv, FW_DOWNLOAD,
- "%s download section failed\n", fw_name);
- goto exit;
- }
- }
-
- ret = iwmct_kick_fw(priv, !!(priv->barker & BARKER_DNLOAD_JUMP_MSK));
-
-exit:
- kfree(priv->parser.buf);
- release_firmware(raw);
- return ret;
-}
diff --git a/drivers/misc/iwmc3200top/fw-msg.h b/drivers/misc/iwmc3200top/fw-msg.h
deleted file mode 100644
index 9e26b75..0000000
--- a/drivers/misc/iwmc3200top/fw-msg.h
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * iwmc3200top - Intel Wireless MultiCom 3200 Top Driver
- * drivers/misc/iwmc3200top/fw-msg.h
- *
- * Copyright (C) 2009 Intel Corporation. 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 Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- *
- *
- * Author Name: Maxim Grabarnik <maxim.grabarnink-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
- * -
- *
- */
-
-#ifndef __FWMSG_H__
-#define __FWMSG_H__
-
-#define COMM_TYPE_D2H 0xFF
-#define COMM_TYPE_H2D 0xEE
-
-#define COMM_CATEGORY_OPERATIONAL 0x00
-#define COMM_CATEGORY_DEBUG 0x01
-#define COMM_CATEGORY_TESTABILITY 0x02
-#define COMM_CATEGORY_DIAGNOSTICS 0x03
-
-#define OP_DBG_ZSTR_MSG cpu_to_le16(0x1A)
-
-#define FW_LOG_SRC_MAX 32
-#define FW_LOG_SRC_ALL 255
-
-#define FW_STRING_TABLE_ADDR cpu_to_le32(0x0C000000)
-
-#define CMD_DBG_LOG_LEVEL cpu_to_le16(0x0001)
-#define CMD_TST_DEV_RESET cpu_to_le16(0x0060)
-#define CMD_TST_FUNC_RESET cpu_to_le16(0x0062)
-#define CMD_TST_IFACE_RESET cpu_to_le16(0x0064)
-#define CMD_TST_CPU_UTILIZATION cpu_to_le16(0x0065)
-#define CMD_TST_TOP_DEEP_SLEEP cpu_to_le16(0x0080)
-#define CMD_TST_WAKEUP cpu_to_le16(0x0081)
-#define CMD_TST_FUNC_WAKEUP cpu_to_le16(0x0082)
-#define CMD_TST_FUNC_DEEP_SLEEP_REQUEST cpu_to_le16(0x0083)
-#define CMD_TST_GET_MEM_DUMP cpu_to_le16(0x0096)
-
-#define OP_OPR_ALIVE cpu_to_le16(0x0010)
-#define OP_OPR_CMD_ACK cpu_to_le16(0x001F)
-#define OP_OPR_CMD_NACK cpu_to_le16(0x0020)
-#define OP_TST_MEM_DUMP cpu_to_le16(0x0043)
-
-#define CMD_FLAG_PADDING_256 0x80
-
-#define FW_HCMD_BLOCK_SIZE 256
-
-struct msg_hdr {
- u8 type;
- u8 category;
- __le16 opcode;
- u8 seqnum;
- u8 flags;
- __le16 length;
-} __attribute__((__packed__));
-
-struct log_hdr {
- __le32 timestamp;
- u8 severity;
- u8 logsource;
- __le16 reserved;
-} __attribute__((__packed__));
-
-struct mdump_hdr {
- u8 dmpid;
- u8 frag;
- __le16 size;
- __le32 addr;
-} __attribute__((__packed__));
-
-struct top_msg {
- struct msg_hdr hdr;
- union {
- /* D2H messages */
- struct {
- struct log_hdr log_hdr;
- u8 data[1];
- } __attribute__((__packed__)) log;
-
- struct {
- struct log_hdr log_hdr;
- struct mdump_hdr md_hdr;
- u8 data[1];
- } __attribute__((__packed__)) mdump;
-
- /* H2D messages */
- struct {
- u8 logsource;
- u8 sevmask;
- } __attribute__((__packed__)) logdefs[FW_LOG_SRC_MAX];
- struct mdump_hdr mdump_req;
- } u;
-} __attribute__((__packed__));
-
-
-#endif /* __FWMSG_H__ */
diff --git a/drivers/misc/iwmc3200top/iwmc3200top.h b/drivers/misc/iwmc3200top/iwmc3200top.h
deleted file mode 100644
index 620973e..0000000
--- a/drivers/misc/iwmc3200top/iwmc3200top.h
+++ /dev/null
@@ -1,205 +0,0 @@
-/*
- * iwmc3200top - Intel Wireless MultiCom 3200 Top Driver
- * drivers/misc/iwmc3200top/iwmc3200top.h
- *
- * Copyright (C) 2009 Intel Corporation. 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 Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- *
- *
- * Author Name: Maxim Grabarnik <maxim.grabarnink-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
- * -
- *
- */
-
-#ifndef __IWMC3200TOP_H__
-#define __IWMC3200TOP_H__
-
-#include <linux/workqueue.h>
-
-#define DRV_NAME "iwmc3200top"
-#define FW_API_VER 1
-#define _FW_NAME(api) DRV_NAME "." #api ".fw"
-#define FW_NAME(api) _FW_NAME(api)
-
-#define IWMC_SDIO_BLK_SIZE 256
-#define IWMC_DEFAULT_TR_BLK 64
-#define IWMC_SDIO_DATA_ADDR 0x0
-#define IWMC_SDIO_INTR_ENABLE_ADDR 0x14
-#define IWMC_SDIO_INTR_STATUS_ADDR 0x13
-#define IWMC_SDIO_INTR_CLEAR_ADDR 0x13
-#define IWMC_SDIO_INTR_GET_SIZE_ADDR 0x2C
-
-#define COMM_HUB_HEADER_LENGTH 16
-#define LOGGER_HEADER_LENGTH 10
-
-
-#define BARKER_DNLOAD_BT_POS 0
-#define BARKER_DNLOAD_BT_MSK BIT(BARKER_DNLOAD_BT_POS)
-#define BARKER_DNLOAD_GPS_POS 1
-#define BARKER_DNLOAD_GPS_MSK BIT(BARKER_DNLOAD_GPS_POS)
-#define BARKER_DNLOAD_TOP_POS 2
-#define BARKER_DNLOAD_TOP_MSK BIT(BARKER_DNLOAD_TOP_POS)
-#define BARKER_DNLOAD_RESERVED1_POS 3
-#define BARKER_DNLOAD_RESERVED1_MSK BIT(BARKER_DNLOAD_RESERVED1_POS)
-#define BARKER_DNLOAD_JUMP_POS 4
-#define BARKER_DNLOAD_JUMP_MSK BIT(BARKER_DNLOAD_JUMP_POS)
-#define BARKER_DNLOAD_SYNC_POS 5
-#define BARKER_DNLOAD_SYNC_MSK BIT(BARKER_DNLOAD_SYNC_POS)
-#define BARKER_DNLOAD_RESERVED2_POS 6
-#define BARKER_DNLOAD_RESERVED2_MSK (0x3 << BARKER_DNLOAD_RESERVED2_POS)
-#define BARKER_DNLOAD_BARKER_POS 8
-#define BARKER_DNLOAD_BARKER_MSK (0xffffff << BARKER_DNLOAD_BARKER_POS)
-
-#define IWMC_BARKER_REBOOT (0xdeadbe << BARKER_DNLOAD_BARKER_POS)
-/* whole field barker */
-#define IWMC_BARKER_ACK 0xfeedbabe
-
-#define IWMC_CMD_SIGNATURE 0xcbbc
-
-#define CMD_HDR_OPCODE_POS 0
-#define CMD_HDR_OPCODE_MSK_MSK (0xf << CMD_HDR_OPCODE_MSK_POS)
-#define CMD_HDR_RESPONSE_CODE_POS 4
-#define CMD_HDR_RESPONSE_CODE_MSK (0xf << CMD_HDR_RESPONSE_CODE_POS)
-#define CMD_HDR_USE_CHECKSUM_POS 8
-#define CMD_HDR_USE_CHECKSUM_MSK BIT(CMD_HDR_USE_CHECKSUM_POS)
-#define CMD_HDR_RESPONSE_REQUIRED_POS 9
-#define CMD_HDR_RESPONSE_REQUIRED_MSK BIT(CMD_HDR_RESPONSE_REQUIRED_POS)
-#define CMD_HDR_DIRECT_ACCESS_POS 10
-#define CMD_HDR_DIRECT_ACCESS_MSK BIT(CMD_HDR_DIRECT_ACCESS_POS)
-#define CMD_HDR_RESERVED_POS 11
-#define CMD_HDR_RESERVED_MSK BIT(0x1f << CMD_HDR_RESERVED_POS)
-#define CMD_HDR_SIGNATURE_POS 16
-#define CMD_HDR_SIGNATURE_MSK BIT(0xffff << CMD_HDR_SIGNATURE_POS)
-
-enum {
- IWMC_OPCODE_PING = 0,
- IWMC_OPCODE_READ = 1,
- IWMC_OPCODE_WRITE = 2,
- IWMC_OPCODE_JUMP = 3,
- IWMC_OPCODE_REBOOT = 4,
- IWMC_OPCODE_PERSISTENT_WRITE = 5,
- IWMC_OPCODE_PERSISTENT_READ = 6,
- IWMC_OPCODE_READ_MODIFY_WRITE = 7,
- IWMC_OPCODE_LAST_COMMAND = 15
-};
-
-struct iwmct_fw_load_hdr {
- __le32 cmd;
- __le32 target_addr;
- __le32 data_size;
- __le32 block_chksm;
- u8 data[0];
-};
-
-/**
- * struct iwmct_fw_hdr
- * holds all sw components versions
- */
-struct iwmct_fw_hdr {
- u8 top_major;
- u8 top_minor;
- u8 top_revision;
- u8 gps_major;
- u8 gps_minor;
- u8 gps_revision;
- u8 bt_major;
- u8 bt_minor;
- u8 bt_revision;
- u8 tic_name[31];
-};
-
-/**
- * struct iwmct_fw_sec_hdr
- * @type: function type
- * @data_size: section's data size
- * @target_addr: download address
- */
-struct iwmct_fw_sec_hdr {
- u8 type[4];
- __le32 data_size;
- __le32 target_addr;
-};
-
-/**
- * struct iwmct_parser
- * @file: fw image
- * @file_size: fw size
- * @cur_pos: position in file
- * @buf: temp buf for download
- * @buf_size: size of buf
- * @entry_point: address to jump in fw kick-off
- */
-struct iwmct_parser {
- const u8 *file;
- size_t file_size;
- size_t cur_pos;
- u8 *buf;
- size_t buf_size;
- u32 entry_point;
- struct iwmct_fw_hdr versions;
-};
-
-
-struct iwmct_work_struct {
- struct list_head list;
- ssize_t iosize;
-};
-
-struct iwmct_dbg {
- int blocks;
- bool dump;
- bool jump;
- bool direct;
- bool checksum;
- bool fw_download;
- int block_size;
- int download_trans_blks;
-
- char label_fw[256];
-};
-
-struct iwmct_debugfs;
-
-struct iwmct_priv {
- struct sdio_func *func;
- struct iwmct_debugfs *dbgfs;
- struct iwmct_parser parser;
- atomic_t reset;
- atomic_t dev_sync;
- u32 trans_len;
- u32 barker;
- struct iwmct_dbg dbg;
-
- /* drivers work items */
- struct work_struct bus_rescan_worker;
- struct work_struct isr_worker;
-
- /* drivers wait queue */
- wait_queue_head_t wait_q;
-
- /* rx request list */
- struct list_head read_req_list;
-};
-
-extern int iwmct_tx(struct iwmct_priv *priv, void *src, int count);
-extern int iwmct_fw_load(struct iwmct_priv *priv);
-
-extern void iwmct_dbg_init_params(struct iwmct_priv *drv);
-extern void iwmct_dbg_init_drv_attrs(struct device_driver *drv);
-extern void iwmct_dbg_remove_drv_attrs(struct device_driver *drv);
-extern int iwmct_send_hcmd(struct iwmct_priv *priv, u8 *cmd, u16 len);
-
-#endif /* __IWMC3200TOP_H__ */
diff --git a/drivers/misc/iwmc3200top/log.c b/drivers/misc/iwmc3200top/log.c
deleted file mode 100644
index a36a55a..0000000
--- a/drivers/misc/iwmc3200top/log.c
+++ /dev/null
@@ -1,348 +0,0 @@
-/*
- * iwmc3200top - Intel Wireless MultiCom 3200 Top Driver
- * drivers/misc/iwmc3200top/log.c
- *
- * Copyright (C) 2009 Intel Corporation. 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 Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- *
- *
- * Author Name: Maxim Grabarnik <maxim.grabarnink-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
- * -
- *
- */
-
-#include <linux/kernel.h>
-#include <linux/mmc/sdio_func.h>
-#include <linux/slab.h>
-#include <linux/ctype.h>
-#include "fw-msg.h"
-#include "iwmc3200top.h"
-#include "log.h"
-
-/* Maximal hexadecimal string size of the FW memdump message */
-#define LOG_MSG_SIZE_MAX 12400
-
-/* iwmct_logdefs is a global used by log macros */
-u8 iwmct_logdefs[LOG_SRC_MAX];
-static u8 iwmct_fw_logdefs[FW_LOG_SRC_MAX];
-
-
-static int _log_set_log_filter(u8 *logdefs, int size, u8 src, u8 logmask)
-{
- int i;
-
- if (src < size)
- logdefs[src] = logmask;
- else if (src == LOG_SRC_ALL)
- for (i = 0; i < size; i++)
- logdefs[i] = logmask;
- else
- return -1;
-
- return 0;
-}
-
-
-int iwmct_log_set_filter(u8 src, u8 logmask)
-{
- return _log_set_log_filter(iwmct_logdefs, LOG_SRC_MAX, src, logmask);
-}
-
-
-int iwmct_log_set_fw_filter(u8 src, u8 logmask)
-{
- return _log_set_log_filter(iwmct_fw_logdefs,
- FW_LOG_SRC_MAX, src, logmask);
-}
-
-
-static int log_msg_format_hex(char *str, int slen, u8 *ibuf,
- int ilen, char *pref)
-{
- int pos = 0;
- int i;
- int len;
-
- for (pos = 0, i = 0; pos < slen - 2 && pref[i] != '\0'; i++, pos++)
- str[pos] = pref[i];
-
- for (i = 0; pos < slen - 2 && i < ilen; pos += len, i++)
- len = snprintf(&str[pos], slen - pos - 1, " %2.2X", ibuf[i]);
-
- if (i < ilen)
- return -1;
-
- return 0;
-}
-
-/* NOTE: This function is not thread safe.
- Currently it's called only from sdio rx worker - no race there
-*/
-void iwmct_log_top_message(struct iwmct_priv *priv, u8 *buf, int len)
-{
- struct top_msg *msg;
- static char logbuf[LOG_MSG_SIZE_MAX];
-
- msg = (struct top_msg *)buf;
-
- if (len < sizeof(msg->hdr) + sizeof(msg->u.log.log_hdr)) {
- LOG_ERROR(priv, FW_MSG, "Log message from TOP "
- "is too short %d (expected %zd)\n",
- len, sizeof(msg->hdr) + sizeof(msg->u.log.log_hdr));
- return;
- }
-
- if (!(iwmct_fw_logdefs[msg->u.log.log_hdr.logsource] &
- BIT(msg->u.log.log_hdr.severity)) ||
- !(iwmct_logdefs[LOG_SRC_FW_MSG] & BIT(msg->u.log.log_hdr.severity)))
- return;
-
- switch (msg->hdr.category) {
- case COMM_CATEGORY_TESTABILITY:
- if (!(iwmct_logdefs[LOG_SRC_TST] &
- BIT(msg->u.log.log_hdr.severity)))
- return;
- if (log_msg_format_hex(logbuf, LOG_MSG_SIZE_MAX, buf,
- le16_to_cpu(msg->hdr.length) +
- sizeof(msg->hdr), "<TST>"))
- LOG_WARNING(priv, TST,
- "TOP TST message is too long, truncating...");
- LOG_WARNING(priv, TST, "%s\n", logbuf);
- break;
- case COMM_CATEGORY_DEBUG:
- if (msg->hdr.opcode == OP_DBG_ZSTR_MSG)
- LOG_INFO(priv, FW_MSG, "%s %s", "<DBG>",
- ((u8 *)msg) + sizeof(msg->hdr)
- + sizeof(msg->u.log.log_hdr));
- else {
- if (log_msg_format_hex(logbuf, LOG_MSG_SIZE_MAX, buf,
- le16_to_cpu(msg->hdr.length)
- + sizeof(msg->hdr),
- "<DBG>"))
- LOG_WARNING(priv, FW_MSG,
- "TOP DBG message is too long,"
- "truncating...");
- LOG_WARNING(priv, FW_MSG, "%s\n", logbuf);
- }
- break;
- default:
- break;
- }
-}
-
-static int _log_get_filter_str(u8 *logdefs, int logdefsz, char *buf, int size)
-{
- int i, pos, len;
- for (i = 0, pos = 0; (pos < size-1) && (i < logdefsz); i++) {
- len = snprintf(&buf[pos], size - pos - 1, "0x%02X%02X,",
- i, logdefs[i]);
- pos += len;
- }
- buf[pos-1] = '\n';
- buf[pos] = '\0';
-
- if (i < logdefsz)
- return -1;
- return 0;
-}
-
-int log_get_filter_str(char *buf, int size)
-{
- return _log_get_filter_str(iwmct_logdefs, LOG_SRC_MAX, buf, size);
-}
-
-int log_get_fw_filter_str(char *buf, int size)
-{
- return _log_get_filter_str(iwmct_fw_logdefs, FW_LOG_SRC_MAX, buf, size);
-}
-
-#define HEXADECIMAL_RADIX 16
-#define LOG_SRC_FORMAT 7 /* log level is in format of "0xXXXX," */
-
-ssize_t show_iwmct_log_level(struct device *d,
- struct device_attribute *attr, char *buf)
-{
- struct iwmct_priv *priv = dev_get_drvdata(d);
- char *str_buf;
- int buf_size;
- ssize_t ret;
-
- buf_size = (LOG_SRC_FORMAT * LOG_SRC_MAX) + 1;
- str_buf = kzalloc(buf_size, GFP_KERNEL);
- if (!str_buf) {
- LOG_ERROR(priv, DEBUGFS,
- "failed to allocate %d bytes\n", buf_size);
- ret = -ENOMEM;
- goto exit;
- }
-
- if (log_get_filter_str(str_buf, buf_size) < 0) {
- ret = -EINVAL;
- goto exit;
- }
-
- ret = sprintf(buf, "%s", str_buf);
-
-exit:
- kfree(str_buf);
- return ret;
-}
-
-ssize_t store_iwmct_log_level(struct device *d,
- struct device_attribute *attr,
- const char *buf, size_t count)
-{
- struct iwmct_priv *priv = dev_get_drvdata(d);
- char *token, *str_buf = NULL;
- long val;
- ssize_t ret = count;
- u8 src, mask;
-
- if (!count)
- goto exit;
-
- str_buf = kzalloc(count, GFP_KERNEL);
- if (!str_buf) {
- LOG_ERROR(priv, DEBUGFS,
- "failed to allocate %zd bytes\n", count);
- ret = -ENOMEM;
- goto exit;
- }
-
- memcpy(str_buf, buf, count);
-
- while ((token = strsep(&str_buf, ",")) != NULL) {
- while (isspace(*token))
- ++token;
- if (strict_strtol(token, HEXADECIMAL_RADIX, &val)) {
- LOG_ERROR(priv, DEBUGFS,
- "failed to convert string to long %s\n",
- token);
- ret = -EINVAL;
- goto exit;
- }
-
- mask = val & 0xFF;
- src = (val & 0XFF00) >> 8;
- iwmct_log_set_filter(src, mask);
- }
-
-exit:
- kfree(str_buf);
- return ret;
-}
-
-ssize_t show_iwmct_log_level_fw(struct device *d,
- struct device_attribute *attr, char *buf)
-{
- struct iwmct_priv *priv = dev_get_drvdata(d);
- char *str_buf;
- int buf_size;
- ssize_t ret;
-
- buf_size = (LOG_SRC_FORMAT * FW_LOG_SRC_MAX) + 2;
-
- str_buf = kzalloc(buf_size, GFP_KERNEL);
- if (!str_buf) {
- LOG_ERROR(priv, DEBUGFS,
- "failed to allocate %d bytes\n", buf_size);
- ret = -ENOMEM;
- goto exit;
- }
-
- if (log_get_fw_filter_str(str_buf, buf_size) < 0) {
- ret = -EINVAL;
- goto exit;
- }
-
- ret = sprintf(buf, "%s", str_buf);
-
-exit:
- kfree(str_buf);
- return ret;
-}
-
-ssize_t store_iwmct_log_level_fw(struct device *d,
- struct device_attribute *attr,
- const char *buf, size_t count)
-{
- struct iwmct_priv *priv = dev_get_drvdata(d);
- struct top_msg cmd;
- char *token, *str_buf = NULL;
- ssize_t ret = count;
- u16 cmdlen = 0;
- int i;
- long val;
- u8 src, mask;
-
- if (!count)
- goto exit;
-
- str_buf = kzalloc(count, GFP_KERNEL);
- if (!str_buf) {
- LOG_ERROR(priv, DEBUGFS,
- "failed to allocate %zd bytes\n", count);
- ret = -ENOMEM;
- goto exit;
- }
-
- memcpy(str_buf, buf, count);
-
- cmd.hdr.type = COMM_TYPE_H2D;
- cmd.hdr.category = COMM_CATEGORY_DEBUG;
- cmd.hdr.opcode = CMD_DBG_LOG_LEVEL;
-
- for (i = 0; ((token = strsep(&str_buf, ",")) != NULL) &&
- (i < FW_LOG_SRC_MAX); i++) {
-
- while (isspace(*token))
- ++token;
-
- if (strict_strtol(token, HEXADECIMAL_RADIX, &val)) {
- LOG_ERROR(priv, DEBUGFS,
- "failed to convert string to long %s\n",
- token);
- ret = -EINVAL;
- goto exit;
- }
-
- mask = val & 0xFF; /* LSB */
- src = (val & 0XFF00) >> 8; /* 2nd least significant byte. */
- iwmct_log_set_fw_filter(src, mask);
-
- cmd.u.logdefs[i].logsource = src;
- cmd.u.logdefs[i].sevmask = mask;
- }
-
- cmd.hdr.length = cpu_to_le16(i * sizeof(cmd.u.logdefs[0]));
- cmdlen = (i * sizeof(cmd.u.logdefs[0]) + sizeof(cmd.hdr));
-
- ret = iwmct_send_hcmd(priv, (u8 *)&cmd, cmdlen);
- if (ret) {
- LOG_ERROR(priv, DEBUGFS,
- "Failed to send %d bytes of fwcmd, ret=%zd\n",
- cmdlen, ret);
- goto exit;
- } else
- LOG_INFO(priv, DEBUGFS, "fwcmd sent (%d bytes)\n", cmdlen);
-
- ret = count;
-
-exit:
- kfree(str_buf);
- return ret;
-}
-
diff --git a/drivers/misc/iwmc3200top/log.h b/drivers/misc/iwmc3200top/log.h
deleted file mode 100644
index 4434bb1..0000000
--- a/drivers/misc/iwmc3200top/log.h
+++ /dev/null
@@ -1,171 +0,0 @@
-/*
- * iwmc3200top - Intel Wireless MultiCom 3200 Top Driver
- * drivers/misc/iwmc3200top/log.h
- *
- * Copyright (C) 2009 Intel Corporation. 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 Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- *
- *
- * Author Name: Maxim Grabarnik <maxim.grabarnink-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
- * -
- *
- */
-
-#ifndef __LOG_H__
-#define __LOG_H__
-
-
-/* log severity:
- * The log levels here match FW log levels
- * so values need to stay as is */
-#define LOG_SEV_CRITICAL 0
-#define LOG_SEV_ERROR 1
-#define LOG_SEV_WARNING 2
-#define LOG_SEV_INFO 3
-#define LOG_SEV_INFOEX 4
-
-/* Log levels not defined for FW */
-#define LOG_SEV_TRACE 5
-#define LOG_SEV_DUMP 6
-
-#define LOG_SEV_FW_FILTER_ALL \
- (BIT(LOG_SEV_CRITICAL) | \
- BIT(LOG_SEV_ERROR) | \
- BIT(LOG_SEV_WARNING) | \
- BIT(LOG_SEV_INFO) | \
- BIT(LOG_SEV_INFOEX))
-
-#define LOG_SEV_FILTER_ALL \
- (BIT(LOG_SEV_CRITICAL) | \
- BIT(LOG_SEV_ERROR) | \
- BIT(LOG_SEV_WARNING) | \
- BIT(LOG_SEV_INFO) | \
- BIT(LOG_SEV_INFOEX) | \
- BIT(LOG_SEV_TRACE) | \
- BIT(LOG_SEV_DUMP))
-
-/* log source */
-#define LOG_SRC_INIT 0
-#define LOG_SRC_DEBUGFS 1
-#define LOG_SRC_FW_DOWNLOAD 2
-#define LOG_SRC_FW_MSG 3
-#define LOG_SRC_TST 4
-#define LOG_SRC_IRQ 5
-
-#define LOG_SRC_MAX 6
-#define LOG_SRC_ALL 0xFF
-
-/**
- * Default intitialization runtime log level
- */
-#ifndef LOG_SEV_FILTER_RUNTIME
-#define LOG_SEV_FILTER_RUNTIME \
- (BIT(LOG_SEV_CRITICAL) | \
- BIT(LOG_SEV_ERROR) | \
- BIT(LOG_SEV_WARNING))
-#endif
-
-#ifndef FW_LOG_SEV_FILTER_RUNTIME
-#define FW_LOG_SEV_FILTER_RUNTIME LOG_SEV_FILTER_ALL
-#endif
-
-#ifdef CONFIG_IWMC3200TOP_DEBUG
-/**
- * Log macros
- */
-
-#define priv2dev(priv) (&(priv->func)->dev)
-
-#define LOG_CRITICAL(priv, src, fmt, args...) \
-do { \
- if (iwmct_logdefs[LOG_SRC_ ## src] & BIT(LOG_SEV_CRITICAL)) \
- dev_crit(priv2dev(priv), "%s %d: " fmt, \
- __func__, __LINE__, ##args); \
-} while (0)
-
-#define LOG_ERROR(priv, src, fmt, args...) \
-do { \
- if (iwmct_logdefs[LOG_SRC_ ## src] & BIT(LOG_SEV_ERROR)) \
- dev_err(priv2dev(priv), "%s %d: " fmt, \
- __func__, __LINE__, ##args); \
-} while (0)
-
-#define LOG_WARNING(priv, src, fmt, args...) \
-do { \
- if (iwmct_logdefs[LOG_SRC_ ## src] & BIT(LOG_SEV_WARNING)) \
- dev_warn(priv2dev(priv), "%s %d: " fmt, \
- __func__, __LINE__, ##args); \
-} while (0)
-
-#define LOG_INFO(priv, src, fmt, args...) \
-do { \
- if (iwmct_logdefs[LOG_SRC_ ## src] & BIT(LOG_SEV_INFO)) \
- dev_info(priv2dev(priv), "%s %d: " fmt, \
- __func__, __LINE__, ##args); \
-} while (0)
-
-#define LOG_TRACE(priv, src, fmt, args...) \
-do { \
- if (iwmct_logdefs[LOG_SRC_ ## src] & BIT(LOG_SEV_TRACE)) \
- dev_dbg(priv2dev(priv), "%s %d: " fmt, \
- __func__, __LINE__, ##args); \
-} while (0)
-
-#define LOG_HEXDUMP(src, ptr, len) \
-do { \
- if (iwmct_logdefs[LOG_SRC_ ## src] & BIT(LOG_SEV_DUMP)) \
- print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_NONE, \
- 16, 1, ptr, len, false); \
-} while (0)
-
-void iwmct_log_top_message(struct iwmct_priv *priv, u8 *buf, int len);
-
-extern u8 iwmct_logdefs[];
-
-int iwmct_log_set_filter(u8 src, u8 logmask);
-int iwmct_log_set_fw_filter(u8 src, u8 logmask);
-
-ssize_t show_iwmct_log_level(struct device *d,
- struct device_attribute *attr, char *buf);
-ssize_t store_iwmct_log_level(struct device *d,
- struct device_attribute *attr,
- const char *buf, size_t count);
-ssize_t show_iwmct_log_level_fw(struct device *d,
- struct device_attribute *attr, char *buf);
-ssize_t store_iwmct_log_level_fw(struct device *d,
- struct device_attribute *attr,
- const char *buf, size_t count);
-
-#else
-
-#define LOG_CRITICAL(priv, src, fmt, args...)
-#define LOG_ERROR(priv, src, fmt, args...)
-#define LOG_WARNING(priv, src, fmt, args...)
-#define LOG_INFO(priv, src, fmt, args...)
-#define LOG_TRACE(priv, src, fmt, args...)
-#define LOG_HEXDUMP(src, ptr, len)
-
-static inline void iwmct_log_top_message(struct iwmct_priv *priv,
- u8 *buf, int len) {}
-static inline int iwmct_log_set_filter(u8 src, u8 logmask) { return 0; }
-static inline int iwmct_log_set_fw_filter(u8 src, u8 logmask) { return 0; }
-
-#endif /* CONFIG_IWMC3200TOP_DEBUG */
-
-int log_get_filter_str(char *buf, int size);
-int log_get_fw_filter_str(char *buf, int size);
-
-#endif /* __LOG_H__ */
diff --git a/drivers/misc/iwmc3200top/main.c b/drivers/misc/iwmc3200top/main.c
deleted file mode 100644
index 701eb60..0000000
--- a/drivers/misc/iwmc3200top/main.c
+++ /dev/null
@@ -1,662 +0,0 @@
-/*
- * iwmc3200top - Intel Wireless MultiCom 3200 Top Driver
- * drivers/misc/iwmc3200top/main.c
- *
- * Copyright (C) 2009 Intel Corporation. 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 Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- *
- *
- * Author Name: Maxim Grabarnik <maxim.grabarnink-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
- * -
- *
- */
-
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/debugfs.h>
-#include <linux/mmc/sdio_ids.h>
-#include <linux/mmc/sdio_func.h>
-#include <linux/mmc/sdio.h>
-
-#include "iwmc3200top.h"
-#include "log.h"
-#include "fw-msg.h"
-#include "debugfs.h"
-
-
-#define DRIVER_DESCRIPTION "Intel(R) IWMC 3200 Top Driver"
-#define DRIVER_COPYRIGHT "Copyright (c) 2008 Intel Corporation."
-
-#define DRIVER_VERSION "0.1.62"
-
-MODULE_DESCRIPTION(DRIVER_DESCRIPTION);
-MODULE_VERSION(DRIVER_VERSION);
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR(DRIVER_COPYRIGHT);
-MODULE_FIRMWARE(FW_NAME(FW_API_VER));
-
-
-static inline int __iwmct_tx(struct iwmct_priv *priv, void *src, int count)
-{
- return sdio_memcpy_toio(priv->func, IWMC_SDIO_DATA_ADDR, src, count);
-
-}
-int iwmct_tx(struct iwmct_priv *priv, void *src, int count)
-{
- int ret;
- sdio_claim_host(priv->func);
- ret = __iwmct_tx(priv, src, count);
- sdio_release_host(priv->func);
- return ret;
-}
-/*
- * This workers main task is to wait for OP_OPR_ALIVE
- * from TOP FW until ALIVE_MSG_TIMOUT timeout is elapsed.
- * When OP_OPR_ALIVE received it will issue
- * a call to "bus_rescan_devices".
- */
-static void iwmct_rescan_worker(struct work_struct *ws)
-{
- struct iwmct_priv *priv;
- int ret;
-
- priv = container_of(ws, struct iwmct_priv, bus_rescan_worker);
-
- LOG_INFO(priv, FW_MSG, "Calling bus_rescan\n");
-
- ret = bus_rescan_devices(priv->func->dev.bus);
- if (ret < 0)
- LOG_INFO(priv, INIT, "bus_rescan_devices FAILED!!!\n");
-}
-
-static void op_top_message(struct iwmct_priv *priv, struct top_msg *msg)
-{
- switch (msg->hdr.opcode) {
- case OP_OPR_ALIVE:
- LOG_INFO(priv, FW_MSG, "Got ALIVE from device, wake rescan\n");
- schedule_work(&priv->bus_rescan_worker);
- break;
- default:
- LOG_INFO(priv, FW_MSG, "Received msg opcode 0x%X\n",
- msg->hdr.opcode);
- break;
- }
-}
-
-
-static void handle_top_message(struct iwmct_priv *priv, u8 *buf, int len)
-{
- struct top_msg *msg;
-
- msg = (struct top_msg *)buf;
-
- if (msg->hdr.type != COMM_TYPE_D2H) {
- LOG_ERROR(priv, FW_MSG,
- "Message from TOP with invalid message type 0x%X\n",
- msg->hdr.type);
- return;
- }
-
- if (len < sizeof(msg->hdr)) {
- LOG_ERROR(priv, FW_MSG,
- "Message from TOP is too short for message header "
- "received %d bytes, expected at least %zd bytes\n",
- len, sizeof(msg->hdr));
- return;
- }
-
- if (len < le16_to_cpu(msg->hdr.length) + sizeof(msg->hdr)) {
- LOG_ERROR(priv, FW_MSG,
- "Message length (%d bytes) is shorter than "
- "in header (%d bytes)\n",
- len, le16_to_cpu(msg->hdr.length));
- return;
- }
-
- switch (msg->hdr.category) {
- case COMM_CATEGORY_OPERATIONAL:
- op_top_message(priv, (struct top_msg *)buf);
- break;
-
- case COMM_CATEGORY_DEBUG:
- case COMM_CATEGORY_TESTABILITY:
- case COMM_CATEGORY_DIAGNOSTICS:
- iwmct_log_top_message(priv, buf, len);
- break;
-
- default:
- LOG_ERROR(priv, FW_MSG,
- "Message from TOP with unknown category 0x%X\n",
- msg->hdr.category);
- break;
- }
-}
-
-int iwmct_send_hcmd(struct iwmct_priv *priv, u8 *cmd, u16 len)
-{
- int ret;
- u8 *buf;
-
- LOG_TRACE(priv, FW_MSG, "Sending hcmd:\n");
-
- /* add padding to 256 for IWMC */
- ((struct top_msg *)cmd)->hdr.flags |= CMD_FLAG_PADDING_256;
-
- LOG_HEXDUMP(FW_MSG, cmd, len);
-
- if (len > FW_HCMD_BLOCK_SIZE) {
- LOG_ERROR(priv, FW_MSG, "size %d exceeded hcmd max size %d\n",
- len, FW_HCMD_BLOCK_SIZE);
- return -1;
- }
-
- buf = kzalloc(FW_HCMD_BLOCK_SIZE, GFP_KERNEL);
- if (!buf) {
- LOG_ERROR(priv, FW_MSG, "kzalloc error, buf size %d\n",
- FW_HCMD_BLOCK_SIZE);
- return -1;
- }
-
- memcpy(buf, cmd, len);
- ret = iwmct_tx(priv, buf, FW_HCMD_BLOCK_SIZE);
-
- kfree(buf);
- return ret;
-}
-
-
-static void iwmct_irq_read_worker(struct work_struct *ws)
-{
- struct iwmct_priv *priv;
- struct iwmct_work_struct *read_req;
- __le32 *buf = NULL;
- int ret;
- int iosize;
- u32 barker;
- bool is_barker;
-
- priv = container_of(ws, struct iwmct_priv, isr_worker);
-
- LOG_TRACE(priv, IRQ, "enter iwmct_irq_read_worker %p\n", ws);
-
- /* --------------------- Handshake with device -------------------- */
- sdio_claim_host(priv->func);
-
- /* all list manipulations have to be protected by
- * sdio_claim_host/sdio_release_host */
- if (list_empty(&priv->read_req_list)) {
- LOG_ERROR(priv, IRQ, "read_req_list empty in read worker\n");
- goto exit_release;
- }
-
- read_req = list_entry(priv->read_req_list.next,
- struct iwmct_work_struct, list);
-
- list_del(&read_req->list);
- iosize = read_req->iosize;
- kfree(read_req);
-
- buf = kzalloc(iosize, GFP_KERNEL);
- if (!buf) {
- LOG_ERROR(priv, IRQ, "kzalloc error, buf size %d\n", iosize);
- goto exit_release;
- }
-
- LOG_INFO(priv, IRQ, "iosize=%d, buf=%p, func=%d\n",
- iosize, buf, priv->func->num);
-
- /* read from device */
- ret = sdio_memcpy_fromio(priv->func, buf, IWMC_SDIO_DATA_ADDR, iosize);
- if (ret) {
- LOG_ERROR(priv, IRQ, "error %d reading buffer\n", ret);
- goto exit_release;
- }
-
- LOG_HEXDUMP(IRQ, (u8 *)buf, iosize);
-
- barker = le32_to_cpu(buf[0]);
-
- /* Verify whether it's a barker and if not - treat as regular Rx */
- if (barker == IWMC_BARKER_ACK ||
- (barker & BARKER_DNLOAD_BARKER_MSK) == IWMC_BARKER_REBOOT) {
-
- /* Valid Barker is equal on first 4 dwords */
- is_barker = (buf[1] == buf[0]) &&
- (buf[2] == buf[0]) &&
- (buf[3] == buf[0]);
-
- if (!is_barker) {
- LOG_WARNING(priv, IRQ,
- "Potentially inconsistent barker "
- "%08X_%08X_%08X_%08X\n",
- le32_to_cpu(buf[0]), le32_to_cpu(buf[1]),
- le32_to_cpu(buf[2]), le32_to_cpu(buf[3]));
- }
- } else {
- is_barker = false;
- }
-
- /* Handle Top CommHub message */
- if (!is_barker) {
- sdio_release_host(priv->func);
- handle_top_message(priv, (u8 *)buf, iosize);
- goto exit;
- } else if (barker == IWMC_BARKER_ACK) { /* Handle barkers */
- if (atomic_read(&priv->dev_sync) == 0) {
- LOG_ERROR(priv, IRQ,
- "ACK barker arrived out-of-sync\n");
- goto exit_release;
- }
-
- /* Continuing to FW download (after Sync is completed)*/
- atomic_set(&priv->dev_sync, 0);
- LOG_INFO(priv, IRQ, "ACK barker arrived "
- "- starting FW download\n");
- } else { /* REBOOT barker */
- LOG_INFO(priv, IRQ, "Received reboot barker: %x\n", barker);
- priv->barker = barker;
-
- if (barker & BARKER_DNLOAD_SYNC_MSK) {
- /* Send the same barker back */
- ret = __iwmct_tx(priv, buf, iosize);
- if (ret) {
- LOG_ERROR(priv, IRQ,
- "error %d echoing barker\n", ret);
- goto exit_release;
- }
- LOG_INFO(priv, IRQ, "Echoing barker to device\n");
- atomic_set(&priv->dev_sync, 1);
- goto exit_release;
- }
-
- /* Continuing to FW download (without Sync) */
- LOG_INFO(priv, IRQ, "No sync requested "
- "- starting FW download\n");
- }
-
- sdio_release_host(priv->func);
-
- if (priv->dbg.fw_download)
- iwmct_fw_load(priv);
- else
- LOG_ERROR(priv, IRQ, "FW download not allowed\n");
-
- goto exit;
-
-exit_release:
- sdio_release_host(priv->func);
-exit:
- kfree(buf);
- LOG_TRACE(priv, IRQ, "exit iwmct_irq_read_worker\n");
-}
-
-static void iwmct_irq(struct sdio_func *func)
-{
- struct iwmct_priv *priv;
- int val, ret;
- int iosize;
- int addr = IWMC_SDIO_INTR_GET_SIZE_ADDR;
- struct iwmct_work_struct *read_req;
-
- priv = sdio_get_drvdata(func);
-
- LOG_TRACE(priv, IRQ, "enter iwmct_irq\n");
-
- /* read the function's status register */
- val = sdio_readb(func, IWMC_SDIO_INTR_STATUS_ADDR, &ret);
-
- LOG_TRACE(priv, IRQ, "iir value = %d, ret=%d\n", val, ret);
-
- if (!val) {
- LOG_ERROR(priv, IRQ, "iir = 0, exiting ISR\n");
- goto exit_clear_intr;
- }
-
-
- /*
- * read 2 bytes of the transaction size
- * IMPORTANT: sdio transaction size has to be read before clearing
- * sdio interrupt!!!
- */
- val = sdio_readb(priv->func, addr++, &ret);
- iosize = val;
- val = sdio_readb(priv->func, addr++, &ret);
- iosize += val << 8;
-
- LOG_INFO(priv, IRQ, "READ size %d\n", iosize);
-
- if (iosize == 0) {
- LOG_ERROR(priv, IRQ, "READ size %d, exiting ISR\n", iosize);
- goto exit_clear_intr;
- }
-
- /* allocate a work structure to pass iosize to the worker */
- read_req = kzalloc(sizeof(struct iwmct_work_struct), GFP_KERNEL);
- if (!read_req) {
- LOG_ERROR(priv, IRQ, "failed to allocate read_req, exit ISR\n");
- goto exit_clear_intr;
- }
-
- INIT_LIST_HEAD(&read_req->list);
- read_req->iosize = iosize;
-
- list_add_tail(&priv->read_req_list, &read_req->list);
-
- /* clear the function's interrupt request bit (write 1 to clear) */
- sdio_writeb(func, 1, IWMC_SDIO_INTR_CLEAR_ADDR, &ret);
-
- schedule_work(&priv->isr_worker);
-
- LOG_TRACE(priv, IRQ, "exit iwmct_irq\n");
-
- return;
-
-exit_clear_intr:
- /* clear the function's interrupt request bit (write 1 to clear) */
- sdio_writeb(func, 1, IWMC_SDIO_INTR_CLEAR_ADDR, &ret);
-}
-
-
-static int blocks;
-module_param(blocks, int, 0604);
-MODULE_PARM_DESC(blocks, "max_blocks_to_send");
-
-static bool dump;
-module_param(dump, bool, 0604);
-MODULE_PARM_DESC(dump, "dump_hex_content");
-
-static bool jump = 1;
-module_param(jump, bool, 0604);
-
-static bool direct = 1;
-module_param(direct, bool, 0604);
-
-static bool checksum = 1;
-module_param(checksum, bool, 0604);
-
-static bool fw_download = 1;
-module_param(fw_download, bool, 0604);
-
-static int block_size = IWMC_SDIO_BLK_SIZE;
-module_param(block_size, int, 0404);
-
-static int download_trans_blks = IWMC_DEFAULT_TR_BLK;
-module_param(download_trans_blks, int, 0604);
-
-static bool rubbish_barker;
-module_param(rubbish_barker, bool, 0604);
-
-#ifdef CONFIG_IWMC3200TOP_DEBUG
-static int log_level[LOG_SRC_MAX];
-static unsigned int log_level_argc;
-module_param_array(log_level, int, &log_level_argc, 0604);
-MODULE_PARM_DESC(log_level, "log_level");
-
-static int log_level_fw[FW_LOG_SRC_MAX];
-static unsigned int log_level_fw_argc;
-module_param_array(log_level_fw, int, &log_level_fw_argc, 0604);
-MODULE_PARM_DESC(log_level_fw, "log_level_fw");
-#endif
-
-void iwmct_dbg_init_params(struct iwmct_priv *priv)
-{
-#ifdef CONFIG_IWMC3200TOP_DEBUG
- int i;
-
- for (i = 0; i < log_level_argc; i++) {
- dev_notice(&priv->func->dev, "log_level[%d]=0x%X\n",
- i, log_level[i]);
- iwmct_log_set_filter((log_level[i] >> 8) & 0xFF,
- log_level[i] & 0xFF);
- }
- for (i = 0; i < log_level_fw_argc; i++) {
- dev_notice(&priv->func->dev, "log_level_fw[%d]=0x%X\n",
- i, log_level_fw[i]);
- iwmct_log_set_fw_filter((log_level_fw[i] >> 8) & 0xFF,
- log_level_fw[i] & 0xFF);
- }
-#endif
-
- priv->dbg.blocks = blocks;
- LOG_INFO(priv, INIT, "blocks=%d\n", blocks);
- priv->dbg.dump = (bool)dump;
- LOG_INFO(priv, INIT, "dump=%d\n", dump);
- priv->dbg.jump = (bool)jump;
- LOG_INFO(priv, INIT, "jump=%d\n", jump);
- priv->dbg.direct = (bool)direct;
- LOG_INFO(priv, INIT, "direct=%d\n", direct);
- priv->dbg.checksum = (bool)checksum;
- LOG_INFO(priv, INIT, "checksum=%d\n", checksum);
- priv->dbg.fw_download = (bool)fw_download;
- LOG_INFO(priv, INIT, "fw_download=%d\n", fw_download);
- priv->dbg.block_size = block_size;
- LOG_INFO(priv, INIT, "block_size=%d\n", block_size);
- priv->dbg.download_trans_blks = download_trans_blks;
- LOG_INFO(priv, INIT, "download_trans_blks=%d\n", download_trans_blks);
-}
-
-/*****************************************************************************
- *
- * sysfs attributes
- *
- *****************************************************************************/
-static ssize_t show_iwmct_fw_version(struct device *d,
- struct device_attribute *attr, char *buf)
-{
- struct iwmct_priv *priv = dev_get_drvdata(d);
- return sprintf(buf, "%s\n", priv->dbg.label_fw);
-}
-static DEVICE_ATTR(cc_label_fw, S_IRUGO, show_iwmct_fw_version, NULL);
-
-#ifdef CONFIG_IWMC3200TOP_DEBUG
-static DEVICE_ATTR(log_level, S_IWUSR | S_IRUGO,
- show_iwmct_log_level, store_iwmct_log_level);
-static DEVICE_ATTR(log_level_fw, S_IWUSR | S_IRUGO,
- show_iwmct_log_level_fw, store_iwmct_log_level_fw);
-#endif
-
-static struct attribute *iwmct_sysfs_entries[] = {
- &dev_attr_cc_label_fw.attr,
-#ifdef CONFIG_IWMC3200TOP_DEBUG
- &dev_attr_log_level.attr,
- &dev_attr_log_level_fw.attr,
-#endif
- NULL
-};
-
-static struct attribute_group iwmct_attribute_group = {
- .name = NULL, /* put in device directory */
- .attrs = iwmct_sysfs_entries,
-};
-
-
-static int iwmct_probe(struct sdio_func *func,
- const struct sdio_device_id *id)
-{
- struct iwmct_priv *priv;
- int ret;
- int val = 1;
- int addr = IWMC_SDIO_INTR_ENABLE_ADDR;
-
- dev_dbg(&func->dev, "enter iwmct_probe\n");
-
- dev_dbg(&func->dev, "IRQ polling period id %u msecs, HZ is %d\n",
- jiffies_to_msecs(2147483647), HZ);
-
- priv = kzalloc(sizeof(struct iwmct_priv), GFP_KERNEL);
- if (!priv) {
- dev_err(&func->dev, "kzalloc error\n");
- return -ENOMEM;
- }
- priv->func = func;
- sdio_set_drvdata(func, priv);
-
- INIT_WORK(&priv->bus_rescan_worker, iwmct_rescan_worker);
- INIT_WORK(&priv->isr_worker, iwmct_irq_read_worker);
-
- init_waitqueue_head(&priv->wait_q);
-
- sdio_claim_host(func);
- /* FIXME: Remove after it is fixed in the Boot ROM upgrade */
- func->enable_timeout = 10;
-
- /* In our HW, setting the block size also wakes up the boot rom. */
- ret = sdio_set_block_size(func, priv->dbg.block_size);
- if (ret) {
- LOG_ERROR(priv, INIT,
- "sdio_set_block_size() failure: %d\n", ret);
- goto error_sdio_enable;
- }
-
- ret = sdio_enable_func(func);
- if (ret) {
- LOG_ERROR(priv, INIT, "sdio_enable_func() failure: %d\n", ret);
- goto error_sdio_enable;
- }
-
- /* init reset and dev_sync states */
- atomic_set(&priv->reset, 0);
- atomic_set(&priv->dev_sync, 0);
-
- /* init read req queue */
- INIT_LIST_HEAD(&priv->read_req_list);
-
- /* process configurable parameters */
- iwmct_dbg_init_params(priv);
- ret = sysfs_create_group(&func->dev.kobj, &iwmct_attribute_group);
- if (ret) {
- LOG_ERROR(priv, INIT, "Failed to register attributes and "
- "initialize module_params\n");
- goto error_dev_attrs;
- }
-
- iwmct_dbgfs_register(priv, DRV_NAME);
-
- if (!priv->dbg.direct && priv->dbg.download_trans_blks > 8) {
- LOG_INFO(priv, INIT,
- "Reducing transaction to 8 blocks = 2K (from %d)\n",
- priv->dbg.download_trans_blks);
- priv->dbg.download_trans_blks = 8;
- }
- priv->trans_len = priv->dbg.download_trans_blks * priv->dbg.block_size;
- LOG_INFO(priv, INIT, "Transaction length = %d\n", priv->trans_len);
-
- ret = sdio_claim_irq(func, iwmct_irq);
- if (ret) {
- LOG_ERROR(priv, INIT, "sdio_claim_irq() failure: %d\n", ret);
- goto error_claim_irq;
- }
-
-
- /* Enable function's interrupt */
- sdio_writeb(priv->func, val, addr, &ret);
- if (ret) {
- LOG_ERROR(priv, INIT, "Failure writing to "
- "Interrupt Enable Register (%d): %d\n", addr, ret);
- goto error_enable_int;
- }
-
- sdio_release_host(func);
-
- LOG_INFO(priv, INIT, "exit iwmct_probe\n");
-
- return ret;
-
-error_enable_int:
- sdio_release_irq(func);
-error_claim_irq:
- sdio_disable_func(func);
-error_dev_attrs:
- iwmct_dbgfs_unregister(priv->dbgfs);
- sysfs_remove_group(&func->dev.kobj, &iwmct_attribute_group);
-error_sdio_enable:
- sdio_release_host(func);
- return ret;
-}
-
-static void iwmct_remove(struct sdio_func *func)
-{
- struct iwmct_work_struct *read_req;
- struct iwmct_priv *priv = sdio_get_drvdata(func);
-
- LOG_INFO(priv, INIT, "enter\n");
-
- sdio_claim_host(func);
- sdio_release_irq(func);
- sdio_release_host(func);
-
- /* Make sure works are finished */
- flush_work_sync(&priv->bus_rescan_worker);
- flush_work_sync(&priv->isr_worker);
-
- sdio_claim_host(func);
- sdio_disable_func(func);
- sysfs_remove_group(&func->dev.kobj, &iwmct_attribute_group);
- iwmct_dbgfs_unregister(priv->dbgfs);
- sdio_release_host(func);
-
- /* free read requests */
- while (!list_empty(&priv->read_req_list)) {
- read_req = list_entry(priv->read_req_list.next,
- struct iwmct_work_struct, list);
-
- list_del(&read_req->list);
- kfree(read_req);
- }
-
- kfree(priv);
-}
-
-
-static const struct sdio_device_id iwmct_ids[] = {
- /* Intel Wireless MultiCom 3200 Top Driver */
- { SDIO_DEVICE(SDIO_VENDOR_ID_INTEL, 0x1404)},
- { }, /* Terminating entry */
-};
-
-MODULE_DEVICE_TABLE(sdio, iwmct_ids);
-
-static struct sdio_driver iwmct_driver = {
- .probe = iwmct_probe,
- .remove = iwmct_remove,
- .name = DRV_NAME,
- .id_table = iwmct_ids,
-};
-
-static int __init iwmct_init(void)
-{
- int rc;
-
- /* Default log filter settings */
- iwmct_log_set_filter(LOG_SRC_ALL, LOG_SEV_FILTER_RUNTIME);
- iwmct_log_set_filter(LOG_SRC_FW_MSG, LOG_SEV_FW_FILTER_ALL);
- iwmct_log_set_fw_filter(LOG_SRC_ALL, FW_LOG_SEV_FILTER_RUNTIME);
-
- rc = sdio_register_driver(&iwmct_driver);
-
- return rc;
-}
-
-static void __exit iwmct_exit(void)
-{
- sdio_unregister_driver(&iwmct_driver);
-}
-
-module_init(iwmct_init);
-module_exit(iwmct_exit);
^ permalink raw reply related
* Re: [PATCH 5/6] tuntap: per queue 64 bit stats\
From: Michael S. Tsirkin @ 2012-06-26 19:46 UTC (permalink / raw)
To: Jason Wang
Cc: Eric Dumazet, akong, habanero, tahm, haixiao, jwhan,
ernesto.martin, mashirle, davem, netdev, linux-kernel, krkumar2,
shemminger, edumazet
In-Reply-To: <4FE95015.7000707@redhat.com>
On Tue, Jun 26, 2012 at 02:00:53PM +0800, Jason Wang wrote:
> On 06/25/2012 08:52 PM, Eric Dumazet wrote:
> >On Mon, 2012-06-25 at 19:59 +0800, Jason Wang wrote:
> >>As we've added multiqueue support for tun/tap, this patch convert the statistics
> >>to use per-queue 64 bit statistics.
> >LLTX means you can have several cpus calling TX path in parallel.
> >
> >So tx stats are wrong (even before this patch), and racy after this
> >patch (if several cpu access same queue, it seems to be possible)
> >
> > u64_stats_update_begin(&tfile->stats.tx_syncp);
> > tfile->stats.tx_packets++;
> > tfile->stats.tx_bytes += total;
> > u64_stats_update_end(&tfile->stats.tx_syncp);
> >
> >This can break horribly if several cpus run this code using same 'tfile'
> >pointer.
>
> Yes, looks like it's hard to use NETIF_F_LLTX without breaking the
> u64 statistics, may worth to use tx lock and alloc_netdev_mq().
Or make them per cpu as most everyone did.
> >I suggest this patch comes before 'tuntap: multiqueue support' in the
> >serie.
>
> Sure, thanks.
> >
> >
> >
^ permalink raw reply
* [PATCH net-next] udp: Add socket early demux support
From: Vijay Subramanian @ 2012-06-26 19:43 UTC (permalink / raw)
To: netdev
Cc: davem, shemminger, eric.dumazet, alexander.h.duyck,
Vijay Subramanian
Based on the recent TCP socket early demux code, this patch provides similar
support for UDP.
Signed-off-by: Vijay Subramanian <subramanian.vijay@gmail.com>
---
This has been tested on x86 with UDP iperf flows and seemed to work. If this is
accepted, I plan to submit one more patch moving common code from TCP and UDP
early demux code into common helper functions.
Thanks in advance for feedback.
include/net/udp.h | 1 +
net/ipv4/af_inet.c | 1 +
net/ipv4/udp.c | 67 ++++++++++++++++++++++++++++++++++++++++++++++++++-
3 files changed, 67 insertions(+), 2 deletions(-)
diff --git a/include/net/udp.h b/include/net/udp.h
index 065f379..e0ed11d 100644
--- a/include/net/udp.h
+++ b/include/net/udp.h
@@ -175,6 +175,7 @@ extern int udp_lib_get_port(struct sock *sk, unsigned short snum,
unsigned int hash2_nulladdr);
/* net/ipv4/udp.c */
+extern int udp_v4_early_demux(struct sk_buff *skb);
extern int udp_get_port(struct sock *sk, unsigned short snum,
int (*saddr_cmp)(const struct sock *,
const struct sock *));
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
index 07a02f6..c7d40db 100644
--- a/net/ipv4/af_inet.c
+++ b/net/ipv4/af_inet.c
@@ -1531,6 +1531,7 @@ static const struct net_protocol tcp_protocol = {
};
static const struct net_protocol udp_protocol = {
+ .early_demux = udp_v4_early_demux,
.handler = udp_rcv,
.err_handler = udp_err,
.gso_send_check = udp4_ufo_send_check,
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index db017ef..bd85cd8 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -520,10 +520,10 @@ static inline struct sock *__udp4_lib_lookup_skb(struct sk_buff *skb,
__be16 sport, __be16 dport,
struct udp_table *udptable)
{
- 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 __udp4_lib_lookup(dev_net(skb_dst(skb)->dev), iph->saddr, sport,
@@ -1403,6 +1403,19 @@ int udp_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)
int rc;
int is_udplite = IS_UDPLITE(sk);
+ 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));
+
/*
* Charge it to the socket, dropping if the queue is full.
*/
@@ -1622,6 +1635,56 @@ static inline int udp4_csum_init(struct sk_buff *skb, struct udphdr *uh,
return 0;
}
+int udp_v4_early_demux(struct sk_buff *skb)
+{
+ struct net *net = dev_net(skb->dev);
+ const struct iphdr *iph;
+ const struct udphdr *uh;
+ struct net_device *dev;
+ struct sock *sk;
+ unsigned short ulen;
+ int err;
+
+ err = -ENOENT;
+ if (skb->pkt_type != PACKET_HOST)
+ goto out_err;
+
+ if (!pskb_may_pull(skb, ip_hdrlen(skb) + sizeof(struct udphdr)))
+ goto out_err;
+
+ iph = ip_hdr(skb);
+ uh = (struct udphdr *)((char *)iph + ip_hdrlen(skb));
+ ulen = ntohs(uh->len);
+
+ if (ulen > skb->len)
+ goto out_err;
+
+ dev = skb->dev;
+
+ sk = udp4_lib_lookup(net, iph->saddr, uh->source, iph->daddr,
+ uh->dest, dev->ifindex);
+
+ if (sk) {
+ struct dst_entry *dst = sk->sk_rx_dst;
+ skb->sk = sk;
+ skb->destructor = sock_edemux;
+
+ if (dst)
+ dst = dst_check(dst, 0);
+ if (dst) {
+ struct rtable *rt = (struct rtable *)dst;
+
+ if (rt->rt_iif == dev->ifindex) {
+ skb_dst_set_noref(skb, dst);
+ err = 0;
+ }
+ }
+ }
+
+out_err:
+ return err;
+}
+
/*
* All we need to do is get the socket, and then do a checksum.
*/
--
1.7.0.4
^ permalink raw reply related
* Re: [RFC net-next (v2) 12/14] ixgbe: set maximal number of default RSS queues
From: Eilon Greenstein @ 2012-06-26 18:23 UTC (permalink / raw)
To: Alexander Duyck; +Cc: Yuval Mintz, davem, netdev, Jeff Kirsher, John Fastabend
In-Reply-To: <4FE9DB88.5070208@intel.com>
On Tue, 2012-06-26 at 08:55 -0700, Alexander Duyck wrote:
> One thing that just occurred to me though is that this is going to lock
> the upper limit for us and we won't be able to override it if we
> implement the set channels code. I believe the same thing goes for the
> igb driver as well.
>
> Is there any chance you could just bypass the ixgbe and igb drivers for
> now and give us time to come up with a more complete solution that would
> allow us to add the set_channels calls. One issue is I have a number of
> ixgbe patches that are going to be completely rewriting this code anyway
> so I could probably just add set_channels support and support for your
> function once it is included in net-next.
Alex,
I share your concern. I actually brought it up originally when
discussing this RFC:
http://marc.info/?l=linux-netdev&m=133991625809201&w=2
>From my end, if you would like to add the Intel side support that would
be great. Unless anyone object, we will leave the ixgbe and igb out of
this patch series.
Thanks,
Eilon
^ permalink raw reply
* Re: [PATCH 1/1] atl1c: fix issue of transmit queue 0 timed out
From: Luis R. Rodriguez @ 2012-06-26 18:03 UTC (permalink / raw)
To: Ren, Cloud; +Cc: davem, netdev, linux-kernel, qca-linux-team, nic-devel, xiong
In-Reply-To: <1340724786-3819-1-git-send-email-cjren@qca.qualcomm.com>
On Tue, Jun 26, 2012 at 12:33:06PM -0300, Ren, Cloud wrote:
> From: xiong <xiong@qca.qualcomm.com>
>
> some people report atl1c could cause system hang with following
> kernel trace info:
> ---------------------------------------
> WARNING: at.../net/sched/sch_generic.c:258
> dev_watchdog+0x1db/0x1d0()
> ...
> NETDEV WATCHDOG: eth0 (atl1c): transmit queue 0 timed out
> ...
> ---------------------------------------
> This is caused by netif_stop_queue calling when cable Link is down
> but netif_wake_queue isn't called when cable Link is resume.
>
> Signed-off-by: xiong <xiong@qca.qualcomm.com>
> Signed-off-by: Cloud Ren <cjren@qca.qualcomm.com>
If this fixes a system hang then this could be a stable
fix -- that is, this should be propagated to older stable
kernels, no?
If so then please add to the commit log a line like this:
Cc: stable@vger.kernel.org [3.4]
Note: this is for the commit log! Right above the line below
that has "---"
Luis
^ permalink raw reply
* Re: BUG: No init found on NFSROOT
From: Fengguang Wu @ 2012-06-26 17:29 UTC (permalink / raw)
To: Trond Myklebust
Cc: J. Bruce Fields, linux-nfs-u79uwXL29TY76Z2rM5mHXA, LKML, netdev
In-Reply-To: <20120626145432.GA15289@localhost>
On Tue, Jun 26, 2012 at 10:54:32PM +0800, Fengguang Wu wrote:
> Hi Trond,
>
> It's found that this commit in linux-next leads to the below boot hang.
>
> da660bb2774ff21c7263b4061198c5abe0629cb4 is the first bad commit
> commit da660bb2774ff21c7263b4061198c5abe0629cb4
> Author: Trond Myklebust <Trond.Myklebust-HgOvQuBEEgTQT0dZR+AlfA@public.gmane.org>
> Date: Thu Jun 21 14:53:10 2012 -0400
>
> SUNRPC: Clean up xdr_read_pages and xdr_enter_page
>
> Move the page alignment code into a separate helper.
>
> Signed-off-by: Trond Myklebust <Trond.Myklebust-HgOvQuBEEgTQT0dZR+AlfA@public.gmane.org>
>
> :040000 040000 742f2939849ea8ff2e4b954316e6ea2933e7e018 6809fe8bd11b9f2459168d6e1dac92b0c5a74eef M net
> bisect run success
>
> The "held lock freed" message may or may not appear in the tests.
Ah that seem to be an independent bug. It's still there when reverting
the above commit on top of linux-next. Will try to bisect it.
> However the "No init found." message reliably appears in all test runs.
That "No init found" disappears after reverting the commit.
Thanks,
Fengguang
> [ 133.909702] =========================
> [ 133.910694] [ BUG: held lock freed! ]
> [ 133.911700] 3.5.0-rc4+ #5 Not tainted
> [ 133.912672] -------------------------
> [ 133.912969] swapper/0/0 is freeing memory ffff88001233ce08-ffff88001233de07, with a lock still held there!
> [ 133.912969] (slock-AF_INET-RPC/1){+.-...}, at: [<ffffffff82ae84ee>] tcp_v4_rcv+0x28b/0x6fc
> [ 133.912969] 3 locks held by swapper/0/0:
> [ 133.912969] #0: (rcu_read_lock){.+.+..}, at: [<ffffffff82a1ea8a>] rcu_lock_acquire+0x0/0x29
> [ 133.912969] #1: (rcu_read_lock){.+.+..}, at: [<ffffffff82aca483>] rcu_lock_acquire.constprop.14+0x0/0x30
> [ 133.912969] #2: (slock-AF_INET-RPC/1){+.-...}, at: [<ffffffff82ae84ee>] tcp_v4_rcv+0x28b/0x6fc
> [ 133.912969]
> [ 133.912969] stack backtrace:
> [ 133.912969] Pid: 0, comm: swapper/0 Not tainted 3.5.0-rc4+ #5
> [ 133.912969] Call Trace:
> [ 133.912969] <IRQ> [<ffffffff810e09ae>] debug_check_no_locks_freed+0x109/0x14b
> [ 133.912969] [<ffffffff811774e0>] kmem_cache_free+0x2e/0xa7
> [ 133.912969] [<ffffffff82a191e5>] __kfree_skb+0x7f/0x83
> [ 133.912969] [<ffffffff82adeccd>] tcp_ack+0x45d/0xc6a
> [ 133.912969] [<ffffffff810c22ae>] ? local_clock+0x3b/0x52
> [ 133.912969] [<ffffffff82adff44>] tcp_rcv_state_process+0x15a/0x7c6
> [ 133.912969] [<ffffffff82ae79e7>] tcp_v4_do_rcv+0x341/0x390
> [ 133.912969] [<ffffffff82ae88db>] tcp_v4_rcv+0x678/0x6fc
> [ 133.912969] [<ffffffff82aca618>] ip_local_deliver_finish+0x165/0x1e4
> [ 133.912969] [<ffffffff82acab4a>] ip_local_deliver+0x53/0x84
> [ 133.912969] [<ffffffff810c228c>] ? local_clock+0x19/0x52
> [ 133.912969] [<ffffffff82aca9c6>] ip_rcv_finish+0x32f/0x367
> [ 133.912969] [<ffffffff82acad8b>] ip_rcv+0x210/0x269
> [ 133.912969] [<ffffffff82a1eab1>] ? rcu_lock_acquire+0x27/0x29
> [ 133.912969] [<ffffffff82a1ea8a>] ? softnet_seq_show+0x68/0x68
> [ 133.912969] [<ffffffff82a21ede>] __netif_receive_skb+0x3cd/0x464
> [ 133.912969] [<ffffffff82a21fda>] netif_receive_skb+0x65/0x9c
> [ 133.912969] [<ffffffff82a227c5>] ? __napi_gro_receive+0xf2/0xff
> [ 133.912969] [<ffffffff82a2209e>] napi_skb_finish+0x26/0x58
> [ 133.912969] [<ffffffff810c228c>] ? local_clock+0x19/0x52
> [ 133.912969] [<ffffffff82a228c5>] napi_gro_receive+0x2f/0x34
> [ 133.912969] [<ffffffff81e36d12>] e1000_receive_skb+0x57/0x60
> [ 133.912969] [<ffffffff81e39b23>] e1000_clean_rx_irq+0x2f2/0x387
> [ 133.912969] [<ffffffff81e390f3>] e1000_clean+0x541/0x695
> [ 133.912969] [<ffffffff8106c57b>] ? kvm_clock_read+0x2e/0x36
> [ 133.912969] [<ffffffff82a22402>] ? net_rx_action+0x1b3/0x1f8
> [ 133.912969] [<ffffffff82a22302>] net_rx_action+0xb3/0x1f8
> [ 133.912969] [<ffffffff810984ab>] ? __do_softirq+0x76/0x1e8
> [ 133.912969] [<ffffffff81098515>] __do_softirq+0xe0/0x1e8
> [ 133.912969] [<ffffffff81122190>] ? time_hardirqs_off+0x26/0x2a
> [ 133.912969] [<ffffffff82ea7fec>] call_softirq+0x1c/0x30
> [ 133.912969] [<ffffffff81049cc8>] do_softirq+0x4a/0xa2
> [ 133.912969] [<ffffffff8109888e>] irq_exit+0x51/0xbc
> [ 133.912969] [<ffffffff82ea88ae>] do_IRQ+0x8e/0xa5
> [ 133.912969] [<ffffffff82ea002f>] common_interrupt+0x6f/0x6f
> [ 133.912969] <EOI> [<ffffffff8106c76b>] ? native_safe_halt+0x6/0x8
> [ 133.912969] [<ffffffff810e08a3>] ? trace_hardirqs_on+0xd/0xf
> [ 133.912969] [<ffffffff8104f384>] default_idle+0x53/0x90
> [ 133.912969] [<ffffffff8104fc09>] cpu_idle+0xcc/0x123
> [ 133.912969] [<ffffffff82d1d8dd>] rest_init+0xd1/0xda
> [ 133.912969] [<ffffffff82d1d80c>] ? csum_partial_copy_generic+0x16c/0x16c
> [ 133.912969] [<ffffffff8460dbbc>] start_kernel+0x3da/0x3e7
> [ 133.912969] [<ffffffff8460d5ea>] ? repair_env_string+0x5a/0x5a
> [ 133.912969] [<ffffffff8460d2d6>] x86_64_start_reservations+0xb1/0xb5
> [ 133.912969] [<ffffffff8460d3d8>] x86_64_start_kernel+0xfe/0x10b
> [ 134.024230] VFS: Mounted root (nfs filesystem) on device 0:14.
> [ 134.025782] debug: unmapping init [mem 0xffffffff84437000-0xffffffff8480efff]
> [ 134.027686] Write protecting the kernel read-only data: 49152k
> [ 134.029956] debug: unmapping init [mem 0xffff880002eb0000-0xffff880002ffffff]
> [ 134.031745] debug: unmapping init [mem 0xffff880003e95000-0xffff880003ffffff]
> [ 134.059408] request_module: runaway loop modprobe binfmt-0000
> [ 134.062946] kworker/u:0 (2781) used greatest stack depth: 3432 bytes left
> [ 134.069553] Kernel panic - not syncing: No init found. Try passing init= option to kernel. See Linux Documentation/init.txt for guidance.
> [ 134.072742] Pid: 1, comm: swapper/0 Not tainted 3.5.0-rc4+ #5
> [ 134.074200] Call Trace:
> [ 134.074971] [<ffffffff82e4fc90>] panic+0xbd/0x1d0
> [ 134.076237] [<ffffffff82e4ccc7>] init_post+0xc8/0xc8
> [ 134.077636] [<ffffffff8460dd8e>] kernel_init+0x1c5/0x1c5
> [ 134.078979] [<ffffffff8460d590>] ? do_early_param+0x8c/0x8c
> [ 134.080408] [<ffffffff82ea7ef4>] kernel_thread_helper+0x4/0x10
> [ 134.082038] [<ffffffff82ea00f0>] ? retint_restore_args+0x13/0x13
> [ 134.083514] [<ffffffff8460dbc9>] ? start_kernel+0x3e7/0x3e7
> [ 134.084997] [<ffffffff82ea7ef0>] ? gs_change+0x13/0x13
>
> Thanks,
> Fengguang
--
To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: New commands to configure IOV features
From: Greg Rose @ 2012-06-26 17:19 UTC (permalink / raw)
To: Yuval Mintz; +Cc: Ben Hutchings, netdev@vger.kernel.org
In-Reply-To: <4FE9A963.7020602@broadcom.com>
On Tue, 26 Jun 2012 15:21:55 +0300
Yuval Mintz <yuvalmin@broadcom.com> wrote:
> On 05/07/2012 06:16 PM, Greg Rose wrote:
>
> > On Mon, 7 May 2012 14:17:54 +0300
> > Yuval Mintz <yuvalmin@broadcom.com> wrote:
> >
> >> I've tried to figure out if there was a standard interface
> >> (ethtool/iproute) through which a user could configure the number
> >> of vfs in his system.
> >>
> >> I've seen the RFC suggested in
> >> http://markmail.org/thread/qblfcv7zbxsxp7q6, and
> >> http://markmail.org/thread/fw54dcppmxuxoe6n, but failed to see any
> >> later references to it (commits or further discussion on this
> >> topic).
> >>
> >> How exactly are things standing with these RFCs? Were they
> >> abandoned?
> >
> > The only way to configure the number of VFs continues to be through
> > the max_vfs module parameter. I've got a patch to do it through
> > ethtool sitting on the back burner but due to other requirements of
> > my day job I've not been able to work on it since last fall.
> >
> > - Greg
>
>
> Hi Ben,
>
> If I want to pick the RFCs and add support for configuring the number
> of VFs - do you think ethtool's the right place for such added
> support?
>
> I'm asking since as far as I can see, ethtool (today) doesn't contain
> any features related to virtual functions.
I think a PCI utility tool would be better, SR-IOV is not limited to
network devices. That's one of the reasons I dropped the RFC. I
haven't gotten back to the idea since then due to my day job keeping me
pretty busy.
- Greg
^ permalink raw reply
* [patch net-next 1/3] team: fix team_adjust_ops with regard to enabled ports
From: Jiri Pirko @ 2012-06-26 16:52 UTC (permalink / raw)
To: netdev; +Cc: davem, eric.dumazet, brouer
In-Reply-To: <1340729567-3164-1-git-send-email-jpirko@redhat.com>
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 <jpirko@redhat.com>
---
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 3a4a74b..6b4cf6e 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);
--
1.7.10.4
^ permalink raw reply related
* [patch net-next 2/3] team: do not allow to map disabled ports
From: Jiri Pirko @ 2012-06-26 16:52 UTC (permalink / raw)
To: netdev; +Cc: davem, eric.dumazet, brouer
In-Reply-To: <1340729567-3164-1-git-send-email-jpirko@redhat.com>
Signed-off-by: Jiri Pirko <jpirko@redhat.com>
---
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 6b4cf6e..5350eea 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 c92fa02..51a4b19 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 c193886..e636a54 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);
--
1.7.10.4
^ permalink raw reply related
* [patch net-next 3/3] team: remove unuset rcu_head field from team_port struct
From: Jiri Pirko @ 2012-06-26 16:52 UTC (permalink / raw)
To: netdev; +Cc: davem, eric.dumazet, brouer
In-Reply-To: <1340729567-3164-1-git-send-email-jpirko@redhat.com>
Signed-off-by: Jiri Pirko <jpirko@redhat.com>
---
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 e636a54..99efd60 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];
};
--
1.7.10.4
^ permalink raw reply related
* [patch net-next 0/3] team: couple of fixes
From: Jiri Pirko @ 2012-06-26 16:52 UTC (permalink / raw)
To: netdev; +Cc: davem, eric.dumazet, brouer
Jiri Pirko (3):
team: fix team_adjust_ops with regard to enabled ports
team: do not allow to map disabled ports
team: remove unuset rcu_head field from team_port struct
drivers/net/team/team.c | 35 ++++++++++++++++++------------
drivers/net/team/team_mode_loadbalance.c | 3 ++-
include/linux/if_team.h | 3 ++-
3 files changed, 25 insertions(+), 16 deletions(-)
--
1.7.10.4
^ permalink raw reply
* Re: [PATCH v2 net-next] tcp: avoid tx starvation by SYNACK packets
From: Eric Dumazet @ 2012-06-26 17:02 UTC (permalink / raw)
To: Hans Schillstrom
Cc: David Miller, subramanian.vijay@gmail.com, dave.taht@gmail.com,
netdev@vger.kernel.org, ncardwell@google.com, therbert@google.com,
brouer@redhat.com
In-Reply-To: <201206260734.33472.hans.schillstrom@ericsson.com>
On Tue, 2012-06-26 at 07:34 +0200, Hans Schillstrom wrote:
> This patch didn't give much in gain actually.
With a 100Mbps link it does.
With a 1Gbps link we are cpu bounded for sure.
> The big cycle consumer during a syn attack is SHA sum right now,
> so from that perspective it's better to add aes crypto (by using AES-NI)
> to the syn cookies instead of SHA sum. Even if only newer x86_64 can use it.
My dev machine is able to process ~280.000 SYN (and synack) per second
(tg3, mono queue), and sha_transform() takes ~10 % of the time according
to perf.
With David patch using jhash instead of SHA, I reach ~315.000 SYN per
second.
^ permalink raw reply
* Re: [PATCH 0/2] flexcan driver updates
From: Oliver Hartkopp @ 2012-06-26 16:55 UTC (permalink / raw)
To: Shawn Guo; +Cc: David S. Miller, Marc Kleine-Budde, netdev, linux-arm-kernel
In-Reply-To: <1340700563-8386-1-git-send-email-shawn.guo@linaro.org>
On 26.06.2012 10:49, Shawn Guo wrote:
> Here are a couple of flexcan driver/bindings updates, which are meant
> to get the driver more device tree friendly.
>
> Shawn Guo (2):
> net: flexcan: clock-frequency is optional for device tree probe
> net: flexcan: add transceiver switch gpio support
>
> .../devicetree/bindings/net/can/fsl-flexcan.txt | 6 ++++
> drivers/net/can/flexcan.c | 30 ++++++++++++++++++++
> 2 files changed, 36 insertions(+), 0 deletions(-)
>
Sorry Shawn, but your posting is pretty misplaced ...
Please check for the maintainers and mailing lists in the MAINTAINERS file
that match your suggested changes:
Documentation/devicetree/bindings/net/can/fsl-flexcan.txt =>
OPEN FIRMWARE AND FLATTENED DEVICE TREE
M: Grant Likely <grant.likely@secretlab.ca>
M: Rob Herring <rob.herring@calxeda.com>
L: devicetree-discuss@lists.ozlabs.org (moderated for non-subscribers)
W: http://fdt.secretlab.ca
T: git git://git.secretlab.ca/git/linux-2.6.git
S: Maintained
F: Documentation/devicetree <<<<<------------- !!!
F: drivers/of
F: include/linux/of*.h
K: of_get_property
K: of_match_table
drivers/net/can/flexcan.c =>
CAN NETWORK DRIVERS
M: Wolfgang Grandegger <wg@grandegger.com>
M: Marc Kleine-Budde <mkl@pengutronix.de>
L: linux-can@vger.kernel.org
W: http://gitorious.org/linux-can
T: git git://gitorious.org/linux-can/linux-can-next.git
S: Maintained
F: drivers/net/can/ <<<<<------------- !!!
F: include/linux/can/dev.h
F: include/linux/can/error.h
F: include/linux/can/netlink.h
F: include/linux/can/platform/
So please post your suggested changes for the flexcan driver on the mailing
lists linux-can@vger.kernel.org and devicetree-discuss@lists.ozlabs.org
Once the changes are discussed and accepted they can be pulled by Dave Miller
from the CAN development git repository into the networking tree.
Thanks,
Oliver
^ permalink raw reply
* Re: [PATCH 04/16] mm: allow PF_MEMALLOC from softirq context
From: Sebastian Andrzej Siewior @ 2012-06-26 16:55 UTC (permalink / raw)
To: Mel Gorman
Cc: Andrew Morton, Linux-MM, Linux-Netdev, LKML, David Miller,
Neil Brown, Peter Zijlstra, Mike Christie, Eric B Munson,
Eric Dumazet
In-Reply-To: <1340375443-22455-5-git-send-email-mgorman@suse.de>
On Fri, Jun 22, 2012 at 03:30:31PM +0100, Mel Gorman wrote:
> This is needed to allow network softirq packet processing to make
> use of PF_MEMALLOC.
> diff --git a/mm/page_alloc.c b/mm/page_alloc.c
> index b6c0727..5c6d9c6 100644
> --- a/mm/page_alloc.c
> +++ b/mm/page_alloc.c
> @@ -2265,7 +2265,11 @@ gfp_to_alloc_flags(gfp_t gfp_mask)
> if (likely(!(gfp_mask & __GFP_NOMEMALLOC))) {
> if (gfp_mask & __GFP_MEMALLOC)
> alloc_flags |= ALLOC_NO_WATERMARKS;
> - else if (likely(!(gfp_mask & __GFP_NOMEMALLOC)) && !in_interrupt())
> + else if (in_serving_softirq() && (current->flags & PF_MEMALLOC))
> + alloc_flags |= ALLOC_NO_WATERMARKS;
> + else if (!in_interrupt() &&
> + ((current->flags & PF_MEMALLOC) ||
> + unlikely(test_thread_flag(TIF_MEMDIE))))
> alloc_flags |= ALLOC_NO_WATERMARKS;
> }
You allocate in RX path with __GFP_MEMALLOC and your sk->sk_allocation has
also __GFP_MEMALLOC set. That means you should get ALLOC_NO_WATERMARKS in
alloc_flags. Is this to done to avoid GFP annotations in skb_share_check() and
friends on your __netif_receive_skb() path?
Sebastian
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply
* Re: [net] ixgbe: Do not pad FCoE frames as this can cause issues with FCoE DDP
From: Greg KH @ 2012-06-26 16:33 UTC (permalink / raw)
To: Jeff Kirsher
Cc: David Miller, alexander.h.duyck, netdev, gospo, sassmann, stable
In-Reply-To: <1340696850.2255.17.camel@jtkirshe-mobl>
On Tue, Jun 26, 2012 at 12:47:30AM -0700, Jeff Kirsher wrote:
> On Tue, 2012-06-26 at 00:43 -0700, David Miller wrote:
> > You can't put things like "[3.4]" unquoted into the CC: list, that's
> > not kosher and vger rejected it.
>
> Sorry, that was what Greg told me to do. I did not realize it needed to
> be in quotes, my bad.
Greg told you no such thing, please use real email addresses on your cc:
lines, to not do so is crazy, and to blame me is sad.
greg k-h
^ permalink raw reply
* Re: New commands to configure IOV features
From: Alexander Duyck @ 2012-06-26 16:13 UTC (permalink / raw)
To: Yuval Mintz; +Cc: Ben Hutchings, Greg Rose, netdev@vger.kernel.org
In-Reply-To: <4FE9A963.7020602@broadcom.com>
On 06/26/2012 05:21 AM, Yuval Mintz wrote:
> On 05/07/2012 06:16 PM, Greg Rose wrote:
>
>> On Mon, 7 May 2012 14:17:54 +0300
>> Yuval Mintz <yuvalmin@broadcom.com> wrote:
>>
>>> I've tried to figure out if there was a standard interface
>>> (ethtool/iproute) through which a user could configure the number
>>> of vfs in his system.
>>>
>>> I've seen the RFC suggested in
>>> http://markmail.org/thread/qblfcv7zbxsxp7q6, and
>>> http://markmail.org/thread/fw54dcppmxuxoe6n, but failed to see any
>>> later references to it (commits or further discussion on this topic).
>>>
>>> How exactly are things standing with these RFCs? Were they abandoned?
>> The only way to configure the number of VFs continues to be through the
>> max_vfs module parameter. I've got a patch to do it through ethtool
>> sitting on the back burner but due to other requirements of my day job
>> I've not been able to work on it since last fall.
>>
>> - Greg
>
> Hi Ben,
>
> If I want to pick the RFCs and add support for configuring the number of
> VFs - do you think ethtool's the right place for such added support?
>
> I'm asking since as far as I can see, ethtool (today) doesn't contain any
> features related to virtual functions.
>
> Thanks,
> Yuval
I think the issue is that any class of PCI device could theoretically
support SR-IOV. For example there could be a storage controller out
there that supports spawning VFs, and an ethtool solution wouldn't work
for a device like that. Personally what I would like to see is a
solution that is more focused on the PCI side of the network adapters
instead of the network side when it comes to enabling VFs.
Thanks,
Alex
^ permalink raw reply
* Re: [net] ixgbe: Do not pad FCoE frames as this can cause issues with FCoE DDP
From: Ben Hutchings @ 2012-06-26 15:56 UTC (permalink / raw)
To: Alexander Duyck
Cc: jeffrey.t.kirsher, David Miller, netdev, gospo, sassmann, stable
In-Reply-To: <4FE9D9C2.5010209@intel.com>
[-- Attachment #1: Type: text/plain, Size: 1654 bytes --]
On Tue, 2012-06-26 at 08:48 -0700, Alexander Duyck wrote:
> On 06/26/2012 07:09 AM, Ben Hutchings wrote:
> > On Tue, 2012-06-26 at 00:53 -0700, Jeff Kirsher wrote:
> >> On Tue, 2012-06-26 at 00:50 -0700, David Miller wrote:
> >>> Sorry, quotes don't work either, what you did is still a SMTP syntax error,
> >>> here's what is in the bounce I get back:
> >>>
> >>> <stable@vger.kernel.org> "[3.4]",
> >>> Jeff Kirsher <jeffrey.t.kirsher@intel.com>
> >>> Illegal-Object: Syntax error in Cc: address found on vger.kernel.org:
> >>> Cc: <stable@vger.kernel.org>"[3.4]"
> >>> ^-missing end of address
> >> Grrr...
> >>
> >> I will re-send without the "[3.4]", Greg will just have to deal with it.
> > It's certainly not necessary to put anything like that in the real Cc
> > header. Many people put something like
> > 'Cc: <stable@vger.kernel.org> # 3.4' in the body; I don't know if that
> > is more like likely to result in the version being stripped when
> > generating mail recipients.
> >
> > Ben.
> >
> Couldn't 3.4 have been put in place of the recipient's name? So you do
> something like this:
> Cc: 3.4 <stable@vger.kernel.org>
Aside from the fact that recipient names with dots must be quoted in the
real header, it's relatively uncommon to use this format and the import
script I use for 3.2.y wouldn't notice it. (So I'd have to go back and
look at the original commit header to work out that it wasn't relevant.)
I don't know whether Greg's script extracts the recipient name.
Ben.
--
Ben Hutchings
Lowery's Law:
If it jams, force it. If it breaks, it needed replacing anyway.
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 828 bytes --]
^ permalink raw reply
* Re: [RFC net-next (v2) 12/14] ixgbe: set maximal number of default RSS queues
From: Alexander Duyck @ 2012-06-26 15:55 UTC (permalink / raw)
To: Yuval Mintz; +Cc: eilong, davem, netdev, Jeff Kirsher, John Fastabend
In-Reply-To: <4FE9983C.2060006@broadcom.com>
On 06/26/2012 04:08 AM, Yuval Mintz wrote:
>>> How about this:
>>> diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_lib.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_lib.c
>>> index af1a531..23a8609 100644
>>> --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_lib.c
>>> +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_lib.c
>>> @@ -277,6 +277,8 @@ static inline bool ixgbe_set_rss_queues(struct ixgbe_adapter *adapter)
>>> bool ret = false;
>>> struct ixgbe_ring_feature *f = &adapter->ring_feature[RING_F_RSS];
>>>
>>> + f->indices = min_t(int, netif_get_num_default_rss_queues(), f->indices);
>>> +
>>> if (adapter->flags & IXGBE_FLAG_RSS_ENABLED) {
>>> f->mask = 0xF;
>>> adapter->num_rx_queues = f->indices;
>>> @@ -302,7 +304,9 @@ static inline bool ixgbe_set_fdir_queues(struct ixgbe_adapter *adapter)
>>> bool ret = false;
>>> struct ixgbe_ring_feature *f_fdir = &adapter->ring_feature[RING_F_FDIR];
>>>
>>> - f_fdir->indices = min_t(int, num_online_cpus(), f_fdir->indices);
>>> + f_fdir->indices = min_t(int, netif_get_num_default_rss_queues(),
>>> + f_fdir->indices);
>>> +
>>> f_fdir->mask = 0;
>>>
>>> /*
>>> @@ -339,8 +343,7 @@ static inline bool ixgbe_set_fcoe_queues(struct ixgbe_adapter *adapter)
>>> if (!(adapter->flags & IXGBE_FLAG_FCOE_ENABLED))
>>> return false;
>>>
>>> - f->indices = min_t(int, num_online_cpus(), f->indices);
>>> -
>>> + f->indices = min_t(int, f->indices, netif_get_num_default_rss_queues());
>>> adapter->num_rx_queues = 1;
>>> adapter->num_tx_queues = 1;
>>>
>> This makes much more sense, but still needs a few minor changes.
>
>
> Well, what about this one:
>
> diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_lib.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_lib.c
> index af1a531..0dd1e51 100644
> --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_lib.c
> +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_lib.c
> @@ -277,6 +277,7 @@ static inline bool ixgbe_set_rss_queues(struct ixgbe_adapter *adapter)
> bool ret = false;
> struct ixgbe_ring_feature *f = &adapter->ring_feature[RING_F_RSS];
>
> + f->indices = min_t(int, netif_get_num_default_rss_queues(), f->indices);
> if (adapter->flags & IXGBE_FLAG_RSS_ENABLED) {
> f->mask = 0xF;
> adapter->num_rx_queues = f->indices;
> @@ -376,7 +377,7 @@ static inline bool ixgbe_set_dcb_queues(struct ixgbe_adapter *adapter)
>
> /* Map queue offset and counts onto allocated tx queues */
> per_tc_q = min_t(unsigned int, dev->num_tx_queues / tcs, DCB_QUEUE_CAP);
> - q = min_t(int, num_online_cpus(), per_tc_q);
> + q = min_t(int, netif_get_num_default_rss_queues(), per_tc_q);
>
> for (i = 0; i < tcs; i++) {
> netdev_set_tc_queue(dev, i, q, offset);
>
Add back in the bit for ixgbe_set_fcoe_queues and you should just about
have it in terms of limiting the number of RSS queues. That bit is
valid since the FCoE queues are based directly off of the RSS configuration.
One thing that just occurred to me though is that this is going to lock
the upper limit for us and we won't be able to override it if we
implement the set channels code. I believe the same thing goes for the
igb driver as well.
Is there any chance you could just bypass the ixgbe and igb drivers for
now and give us time to come up with a more complete solution that would
allow us to add the set_channels calls. One issue is I have a number of
ixgbe patches that are going to be completely rewriting this code anyway
so I could probably just add set_channels support and support for your
function once it is included in net-next.
Thanks,
Alex
^ permalink raw reply
* [PATCH 1/1] connector: use nlmsg_put() instead of NLMSG_PUT() macro.
From: Javier Martinez Canillas @ 2012-06-26 15:41 UTC (permalink / raw)
To: Evgeniy Polyakov; +Cc: netdev, Javier Martinez Canillas
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 <javier.martinez@collabora.co.uk>
---
drivers/connector/connector.c | 12 ++++++------
1 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/drivers/connector/connector.c b/drivers/connector/connector.c
index a1f9364..a728d33 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);
--
1.7.7.6
^ permalink raw reply related
* [PATCH] bridge: Assign rtnl_link_ops to bridge devices created via ioctl (v2)
From: Stephen Hemminger @ 2012-06-26 15:48 UTC (permalink / raw)
To: davem; +Cc: Thomas Graf, netdev
In-Reply-To: <20120626151311.GB31808@canuck.infradead.org>
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 <tgraf@suug.ch>
Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>
---
v2 - Minor change to Thomas's original patch.
This is a bug fix, should go to stable as well.
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(-)
--- a/net/bridge/br_netlink.c 2012-06-26 08:07:18.459760113 -0700
+++ b/net/bridge/br_netlink.c 2012-06-26 08:30:16.729918150 -0700
@@ -208,7 +208,7 @@ static int br_validate(struct nlattr *tb
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,
--- a/net/bridge/br_private.h 2012-06-26 08:07:18.459760113 -0700
+++ b/net/bridge/br_private.h 2012-06-26 08:30:16.729918150 -0700
@@ -549,6 +549,7 @@ extern int (*br_fdb_test_addr_hook)(stru
#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);
--- a/net/bridge/br_if.c 2012-06-26 08:07:18.459760113 -0700
+++ b/net/bridge/br_if.c 2012-06-26 08:30:37.653708011 -0700
@@ -240,6 +240,7 @@ int br_add_bridge(struct net *net, const
return -ENOMEM;
dev_net_set(dev, net);
+ dev->rtnl_link_ops = &br_link_ops;
res = register_netdev(dev);
if (res)
^ permalink raw reply
* Re: [net] ixgbe: Do not pad FCoE frames as this can cause issues with FCoE DDP
From: Alexander Duyck @ 2012-06-26 15:48 UTC (permalink / raw)
To: Ben Hutchings
Cc: jeffrey.t.kirsher, David Miller, netdev, gospo, sassmann, stable
In-Reply-To: <1340719768.5330.2.camel@deadeye.wl.decadent.org.uk>
On 06/26/2012 07:09 AM, Ben Hutchings wrote:
> On Tue, 2012-06-26 at 00:53 -0700, Jeff Kirsher wrote:
>> On Tue, 2012-06-26 at 00:50 -0700, David Miller wrote:
>>> Sorry, quotes don't work either, what you did is still a SMTP syntax error,
>>> here's what is in the bounce I get back:
>>>
>>> <stable@vger.kernel.org> "[3.4]",
>>> Jeff Kirsher <jeffrey.t.kirsher@intel.com>
>>> Illegal-Object: Syntax error in Cc: address found on vger.kernel.org:
>>> Cc: <stable@vger.kernel.org>"[3.4]"
>>> ^-missing end of address
>> Grrr...
>>
>> I will re-send without the "[3.4]", Greg will just have to deal with it.
> It's certainly not necessary to put anything like that in the real Cc
> header. Many people put something like
> 'Cc: <stable@vger.kernel.org> # 3.4' in the body; I don't know if that
> is more like likely to result in the version being stripped when
> generating mail recipients.
>
> Ben.
>
Couldn't 3.4 have been put in place of the recipient's name? So you do
something like this:
Cc: 3.4 <stable@vger.kernel.org>
Thanks,
Alex
^ permalink raw reply
* [PATCH 1/1] atl1c: fix issue of transmit queue 0 timed out
From: Ren, Cloud @ 2012-06-26 15:33 UTC (permalink / raw)
To: davem, netdev, linux-kernel; +Cc: qca-linux-team, nic-devel, xiong
From: xiong <xiong@qca.qualcomm.com>
some people report atl1c could cause system hang with following
kernel trace info:
---------------------------------------
WARNING: at.../net/sched/sch_generic.c:258
dev_watchdog+0x1db/0x1d0()
...
NETDEV WATCHDOG: eth0 (atl1c): transmit queue 0 timed out
...
---------------------------------------
This is caused by netif_stop_queue calling when cable Link is down
but netif_wake_queue isn't called when cable Link is resume.
Signed-off-by: xiong <xiong@qca.qualcomm.com>
Signed-off-by: Cloud Ren <cjren@qca.qualcomm.com>
---
drivers/net/ethernet/atheros/atl1c/atl1c_main.c | 2 ++
1 files changed, 2 insertions(+), 0 deletions(-)
diff --git a/drivers/net/ethernet/atheros/atl1c/atl1c_main.c b/drivers/net/ethernet/atheros/atl1c/atl1c_main.c
index 85717cb..c2736c4 100644
--- a/drivers/net/ethernet/atheros/atl1c/atl1c_main.c
+++ b/drivers/net/ethernet/atheros/atl1c/atl1c_main.c
@@ -351,6 +351,8 @@ static void atl1c_common_task(struct work_struct *work)
atl1c_irq_disable(adapter);
atl1c_check_link_status(adapter);
atl1c_irq_enable(adapter);
+ if (netif_queue_stopped(netdev) && netif_carrier_ok(netdev))
+ netif_wake_queue(netdev);
}
}
--
1.7.7
^ permalink raw reply related
* Re: [PATCH 09/16] netvm: Allow skb allocation to use PFMEMALLOC reserves
From: Sebastian Andrzej Siewior @ 2012-06-26 15:27 UTC (permalink / raw)
To: Mel Gorman
Cc: Andrew Morton, Linux-MM, Linux-Netdev, LKML, David Miller,
Neil Brown, Peter Zijlstra, Mike Christie, Eric B Munson,
Eric Dumazet
In-Reply-To: <1340375443-22455-10-git-send-email-mgorman@suse.de>
On Fri, Jun 22, 2012 at 03:30:36PM +0100, Mel Gorman wrote:
> diff --git a/net/core/sock.c b/net/core/sock.c
> index 5c9ca2b..159dccc 100644
> --- a/net/core/sock.c
> +++ b/net/core/sock.c
> @@ -271,6 +271,9 @@ __u32 sysctl_rmem_default __read_mostly = SK_RMEM_MAX;
> int sysctl_optmem_max __read_mostly = sizeof(unsigned long)*(2*UIO_MAXIOV+512);
> EXPORT_SYMBOL(sysctl_optmem_max);
>
> +struct static_key memalloc_socks = STATIC_KEY_INIT_FALSE;
> +EXPORT_SYMBOL_GPL(memalloc_socks);
> +
This is used via sk_memalloc_socks() by SLAB.
>From 3da9ab9972845974da114c5a6624335e6371b2d5 Mon Sep 17 00:00:00 2001
From: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Date: Tue, 26 Jun 2012 17:18:20 +0200
Subject: [PATCH] export sk_memalloc_socks() only with CONFIG_NET
|mm/built-in.o: In function `atomic_read':
|include/asm/atomic.h:25: undefined reference to `memalloc_socks'
|include/asm/atomic.h:25: undefined reference to `memalloc_socks'
|include/asm/atomic.h:25: undefined reference to `memalloc_socks'
|include/asm/atomic.h:25: undefined reference to `memalloc_socks'
|include/asm/atomic.h:25: undefined reference to `memalloc_socks'
|mm/built-in.o:include/asm/atomic.h:25: more undefined references to `memalloc_socks' follow
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
---
include/net/sock.h | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/include/net/sock.h b/include/net/sock.h
index db0c20c..767c443 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -659,11 +659,20 @@ static inline bool sock_flag(const struct sock *sk, enum sock_flags flag)
return test_bit(flag, &sk->sk_flags);
}
+#ifdef CONFIG_NET
extern struct static_key memalloc_socks;
static inline int sk_memalloc_socks(void)
{
return static_key_false(&memalloc_socks);
}
+#else
+
+static inline int sk_memalloc_socks(void)
+{
+ return 0;
+}
+
+#endif
static inline gfp_t sk_gfp_atomic(struct sock *sk, gfp_t gfp_mask)
{
--
1.7.10
Sebastian
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox