* [PATCH net-next] can-gw: add netlink based CAN routing
From: Oliver Hartkopp @ 2011-09-01 14:23 UTC (permalink / raw)
To: David Miller
Cc: Linux Netdev List, Michal Sojka, Pavel Píša,
Zdenek Hanzálek, Oliver Hartkopp
This patch adds a CAN Gateway/Router to route (and modify) CAN frames.
It is based on the PF_CAN core infrastructure for msg filtering and msg
sending and can optionally modify routed CAN frames on the fly.
CAN frames can *only* be routed between CAN network interfaces (one hop).
They can be modified with AND/OR/XOR/SET operations as configured by the
netlink configuration interface known e.g. from iptables. From the netlink
view this can-gw implements RTM_{NEW|DEL|GET}ROUTE for PF_CAN.
The CAN specific userspace tool to manage CAN routing entries can be found in
the CAN utils http://svn.berlios.de/wsvn/socketcan/trunk/can-utils/cangw.c
at the SocketCAN SVN on BerliOS.
Signed-off-by: Oliver Hartkopp <socketcan@hartkopp.net>
---
The in-kernel CAN frame routing has been implemented to due performance
issues and has turned out to be a valuable tool in multiple projects.
It relies on the networking stack and uses the efficient PF_CAN CAN filters.
It has been analyzed and checked against -rt kernels by University of Prague
(DCE), where a real good performace of this approach could be shown. Only
with heavy ethernet load the routing times increased - but that's networking.
See at http://rtime.felk.cvut.cz/can/benchmark/1/ and .../benchmark/2/
Special thanks for review, feedback, bug-reports & measurements to Michal
Sojka, Pavel Píša and Zdenek Hanzálek from department of control engineering.
include/linux/can/Kbuild | 1
include/linux/can/gw.h | 164 ++++++
net/can/Kconfig | 11
net/can/Makefile | 3
net/can/gw.c | 959 +++++++++++++++++++++++++++++++++++++
5 files changed, 1138 insertions(+)
diff -u -r -N a/include/linux/can/gw.h b/include/linux/can/gw.h
--- a/include/linux/can/gw.h 1970-01-01 01:00:00.000000000 +0100
+++ b/include/linux/can/gw.h 2011-09-01 11:33:47.966271223 +0200
@@ -0,0 +1,164 @@
+/*
+ * linux/can/gw.h
+ *
+ * Definitions for CAN frame Gateway/Router/Bridge
+ *
+ * Author: Oliver Hartkopp <oliver.hartkopp@volkswagen.de>
+ * Copyright (c) 2011 Volkswagen Group Electronic Research
+ * All rights reserved.
+ *
+ * Send feedback to <socketcan-users@lists.berlios.de>
+ *
+ */
+
+#ifndef CAN_GW_H
+#define CAN_GW_H
+
+#include <linux/types.h>
+#include <linux/can.h>
+
+struct rtcanmsg {
+ __u8 can_family;
+ __u8 gwtype;
+ __u16 flags;
+};
+
+/* CAN gateway types */
+enum {
+ CGW_TYPE_UNSPEC,
+ CGW_TYPE_CAN_CAN, /* CAN->CAN routing */
+ __CGW_TYPE_MAX
+};
+
+#define CGW_TYPE_MAX (__CGW_TYPE_MAX - 1)
+
+/* CAN rtnetlink attribute definitions */
+enum {
+ CGW_UNSPEC,
+ CGW_MOD_AND, /* CAN frame modification binary AND */
+ CGW_MOD_OR, /* CAN frame modification binary OR */
+ CGW_MOD_XOR, /* CAN frame modification binary XOR */
+ CGW_MOD_SET, /* CAN frame modification set alternate values */
+ CGW_CS_XOR, /* set data[] XOR checksum into data[index] */
+ CGW_CS_CRC8, /* set data[] CRC8 checksum into data[index] */
+ CGW_HANDLED, /* number of handled CAN frames */
+ CGW_DROPPED, /* number of dropped CAN frames */
+ CGW_SRC_IF, /* ifindex of source network interface */
+ CGW_DST_IF, /* ifindex of destination network interface */
+ CGW_FILTER, /* specify struct can_filter on source CAN device */
+ __CGW_MAX
+};
+
+#define CGW_MAX (__CGW_MAX - 1)
+
+#define CGW_FLAGS_CAN_ECHO 0x01
+#define CGW_FLAGS_CAN_SRC_TSTAMP 0x02
+
+#define CGW_MOD_FUNCS 4 /* AND OR XOR SET */
+
+/* CAN frame elements that are affected by curr. 3 CAN frame modifications */
+#define CGW_MOD_ID 0x01
+#define CGW_MOD_DLC 0x02
+#define CGW_MOD_DATA 0x04
+
+#define CGW_FRAME_MODS 3 /* ID DLC DATA */
+
+#define MAX_MODFUNCTIONS (CGW_MOD_FUNCS * CGW_FRAME_MODS)
+
+struct cgw_frame_mod {
+ struct can_frame cf;
+ __u8 modtype;
+} __attribute__((packed));
+
+#define CGW_MODATTR_LEN sizeof(struct cgw_frame_mod)
+
+struct cgw_csum_xor {
+ __s8 from_idx;
+ __s8 to_idx;
+ __s8 result_idx;
+ __u8 init_xor_val;
+} __attribute__((packed));
+
+struct cgw_csum_crc8 {
+ __s8 from_idx;
+ __s8 to_idx;
+ __s8 result_idx;
+ __u8 init_crc_val;
+ __u8 final_xor_val;
+ __u8 crctab[256];
+ __u8 profile;
+ __u8 profile_data[20];
+} __attribute__((packed));
+
+/* length of checksum operation parameters. idx = index in CAN frame data[] */
+#define CGW_CS_XOR_LEN sizeof(struct cgw_csum_xor)
+#define CGW_CS_CRC8_LEN sizeof(struct cgw_csum_crc8)
+
+/* CRC8 profiles (compute CRC for additional data elements - see below) */
+enum {
+ CGW_CRC8PRF_UNSPEC,
+ CGW_CRC8PRF_1U8, /* compute one additional u8 value */
+ CGW_CRC8PRF_16U8, /* u8 value table indexed by data[1] & 0xF */
+ CGW_CRC8PRF_SFFID_XOR, /* (can_id & 0xFF) ^ (can_id >> 8 & 0xFF) */
+ __CGW_CRC8PRF_MAX
+};
+
+#define CGW_CRC8PRF_MAX (__CGW_CRC8PRF_MAX - 1)
+
+/*
+ * CAN rtnetlink attribute contents in detail
+ *
+ * CGW_XXX_IF (length 4 bytes):
+ * Sets an interface index for source/destination network interfaces.
+ * For the CAN->CAN gwtype the indices of _two_ CAN interfaces are mandatory.
+ *
+ * CGW_FILTER (length 8 bytes):
+ * Sets a CAN receive filter for the gateway job specified by the
+ * struct can_filter described in include/linux/can.h
+ *
+ * CGW_MOD_XXX (length 17 bytes):
+ * Specifies a modification that's done to a received CAN frame before it is
+ * send out to the destination interface.
+ *
+ * <struct can_frame> data used as operator
+ * <u8> affected CAN frame elements
+ *
+ * CGW_CS_XOR (length 4 bytes):
+ * Set a simple XOR checksum starting with an initial value into
+ * data[result-idx] using data[start-idx] .. data[end-idx]
+ *
+ * The XOR checksum is calculated like this:
+ *
+ * xor = init_xor_val
+ *
+ * for (i = from_idx .. to_idx)
+ * xor ^= can_frame.data[i]
+ *
+ * can_frame.data[ result_idx ] = xor
+ *
+ * CGW_CS_CRC8 (length 282 bytes):
+ * Set a CRC8 value into data[result-idx] using a given 256 byte CRC8 table,
+ * a given initial value and a defined input data[start-idx] .. data[end-idx].
+ * Finally the result value is XOR'ed with the final_xor_val.
+ *
+ * The CRC8 checksum is calculated like this:
+ *
+ * crc = init_crc_val
+ *
+ * for (i = from_idx .. to_idx)
+ * crc = crctab[ crc ^ can_frame.data[i] ]
+ *
+ * can_frame.data[ result_idx ] = crc ^ final_xor_val
+ *
+ * The calculated CRC may contain additional source data elements that can be
+ * defined in the handling of 'checksum profiles' e.g. shown in AUTOSAR specs
+ * like http://www.autosar.org/download/R4.0/AUTOSAR_SWS_E2ELibrary.pdf
+ * E.g. the profile_data[] may contain additional u8 values (called DATA_IDs)
+ * that are used depending on counter values inside the CAN frame data[].
+ * So far only three profiles have been implemented for illustration.
+ *
+ * Remark: In general the attribute data is a linear buffer.
+ * Beware of sending unpacked or aligned structs!
+ */
+
+#endif
diff -u -r -N a/include/linux/can/Kbuild b/include/linux/can/Kbuild
--- a/include/linux/can/Kbuild 2011-08-31 21:28:47.515610142 +0200
+++ b/include/linux/can/Kbuild 2011-08-31 21:29:24.343608873 +0200
@@ -1,4 +1,5 @@
header-y += raw.h
header-y += bcm.h
+header-y += gw.h
header-y += error.h
header-y += netlink.h
diff -u -r -N a/net/can/gw.c b/net/can/gw.c
--- a/net/can/gw.c 1970-01-01 01:00:00.000000000 +0100
+++ b/net/can/gw.c 2011-09-01 11:26:56.898284721 +0200
@@ -0,0 +1,959 @@
+/*
+ * gw.c - CAN frame Gateway/Router/Bridge with netlink interface
+ *
+ * Copyright (c) 2011 Volkswagen Group Electronic Research
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Volkswagen nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * Alternatively, provided that this notice is retained in full, this
+ * software may be distributed under the terms of the GNU General
+ * Public License ("GPL") version 2, in which case the provisions of the
+ * GPL apply INSTEAD OF those given above.
+ *
+ * The provided data structures and external interfaces from this code
+ * are not restricted to be used by modules with a GPL compatible license.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * Send feedback to <socketcan-users@lists.berlios.de>
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/list.h>
+#include <linux/spinlock.h>
+#include <linux/rcupdate.h>
+#include <linux/rculist.h>
+#include <linux/net.h>
+#include <linux/netdevice.h>
+#include <linux/if_arp.h>
+#include <linux/skbuff.h>
+#include <linux/can.h>
+#include <linux/can/core.h>
+#include <linux/can/gw.h>
+#include <net/rtnetlink.h>
+#include <net/net_namespace.h>
+#include <net/sock.h>
+
+#define CAN_GW_VERSION "20101209"
+static __initdata const char banner[] =
+ KERN_INFO "can: netlink gateway (rev " CAN_GW_VERSION ")\n";
+
+MODULE_DESCRIPTION("PF_CAN netlink gateway");
+MODULE_LICENSE("Dual BSD/GPL");
+MODULE_AUTHOR("Oliver Hartkopp <oliver.hartkopp@volkswagen.de>");
+MODULE_ALIAS("can-gw");
+
+HLIST_HEAD(cgw_list);
+static struct notifier_block notifier;
+
+static struct kmem_cache *cgw_cache __read_mostly;
+
+/* structure that contains the (on-the-fly) CAN frame modifications */
+struct cf_mod {
+ struct {
+ struct can_frame and;
+ struct can_frame or;
+ struct can_frame xor;
+ struct can_frame set;
+ } modframe;
+ struct {
+ u8 and;
+ u8 or;
+ u8 xor;
+ u8 set;
+ } modtype;
+ void (*modfunc[MAX_MODFUNCTIONS])(struct can_frame *cf,
+ struct cf_mod *mod);
+
+ /* CAN frame checksum calculation after CAN frame modifications */
+ struct {
+ struct cgw_csum_xor xor;
+ struct cgw_csum_crc8 crc8;
+ } csum;
+ struct {
+ void (*xor)(struct can_frame *cf, struct cgw_csum_xor *xor);
+ void (*crc8)(struct can_frame *cf, struct cgw_csum_crc8 *crc8);
+ } csumfunc;
+};
+
+
+/*
+ * So far we just support CAN -> CAN routing and frame modifications.
+ *
+ * The internal can_can_gw structure contains data and attributes for
+ * a CAN -> CAN gateway job.
+ */
+struct can_can_gw {
+ struct can_filter filter;
+ int src_idx;
+ int dst_idx;
+};
+
+/* list entry for CAN gateways jobs */
+struct cgw_job {
+ struct hlist_node list;
+ struct rcu_head rcu;
+ u32 handled_frames;
+ u32 dropped_frames;
+ struct cf_mod mod;
+ union {
+ /* CAN frame data source */
+ struct net_device *dev;
+ } src;
+ union {
+ /* CAN frame data destination */
+ struct net_device *dev;
+ } dst;
+ union {
+ struct can_can_gw ccgw;
+ /* tbc */
+ };
+ u8 gwtype;
+ u16 flags;
+};
+
+/* modification functions that are invoked in the hot path in can_can_gw_rcv */
+
+#define MODFUNC(func, op) static void func(struct can_frame *cf, \
+ struct cf_mod *mod) { op ; }
+
+MODFUNC(mod_and_id, cf->can_id &= mod->modframe.and.can_id)
+MODFUNC(mod_and_dlc, cf->can_dlc &= mod->modframe.and.can_dlc)
+MODFUNC(mod_and_data, *(u64 *)cf->data &= *(u64 *)mod->modframe.and.data)
+MODFUNC(mod_or_id, cf->can_id |= mod->modframe.or.can_id)
+MODFUNC(mod_or_dlc, cf->can_dlc |= mod->modframe.or.can_dlc)
+MODFUNC(mod_or_data, *(u64 *)cf->data |= *(u64 *)mod->modframe.or.data)
+MODFUNC(mod_xor_id, cf->can_id ^= mod->modframe.xor.can_id)
+MODFUNC(mod_xor_dlc, cf->can_dlc ^= mod->modframe.xor.can_dlc)
+MODFUNC(mod_xor_data, *(u64 *)cf->data ^= *(u64 *)mod->modframe.xor.data)
+MODFUNC(mod_set_id, cf->can_id = mod->modframe.set.can_id)
+MODFUNC(mod_set_dlc, cf->can_dlc = mod->modframe.set.can_dlc)
+MODFUNC(mod_set_data, *(u64 *)cf->data = *(u64 *)mod->modframe.set.data)
+
+static inline void canframecpy(struct can_frame *dst, struct can_frame *src)
+{
+ /*
+ * Copy the struct members separately to ensure that no uninitialized
+ * data are copied in the 3 bytes hole of the struct. This is needed
+ * to make easy compares of the data in the struct cf_mod.
+ */
+
+ dst->can_id = src->can_id;
+ dst->can_dlc = src->can_dlc;
+ *(u64 *)dst->data = *(u64 *)src->data;
+}
+
+static int cgw_chk_csum_parms(s8 fr, s8 to, s8 re)
+{
+ /*
+ * absolute dlc values 0 .. 7 => 0 .. 7, e.g. data [0]
+ * relative to received dlc -1 .. -8 :
+ * e.g. for received dlc = 8
+ * -1 => index = 7 (data[7])
+ * -3 => index = 5 (data[5])
+ * -8 => index = 0 (data[0])
+ */
+
+ if (fr > -9 && fr < 8 &&
+ to > -9 && to < 8 &&
+ re > -9 && re < 8)
+ return 0;
+ else
+ return -EINVAL;
+}
+
+static inline int calc_idx(int idx, int rx_dlc)
+{
+ if (idx < 0)
+ return rx_dlc + idx;
+ else
+ return idx;
+}
+
+static void cgw_csum_xor_rel(struct can_frame *cf, struct cgw_csum_xor *xor)
+{
+ int from = calc_idx(xor->from_idx, cf->can_dlc);
+ int to = calc_idx(xor->to_idx, cf->can_dlc);
+ int res = calc_idx(xor->result_idx, cf->can_dlc);
+ u8 val = xor->init_xor_val;
+ int i;
+
+ if (from < 0 || to < 0 || res < 0)
+ return;
+
+ if (from <= to) {
+ for (i = from; i <= to; i++)
+ val ^= cf->data[i];
+ } else {
+ for (i = from; i >= to; i--)
+ val ^= cf->data[i];
+ }
+
+ cf->data[res] = val;
+}
+
+static void cgw_csum_xor_pos(struct can_frame *cf, struct cgw_csum_xor *xor)
+{
+ u8 val = xor->init_xor_val;
+ int i;
+
+ for (i = xor->from_idx; i <= xor->to_idx; i++)
+ val ^= cf->data[i];
+
+ cf->data[xor->result_idx] = val;
+}
+
+static void cgw_csum_xor_neg(struct can_frame *cf, struct cgw_csum_xor *xor)
+{
+ u8 val = xor->init_xor_val;
+ int i;
+
+ for (i = xor->from_idx; i >= xor->to_idx; i--)
+ val ^= cf->data[i];
+
+ cf->data[xor->result_idx] = val;
+}
+
+static void cgw_csum_crc8_rel(struct can_frame *cf, struct cgw_csum_crc8 *crc8)
+{
+ int from = calc_idx(crc8->from_idx, cf->can_dlc);
+ int to = calc_idx(crc8->to_idx, cf->can_dlc);
+ int res = calc_idx(crc8->result_idx, cf->can_dlc);
+ u8 crc = crc8->init_crc_val;
+ int i;
+
+ if (from < 0 || to < 0 || res < 0)
+ return;
+
+ if (from <= to) {
+ for (i = crc8->from_idx; i <= crc8->to_idx; i++)
+ crc = crc8->crctab[crc^cf->data[i]];
+ } else {
+ for (i = crc8->from_idx; i >= crc8->to_idx; i--)
+ crc = crc8->crctab[crc^cf->data[i]];
+ }
+
+ switch (crc8->profile) {
+
+ case CGW_CRC8PRF_1U8:
+ crc = crc8->crctab[crc^crc8->profile_data[0]];
+ break;
+
+ case CGW_CRC8PRF_16U8:
+ crc = crc8->crctab[crc^crc8->profile_data[cf->data[1] & 0xF]];
+ break;
+
+ case CGW_CRC8PRF_SFFID_XOR:
+ crc = crc8->crctab[crc^(cf->can_id & 0xFF)^
+ (cf->can_id >> 8 & 0xFF)];
+ break;
+
+ }
+
+ cf->data[crc8->result_idx] = crc^crc8->final_xor_val;
+}
+
+static void cgw_csum_crc8_pos(struct can_frame *cf, struct cgw_csum_crc8 *crc8)
+{
+ u8 crc = crc8->init_crc_val;
+ int i;
+
+ for (i = crc8->from_idx; i <= crc8->to_idx; i++)
+ crc = crc8->crctab[crc^cf->data[i]];
+
+ switch (crc8->profile) {
+
+ case CGW_CRC8PRF_1U8:
+ crc = crc8->crctab[crc^crc8->profile_data[0]];
+ break;
+
+ case CGW_CRC8PRF_16U8:
+ crc = crc8->crctab[crc^crc8->profile_data[cf->data[1] & 0xF]];
+ break;
+
+ case CGW_CRC8PRF_SFFID_XOR:
+ crc = crc8->crctab[crc^(cf->can_id & 0xFF)^
+ (cf->can_id >> 8 & 0xFF)];
+ break;
+ }
+
+ cf->data[crc8->result_idx] = crc^crc8->final_xor_val;
+}
+
+static void cgw_csum_crc8_neg(struct can_frame *cf, struct cgw_csum_crc8 *crc8)
+{
+ u8 crc = crc8->init_crc_val;
+ int i;
+
+ for (i = crc8->from_idx; i >= crc8->to_idx; i--)
+ crc = crc8->crctab[crc^cf->data[i]];
+
+ switch (crc8->profile) {
+
+ case CGW_CRC8PRF_1U8:
+ crc = crc8->crctab[crc^crc8->profile_data[0]];
+ break;
+
+ case CGW_CRC8PRF_16U8:
+ crc = crc8->crctab[crc^crc8->profile_data[cf->data[1] & 0xF]];
+ break;
+
+ case CGW_CRC8PRF_SFFID_XOR:
+ crc = crc8->crctab[crc^(cf->can_id & 0xFF)^
+ (cf->can_id >> 8 & 0xFF)];
+ break;
+ }
+
+ cf->data[crc8->result_idx] = crc^crc8->final_xor_val;
+}
+
+/* the receive & process & send function */
+static void can_can_gw_rcv(struct sk_buff *skb, void *data)
+{
+ struct cgw_job *gwj = (struct cgw_job *)data;
+ struct can_frame *cf;
+ struct sk_buff *nskb;
+ int modidx = 0;
+
+ /* do not handle already routed frames - see comment below */
+ if (skb_mac_header_was_set(skb))
+ return;
+
+ if (!(gwj->dst.dev->flags & IFF_UP)) {
+ gwj->dropped_frames++;
+ return;
+ }
+
+ /*
+ * clone the given skb, which has not been done in can_rcv()
+ *
+ * When there is at least one modification function activated,
+ * we need to copy the skb as we want to modify skb->data.
+ */
+ if (gwj->mod.modfunc[0])
+ nskb = skb_copy(skb, GFP_ATOMIC);
+ else
+ nskb = skb_clone(skb, GFP_ATOMIC);
+
+ if (!nskb) {
+ gwj->dropped_frames++;
+ return;
+ }
+
+ /*
+ * Mark routed frames by setting some mac header length which is
+ * not relevant for the CAN frames located in the skb->data section.
+ *
+ * As dev->header_ops is not set in CAN netdevices no one is ever
+ * accessing the various header offsets in the CAN skbuffs anyway.
+ * E.g. using the packet socket to read CAN frames is still working.
+ */
+ skb_set_mac_header(nskb, 8);
+ nskb->dev = gwj->dst.dev;
+
+ /* pointer to modifiable CAN frame */
+ cf = (struct can_frame *)nskb->data;
+
+ /* perform preprocessed modification functions if there are any */
+ while (modidx < MAX_MODFUNCTIONS && gwj->mod.modfunc[modidx])
+ (*gwj->mod.modfunc[modidx++])(cf, &gwj->mod);
+
+ /* check for checksum updates when the CAN frame has been modified */
+ if (modidx) {
+ if (gwj->mod.csumfunc.crc8)
+ (*gwj->mod.csumfunc.crc8)(cf, &gwj->mod.csum.crc8);
+
+ if (gwj->mod.csumfunc.xor)
+ (*gwj->mod.csumfunc.xor)(cf, &gwj->mod.csum.xor);
+ }
+
+ /* clear the skb timestamp if not configured the other way */
+ if (!(gwj->flags & CGW_FLAGS_CAN_SRC_TSTAMP))
+ nskb->tstamp.tv64 = 0;
+
+ /* send to netdevice */
+ if (can_send(nskb, gwj->flags & CGW_FLAGS_CAN_ECHO))
+ gwj->dropped_frames++;
+ else
+ gwj->handled_frames++;
+}
+
+static inline int cgw_register_filter(struct cgw_job *gwj)
+{
+ return can_rx_register(gwj->src.dev, gwj->ccgw.filter.can_id,
+ gwj->ccgw.filter.can_mask, can_can_gw_rcv,
+ gwj, "gw");
+}
+
+static inline void cgw_unregister_filter(struct cgw_job *gwj)
+{
+ can_rx_unregister(gwj->src.dev, gwj->ccgw.filter.can_id,
+ gwj->ccgw.filter.can_mask, can_can_gw_rcv, gwj);
+}
+
+static int cgw_notifier(struct notifier_block *nb,
+ unsigned long msg, void *data)
+{
+ struct net_device *dev = (struct net_device *)data;
+
+ if (!net_eq(dev_net(dev), &init_net))
+ return NOTIFY_DONE;
+ if (dev->type != ARPHRD_CAN)
+ return NOTIFY_DONE;
+
+ if (msg == NETDEV_UNREGISTER) {
+
+ struct cgw_job *gwj = NULL;
+ struct hlist_node *n, *nx;
+
+ ASSERT_RTNL();
+
+ hlist_for_each_entry_safe(gwj, n, nx, &cgw_list, list) {
+
+ if (gwj->src.dev == dev || gwj->dst.dev == dev) {
+ hlist_del(&gwj->list);
+ cgw_unregister_filter(gwj);
+ kfree(gwj);
+ }
+ }
+ }
+
+ return NOTIFY_DONE;
+}
+
+static int cgw_put_job(struct sk_buff *skb, struct cgw_job *gwj)
+{
+ struct cgw_frame_mod mb;
+ struct rtcanmsg *rtcan;
+ struct nlmsghdr *nlh = nlmsg_put(skb, 0, 0, 0, sizeof(*rtcan), 0);
+ if (!nlh)
+ return -EMSGSIZE;
+
+ rtcan = nlmsg_data(nlh);
+ rtcan->can_family = AF_CAN;
+ rtcan->gwtype = gwj->gwtype;
+ rtcan->flags = gwj->flags;
+
+ /* add statistics if available */
+
+ if (gwj->handled_frames) {
+ if (nla_put_u32(skb, CGW_HANDLED, gwj->handled_frames) < 0)
+ goto cancel;
+ else
+ nlh->nlmsg_len += NLA_HDRLEN + NLA_ALIGN(sizeof(u32));
+ }
+
+ if (gwj->dropped_frames) {
+ if (nla_put_u32(skb, CGW_DROPPED, gwj->dropped_frames) < 0)
+ goto cancel;
+ else
+ nlh->nlmsg_len += NLA_HDRLEN + NLA_ALIGN(sizeof(u32));
+ }
+
+ /* check non default settings of attributes */
+
+ if (gwj->mod.modtype.and) {
+ memcpy(&mb.cf, &gwj->mod.modframe.and, sizeof(mb.cf));
+ mb.modtype = gwj->mod.modtype.and;
+ if (nla_put(skb, CGW_MOD_AND, sizeof(mb), &mb) < 0)
+ goto cancel;
+ else
+ nlh->nlmsg_len += NLA_HDRLEN + NLA_ALIGN(sizeof(mb));
+ }
+
+ if (gwj->mod.modtype.or) {
+ memcpy(&mb.cf, &gwj->mod.modframe.or, sizeof(mb.cf));
+ mb.modtype = gwj->mod.modtype.or;
+ if (nla_put(skb, CGW_MOD_OR, sizeof(mb), &mb) < 0)
+ goto cancel;
+ else
+ nlh->nlmsg_len += NLA_HDRLEN + NLA_ALIGN(sizeof(mb));
+ }
+
+ if (gwj->mod.modtype.xor) {
+ memcpy(&mb.cf, &gwj->mod.modframe.xor, sizeof(mb.cf));
+ mb.modtype = gwj->mod.modtype.xor;
+ if (nla_put(skb, CGW_MOD_XOR, sizeof(mb), &mb) < 0)
+ goto cancel;
+ else
+ nlh->nlmsg_len += NLA_HDRLEN + NLA_ALIGN(sizeof(mb));
+ }
+
+ if (gwj->mod.modtype.set) {
+ memcpy(&mb.cf, &gwj->mod.modframe.set, sizeof(mb.cf));
+ mb.modtype = gwj->mod.modtype.set;
+ if (nla_put(skb, CGW_MOD_SET, sizeof(mb), &mb) < 0)
+ goto cancel;
+ else
+ nlh->nlmsg_len += NLA_HDRLEN + NLA_ALIGN(sizeof(mb));
+ }
+
+ if (gwj->mod.csumfunc.crc8) {
+ if (nla_put(skb, CGW_CS_CRC8, CGW_CS_CRC8_LEN,
+ &gwj->mod.csum.crc8) < 0)
+ goto cancel;
+ else
+ nlh->nlmsg_len += NLA_HDRLEN + \
+ NLA_ALIGN(CGW_CS_CRC8_LEN);
+ }
+
+ if (gwj->mod.csumfunc.xor) {
+ if (nla_put(skb, CGW_CS_XOR, CGW_CS_XOR_LEN,
+ &gwj->mod.csum.xor) < 0)
+ goto cancel;
+ else
+ nlh->nlmsg_len += NLA_HDRLEN + \
+ NLA_ALIGN(CGW_CS_XOR_LEN);
+ }
+
+ if (gwj->gwtype == CGW_TYPE_CAN_CAN) {
+
+ if (gwj->ccgw.filter.can_id || gwj->ccgw.filter.can_mask) {
+ if (nla_put(skb, CGW_FILTER, sizeof(struct can_filter),
+ &gwj->ccgw.filter) < 0)
+ goto cancel;
+ else
+ nlh->nlmsg_len += NLA_HDRLEN +
+ NLA_ALIGN(sizeof(struct can_filter));
+ }
+
+ if (nla_put_u32(skb, CGW_SRC_IF, gwj->ccgw.src_idx) < 0)
+ goto cancel;
+ else
+ nlh->nlmsg_len += NLA_HDRLEN + NLA_ALIGN(sizeof(u32));
+
+ if (nla_put_u32(skb, CGW_DST_IF, gwj->ccgw.dst_idx) < 0)
+ goto cancel;
+ else
+ nlh->nlmsg_len += NLA_HDRLEN + NLA_ALIGN(sizeof(u32));
+ }
+
+ return skb->len;
+
+cancel:
+ nlmsg_cancel(skb, nlh);
+ return -EMSGSIZE;
+}
+
+/* Dump information about all CAN gateway jobs, in response to RTM_GETROUTE */
+static int cgw_dump_jobs(struct sk_buff *skb, struct netlink_callback *cb)
+{
+ struct cgw_job *gwj = NULL;
+ struct hlist_node *n;
+ int idx = 0;
+ int s_idx = cb->args[0];
+
+ rcu_read_lock();
+ hlist_for_each_entry_rcu(gwj, n, &cgw_list, list) {
+ if (idx < s_idx)
+ goto cont;
+
+ if (cgw_put_job(skb, gwj) < 0)
+ break;
+cont:
+ idx++;
+ }
+ rcu_read_unlock();
+
+ cb->args[0] = idx;
+
+ return skb->len;
+}
+
+/* check for common and gwtype specific attributes */
+static int cgw_parse_attr(struct nlmsghdr *nlh, struct cf_mod *mod,
+ u8 gwtype, void *gwtypeattr)
+{
+ struct nlattr *tb[CGW_MAX+1];
+ struct cgw_frame_mod mb;
+ int modidx = 0;
+ int err = 0;
+
+ /* initialize modification & checksum data space */
+ memset(mod, 0, sizeof(*mod));
+
+ err = nlmsg_parse(nlh, sizeof(struct rtcanmsg), tb, CGW_MAX, NULL);
+ if (err < 0)
+ return err;
+
+ /* check for AND/OR/XOR/SET modifications */
+
+ if (tb[CGW_MOD_AND] &&
+ nla_len(tb[CGW_MOD_AND]) == CGW_MODATTR_LEN) {
+ nla_memcpy(&mb, tb[CGW_MOD_AND], CGW_MODATTR_LEN);
+
+ canframecpy(&mod->modframe.and, &mb.cf);
+ mod->modtype.and = mb.modtype;
+
+ if (mb.modtype & CGW_MOD_ID)
+ mod->modfunc[modidx++] = mod_and_id;
+
+ if (mb.modtype & CGW_MOD_DLC)
+ mod->modfunc[modidx++] = mod_and_dlc;
+
+ if (mb.modtype & CGW_MOD_DATA)
+ mod->modfunc[modidx++] = mod_and_data;
+ }
+
+ if (tb[CGW_MOD_OR] &&
+ nla_len(tb[CGW_MOD_OR]) == CGW_MODATTR_LEN) {
+ nla_memcpy(&mb, tb[CGW_MOD_OR], CGW_MODATTR_LEN);
+
+ canframecpy(&mod->modframe.or, &mb.cf);
+ mod->modtype.or = mb.modtype;
+
+ if (mb.modtype & CGW_MOD_ID)
+ mod->modfunc[modidx++] = mod_or_id;
+
+ if (mb.modtype & CGW_MOD_DLC)
+ mod->modfunc[modidx++] = mod_or_dlc;
+
+ if (mb.modtype & CGW_MOD_DATA)
+ mod->modfunc[modidx++] = mod_or_data;
+ }
+
+ if (tb[CGW_MOD_XOR] &&
+ nla_len(tb[CGW_MOD_XOR]) == CGW_MODATTR_LEN) {
+ nla_memcpy(&mb, tb[CGW_MOD_XOR], CGW_MODATTR_LEN);
+
+ canframecpy(&mod->modframe.xor, &mb.cf);
+ mod->modtype.xor = mb.modtype;
+
+ if (mb.modtype & CGW_MOD_ID)
+ mod->modfunc[modidx++] = mod_xor_id;
+
+ if (mb.modtype & CGW_MOD_DLC)
+ mod->modfunc[modidx++] = mod_xor_dlc;
+
+ if (mb.modtype & CGW_MOD_DATA)
+ mod->modfunc[modidx++] = mod_xor_data;
+ }
+
+ if (tb[CGW_MOD_SET] &&
+ nla_len(tb[CGW_MOD_SET]) == CGW_MODATTR_LEN) {
+ nla_memcpy(&mb, tb[CGW_MOD_SET], CGW_MODATTR_LEN);
+
+ canframecpy(&mod->modframe.set, &mb.cf);
+ mod->modtype.set = mb.modtype;
+
+ if (mb.modtype & CGW_MOD_ID)
+ mod->modfunc[modidx++] = mod_set_id;
+
+ if (mb.modtype & CGW_MOD_DLC)
+ mod->modfunc[modidx++] = mod_set_dlc;
+
+ if (mb.modtype & CGW_MOD_DATA)
+ mod->modfunc[modidx++] = mod_set_data;
+ }
+
+ /* check for checksum operations after CAN frame modifications */
+ if (modidx) {
+
+ if (tb[CGW_CS_CRC8] &&
+ nla_len(tb[CGW_CS_CRC8]) == CGW_CS_CRC8_LEN) {
+
+ struct cgw_csum_crc8 *c = (struct cgw_csum_crc8 *)\
+ nla_data(tb[CGW_CS_CRC8]);
+
+ err = cgw_chk_csum_parms(c->from_idx, c->to_idx,
+ c->result_idx);
+ if (err)
+ return err;
+
+ nla_memcpy(&mod->csum.crc8, tb[CGW_CS_CRC8],
+ CGW_CS_CRC8_LEN);
+
+ /*
+ * select dedicated processing function to reduce
+ * runtime operations in receive hot path.
+ */
+ if (c->from_idx < 0 || c->to_idx < 0 ||
+ c->result_idx < 0)
+ mod->csumfunc.crc8 = cgw_csum_crc8_rel;
+ else if (c->from_idx <= c->to_idx)
+ mod->csumfunc.crc8 = cgw_csum_crc8_pos;
+ else
+ mod->csumfunc.crc8 = cgw_csum_crc8_neg;
+ }
+
+ if (tb[CGW_CS_XOR] &&
+ nla_len(tb[CGW_CS_XOR]) == CGW_CS_XOR_LEN) {
+
+ struct cgw_csum_xor *c = (struct cgw_csum_xor *)\
+ nla_data(tb[CGW_CS_XOR]);
+
+ err = cgw_chk_csum_parms(c->from_idx, c->to_idx,
+ c->result_idx);
+ if (err)
+ return err;
+
+ nla_memcpy(&mod->csum.xor, tb[CGW_CS_XOR],
+ CGW_CS_XOR_LEN);
+
+ /*
+ * select dedicated processing function to reduce
+ * runtime operations in receive hot path.
+ */
+ if (c->from_idx < 0 || c->to_idx < 0 ||
+ c->result_idx < 0)
+ mod->csumfunc.xor = cgw_csum_xor_rel;
+ else if (c->from_idx <= c->to_idx)
+ mod->csumfunc.xor = cgw_csum_xor_pos;
+ else
+ mod->csumfunc.xor = cgw_csum_xor_neg;
+ }
+ }
+
+ if (gwtype == CGW_TYPE_CAN_CAN) {
+
+ /* check CGW_TYPE_CAN_CAN specific attributes */
+
+ struct can_can_gw *ccgw = (struct can_can_gw *)gwtypeattr;
+ memset(ccgw, 0, sizeof(*ccgw));
+
+ /* check for can_filter in attributes */
+ if (tb[CGW_FILTER] &&
+ nla_len(tb[CGW_FILTER]) == sizeof(struct can_filter))
+ nla_memcpy(&ccgw->filter, tb[CGW_FILTER],
+ sizeof(struct can_filter));
+
+ err = -ENODEV;
+
+ /* specifying two interfaces is mandatory */
+ if (!tb[CGW_SRC_IF] || !tb[CGW_DST_IF])
+ return err;
+
+ if (nla_len(tb[CGW_SRC_IF]) == sizeof(u32))
+ nla_memcpy(&ccgw->src_idx, tb[CGW_SRC_IF],
+ sizeof(u32));
+
+ if (nla_len(tb[CGW_DST_IF]) == sizeof(u32))
+ nla_memcpy(&ccgw->dst_idx, tb[CGW_DST_IF],
+ sizeof(u32));
+
+ /* both indices set to 0 for flushing all routing entries */
+ if (!ccgw->src_idx && !ccgw->dst_idx)
+ return 0;
+
+ /* only one index set to 0 is an error */
+ if (!ccgw->src_idx || !ccgw->dst_idx)
+ return err;
+ }
+
+ /* add the checks for other gwtypes here */
+
+ return 0;
+}
+
+static int cgw_create_job(struct sk_buff *skb, struct nlmsghdr *nlh,
+ void *arg)
+{
+ struct rtcanmsg *r;
+ struct cgw_job *gwj;
+ int err = 0;
+
+ if (nlmsg_len(nlh) < sizeof(*r))
+ return -EINVAL;
+
+ r = nlmsg_data(nlh);
+ if (r->can_family != AF_CAN)
+ return -EPFNOSUPPORT;
+
+ /* so far we only support CAN -> CAN routings */
+ if (r->gwtype != CGW_TYPE_CAN_CAN)
+ return -EINVAL;
+
+ gwj = kmem_cache_alloc(cgw_cache, GFP_KERNEL);
+ if (!gwj)
+ return -ENOMEM;
+
+ gwj->handled_frames = 0;
+ gwj->dropped_frames = 0;
+ gwj->flags = r->flags;
+ gwj->gwtype = r->gwtype;
+
+ err = cgw_parse_attr(nlh, &gwj->mod, CGW_TYPE_CAN_CAN, &gwj->ccgw);
+ if (err < 0)
+ goto out;
+
+ err = -ENODEV;
+
+ /* ifindex == 0 is not allowed for job creation */
+ if (!gwj->ccgw.src_idx || !gwj->ccgw.dst_idx)
+ goto out;
+
+ gwj->src.dev = dev_get_by_index(&init_net, gwj->ccgw.src_idx);
+
+ if (!gwj->src.dev)
+ goto out;
+
+ /* check for CAN netdev not using header_ops - see gw_rcv() */
+ if (gwj->src.dev->type != ARPHRD_CAN || gwj->src.dev->header_ops)
+ goto put_src_out;
+
+ gwj->dst.dev = dev_get_by_index(&init_net, gwj->ccgw.dst_idx);
+
+ if (!gwj->dst.dev)
+ goto put_src_out;
+
+ /* check for CAN netdev not using header_ops - see gw_rcv() */
+ if (gwj->dst.dev->type != ARPHRD_CAN || gwj->dst.dev->header_ops)
+ goto put_src_dst_out;
+
+ ASSERT_RTNL();
+
+ err = cgw_register_filter(gwj);
+ if (!err)
+ hlist_add_head_rcu(&gwj->list, &cgw_list);
+
+put_src_dst_out:
+ dev_put(gwj->dst.dev);
+put_src_out:
+ dev_put(gwj->src.dev);
+out:
+ if (err)
+ kmem_cache_free(cgw_cache, gwj);
+
+ return err;
+}
+
+static void cgw_remove_all_jobs(void)
+{
+ struct cgw_job *gwj = NULL;
+ struct hlist_node *n, *nx;
+
+ ASSERT_RTNL();
+
+ hlist_for_each_entry_safe(gwj, n, nx, &cgw_list, list) {
+ hlist_del(&gwj->list);
+ cgw_unregister_filter(gwj);
+ kfree(gwj);
+ }
+}
+
+static int cgw_remove_job(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
+{
+ struct cgw_job *gwj = NULL;
+ struct hlist_node *n, *nx;
+ struct rtcanmsg *r;
+ struct cf_mod mod;
+ struct can_can_gw ccgw;
+ int err = 0;
+
+ if (nlmsg_len(nlh) < sizeof(*r))
+ return -EINVAL;
+
+ r = nlmsg_data(nlh);
+ if (r->can_family != AF_CAN)
+ return -EPFNOSUPPORT;
+
+ /* so far we only support CAN -> CAN routings */
+ if (r->gwtype != CGW_TYPE_CAN_CAN)
+ return -EINVAL;
+
+ err = cgw_parse_attr(nlh, &mod, CGW_TYPE_CAN_CAN, &ccgw);
+ if (err < 0)
+ return err;
+
+ /* two interface indices both set to 0 => remove all entries */
+ if (!ccgw.src_idx && !ccgw.dst_idx) {
+ cgw_remove_all_jobs();
+ return 0;
+ }
+
+ err = -EINVAL;
+
+ ASSERT_RTNL();
+
+ /* remove only the first matching entry */
+ hlist_for_each_entry_safe(gwj, n, nx, &cgw_list, list) {
+
+ if (gwj->flags != r->flags)
+ continue;
+
+ if (memcmp(&gwj->mod, &mod, sizeof(mod)))
+ continue;
+
+ /* if (r->gwtype == CGW_TYPE_CAN_CAN) - is made sure here */
+ if (memcmp(&gwj->ccgw, &ccgw, sizeof(ccgw)))
+ continue;
+
+ hlist_del(&gwj->list);
+ cgw_unregister_filter(gwj);
+ kfree(gwj);
+ err = 0;
+ break;
+ }
+
+ return err;
+}
+
+static __init int cgw_module_init(void)
+{
+ printk(banner);
+
+ cgw_cache = kmem_cache_create("can_gw", sizeof(struct cgw_job),
+ 0, 0, NULL);
+
+ if (!cgw_cache)
+ return -ENOMEM;
+
+ /* set notifier */
+ notifier.notifier_call = cgw_notifier;
+ register_netdevice_notifier(¬ifier);
+
+ if (__rtnl_register(PF_CAN, RTM_GETROUTE, NULL, cgw_dump_jobs, NULL)) {
+ unregister_netdevice_notifier(¬ifier);
+ kmem_cache_destroy(cgw_cache);
+ return -ENOBUFS;
+ }
+
+ /* Only the first call to __rtnl_register can fail */
+ __rtnl_register(PF_CAN, RTM_NEWROUTE, cgw_create_job, NULL, NULL);
+ __rtnl_register(PF_CAN, RTM_DELROUTE, cgw_remove_job, NULL, NULL);
+
+ return 0;
+}
+
+static __exit void cgw_module_exit(void)
+{
+ rtnl_unregister_all(PF_CAN);
+
+ unregister_netdevice_notifier(¬ifier);
+
+ rtnl_lock();
+ cgw_remove_all_jobs();
+ rtnl_unlock();
+
+ rcu_barrier(); /* Wait for completion of call_rcu()'s */
+
+ kmem_cache_destroy(cgw_cache);
+}
+
+module_init(cgw_module_init);
+module_exit(cgw_module_exit);
diff -u -r -N a/net/can/Kconfig b/net/can/Kconfig
--- a/net/can/Kconfig 2011-08-31 21:10:58.399595821 +0200
+++ b/net/can/Kconfig 2011-08-31 21:09:29.939596430 +0200
@@ -40,5 +40,16 @@
CAN messages are used on the bus (e.g. in automotive environments).
To use the Broadcast Manager, use AF_CAN with protocol CAN_BCM.
+config CAN_GW
+ tristate "CAN Gateway/Router (with netlink configuration)"
+ depends on CAN
+ default N
+ ---help---
+ The CAN Gateway/Router is used to route (and modify) CAN frames.
+ It is based on the PF_CAN core infrastructure for msg filtering and
+ msg sending and can optionally modify routed CAN frames on the fly.
+ CAN frames can be routed between CAN network interfaces (one hop).
+ They can be modified with AND/OR/XOR/SET operations as configured
+ by the netlink configuration interface known e.g. from iptables.
source "drivers/net/can/Kconfig"
diff -u -r -N a/net/can/Makefile b/net/can/Makefile
--- a/net/can/Makefile 2011-08-31 21:10:53.355595713 +0200
+++ b/net/can/Makefile 2011-08-31 21:09:34.483599007 +0200
@@ -10,3 +10,6 @@
obj-$(CONFIG_CAN_BCM) += can-bcm.o
can-bcm-y := bcm.o
+
+obj-$(CONFIG_CAN_GW) += can-gw.o
+can-gw-y := gw.o
^ permalink raw reply
* Re: [PATCH] net: Initialize entire flowi struct
From: Ward, David - 0663 - MITLL @ 2011-09-01 13:34 UTC (permalink / raw)
To: Julian Anastasov; +Cc: David Miller, netdev@vger.kernel.org
In-Reply-To: <alpine.LFD.2.00.1108312321400.1826@ja.ssi.bg>
[-- Attachment #1: Type: text/plain, Size: 2527 bytes --]
Hi Julian,
On 08/31/2011 04:51 PM, Julian Anastasov wrote:
> On Wed, 31 Aug 2011, David Ward wrote
>> The entire flowi struct needs to be initialized by afinfo->decode_session,
>> because flow_hash_code operates over the entire struct and may otherwise
>> return different hash values for what is intended to be the same key.
> Such change will cause problems for callers that
> use flowi4 in stack. Examples:
>
> ip_route_me_harder
> icmp_route_lookup
Thanks for pointing this out.
> Not sure if adding size as parameter to flow_hash_code
> is better approach. May be flow_cache_lookup needs to
> determine size from family that can be used for flow_hash_code,
> flow_key_compare and the memcpy(&fle->key, key, sizeof(*key))
> after fle = kmem_cache_alloc(flow_cachep, GFP_ATOMIC).
Makes sense to me. However should we just replace flow_key_compare with
memcmp then, since the assumptions about constant size and alignment
will no longer apply? Or should there be a separate flow_key_compare
function for each family, and have all of the flowi* structures become
__attribute__((__aligned__(BITS_PER_LONG/8))) ?
David
> The question is how to get size by family.
>
>> Signed-off-by: David Ward<david.ward@ll.mit.edu>
>> ---
>> net/ipv4/xfrm4_policy.c | 2 +-
>> net/ipv6/xfrm6_policy.c | 2 +-
>> 2 files changed, 2 insertions(+), 2 deletions(-)
>>
>> diff --git a/net/ipv4/xfrm4_policy.c b/net/ipv4/xfrm4_policy.c
>> index fc5368a..afce24d 100644
>> --- a/net/ipv4/xfrm4_policy.c
>> +++ b/net/ipv4/xfrm4_policy.c
>> @@ -114,7 +114,7 @@ _decode_session4(struct sk_buff *skb, struct flowi *fl, int reverse)
>> u8 *xprth = skb_network_header(skb) + iph->ihl * 4;
>> struct flowi4 *fl4 =&fl->u.ip4;
>>
>> - memset(fl4, 0, sizeof(struct flowi4));
>> + memset(fl, 0, sizeof(struct flowi));
>> fl4->flowi4_mark = skb->mark;
>>
>> if (!ip_is_fragment(iph)) {
>> diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c
>> index d879f7e..9088d38 100644
>> --- a/net/ipv6/xfrm6_policy.c
>> +++ b/net/ipv6/xfrm6_policy.c
>> @@ -129,7 +129,7 @@ _decode_session6(struct sk_buff *skb, struct flowi *fl, int reverse)
>> const unsigned char *nh = skb_network_header(skb);
>> u8 nexthdr = nh[IP6CB(skb)->nhoff];
>>
>> - memset(fl6, 0, sizeof(struct flowi6));
>> + memset(fl, 0, sizeof(struct flowi));
>> fl6->flowi6_mark = skb->mark;
>>
>> ipv6_addr_copy(&fl6->daddr, reverse ?&hdr->saddr :&hdr->daddr);
>> --
>> 1.7.4.1
[-- Attachment #2: S/MIME Cryptographic Signature --]
[-- Type: application/pkcs7-signature, Size: 4184 bytes --]
^ permalink raw reply
* Re: BQL crap and wireless
From: John W. Linville @ 2011-09-01 14:13 UTC (permalink / raw)
To: Luis R. Rodriguez
Cc: Jim Gettys, Andrew McGregor, Adrian Chadd, Tom Herbert, Dave Taht,
linux-wireless, Matt Smith, Kevin Hayes, Derek Smithies,
netdev-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <CAB=NE6Wj4BxSjZmTOg9EFMcJ+H0RBZE4q8+6DB3x8qP=r42yNQ-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
On Wed, Aug 31, 2011 at 01:50:48PM -0700, Luis R. Rodriguez wrote:
> On Wed, Aug 31, 2011 at 6:28 AM, Jim Gettys <jg-CC+yJ3UmIYqDUpFQwHEjaQ@public.gmane.org> wrote:
> > such as wireless, or even possibly modern broadband with
> > PowerBoost, classic RED or similar algorithms that do not take the
> > buffer drain rate cannot possibly hack it properly.
>
> Understood, just curious if anyone has tried a Minstrel approach.
FWIW, eBDP and the related algorithms from Tianji Li's paper are
philosophically similar to minstrel. They depend on measuring recent
conditions and modifying the current queue length accordingly.
http://www.hamilton.ie/tianji_li/buffersizing.pdf
The hack I added in debloat-testing is based on my understanding
of eBDP. It timestamps the SKBs when they are handed to the driver
for Tx and then checks the timestamp when the SKB is orphaned. It is
a bit crude and is an abuse of the skb_orphan API. Also while it
accounts for the 802.11e queues separately, it doesn't account for
802.11n aggregation. Still, it seems to improve latency w/o hugely
impacting throughput in at least some environments -- YMMV!
John
--
John W. Linville Someday the world will need a hero, and you
linville-2XuSBdqkA4R54TAoqtyWWQ@public.gmane.org might be all we have. Be ready.
--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" 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
* [PATCH v3 -next] 6LoWPAN: fix skb_copy call
From: Alexander Smirnov @ 2011-09-01 13:55 UTC (permalink / raw)
To: davem-fT/PcQaiUtIeIZ0/mPfg9Q
Cc: eric.dumazet-Re5JQEeQqe8AvxtiuMwx3w,
netdev-u79uwXL29TY76Z2rM5mHXA,
kernel-janitors-u79uwXL29TY76Z2rM5mHXA,
linux-zigbee-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f
In-Reply-To: <1314879675-31989-1-git-send-email-alex.bluesman.smirnov-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
This patch fixes 2 issues in lowpan_skb_deliver function:
1. Check for return status of skb_copy call;
2. Use skb_copy with proper GFP flag, drop check for non-interrupt
context.
Signed-off-by: Alexander Smirnov <alex.bluesman.smirnov-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
---
net/ieee802154/6lowpan.c | 17 +++++++++--------
1 files changed, 9 insertions(+), 8 deletions(-)
diff --git a/net/ieee802154/6lowpan.c b/net/ieee802154/6lowpan.c
index cf304cc..deb2adf 100644
--- a/net/ieee802154/6lowpan.c
+++ b/net/ieee802154/6lowpan.c
@@ -479,10 +479,10 @@ static int lowpan_skb_deliver(struct sk_buff *skb, struct ipv6hdr *hdr)
int stat = NET_RX_SUCCESS;
new = skb_copy_expand(skb, sizeof(struct ipv6hdr), skb_tailroom(skb),
- GFP_KERNEL);
+ GFP_ATOMIC);
kfree_skb(skb);
- if (NULL == new)
+ if (!new)
return -ENOMEM;
skb_push(new, sizeof(struct ipv6hdr));
@@ -495,13 +495,14 @@ static int lowpan_skb_deliver(struct sk_buff *skb, struct ipv6hdr *hdr)
rcu_read_lock();
list_for_each_entry_rcu(entry, &lowpan_devices, list)
if (lowpan_dev_info(entry->ldev)->real_dev == new->dev) {
- skb = skb_copy(new, GFP_KERNEL);
- skb->dev = entry->ldev;
+ skb = skb_copy(new, GFP_ATOMIC);
+ if (!skb) {
+ stat = -ENOMEM;
+ break;
+ }
- if (in_interrupt())
- stat = netif_rx(skb);
- else
- stat = netif_rx_ni(skb);
+ skb->dev = entry->ldev;
+ stat = netif_rx(skb);
}
rcu_read_unlock();
--
1.7.2.5
------------------------------------------------------------------------------
Special Offer -- Download ArcSight Logger for FREE!
Finally, a world-class log management solution at an even better
price-free! And you'll get a free "Love Thy Logs" t-shirt when you
download Logger. Secure your free ArcSight Logger TODAY!
http://p.sf.net/sfu/arcsisghtdev2dev
^ permalink raw reply related
* [patch net-next-2.6] br: remove redundant check and init
From: Jiri Pirko @ 2011-09-01 13:29 UTC (permalink / raw)
To: netdev; +Cc: davem, eric.dumazet, shemminger, bridge
Since these checks and initialization are done in
dev_ethtool_get_settings called later on, remove this redundancy.
Signed-off-by: Jiri Pirko <jpirko@redhat.com>
---
net/bridge/br_if.c | 24 +++++++++++-------------
1 files changed, 11 insertions(+), 13 deletions(-)
diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c
index 2cdf007..b365bba 100644
--- a/net/bridge/br_if.c
+++ b/net/bridge/br_if.c
@@ -33,20 +33,18 @@
*/
static int port_cost(struct net_device *dev)
{
- if (dev->ethtool_ops && dev->ethtool_ops->get_settings) {
- struct ethtool_cmd ecmd = { .cmd = ETHTOOL_GSET, };
-
- if (!dev_ethtool_get_settings(dev, &ecmd)) {
- switch (ethtool_cmd_speed(&ecmd)) {
- case SPEED_10000:
- return 2;
- case SPEED_1000:
- return 4;
- case SPEED_100:
- return 19;
- case SPEED_10:
- return 100;
- }
+ struct ethtool_cmd ecmd;
+
+ if (!dev_ethtool_get_settings(dev, &ecmd)) {
+ switch (ethtool_cmd_speed(&ecmd)) {
+ case SPEED_10000:
+ return 2;
+ case SPEED_1000:
+ return 4;
+ case SPEED_100:
+ return 19;
+ case SPEED_10:
+ return 100;
}
}
--
1.7.6
^ permalink raw reply related
* Re: slow performance on disk/network i/o full speed after drop_caches
From: Mel Gorman @ 2011-09-01 12:57 UTC (permalink / raw)
To: Wu Fengguang
Cc: Stefan Priebe - Profihost AG, Zhu Yanhai, Pekka Enberg, LKML,
linux-mm@kvack.org, Andrew Morton, Jens Axboe, Linux Netdev List,
KOSAKI Motohiro
In-Reply-To: <20110901041458.GA30123@localhost>
On Thu, Sep 01, 2011 at 12:14:58PM +0800, Wu Fengguang wrote:
> Hi Stefan,
>
> On Wed, Aug 31, 2011 at 03:11:02PM +0800, Stefan Priebe - Profihost AG wrote:
> > Hi Fengguang,
> > Hi Yanhai,
> >
> > > you're abssolutely corect zone_reclaim_mode is on - but why?
> > > There must be some linux software which switches it on.
> > >
> > > ~# grep 'zone_reclaim_mode' /etc/sysctl.* -r -i
> > > ~#
> > >
> > > also
> > > ~# grep 'zone_reclaim_mode' /etc/sysctl.* -r -i
> > > ~#
> > >
> > > tells us nothing.
> > >
> > > I've then read this:
> > >
> > > "zone_reclaim_mode is set during bootup to 1 if it is determined that
> > > pages from remote zones will cause a measurable performance reduction.
> > > The page allocator will then reclaim easily reusable pages (those page
> > > cache pages that are currently not used) before allocating off node pages."
> > >
> > > Why does the kernel do that here in our case on these machines.
> >
> > Can nobody help why the kernel in this case set it to 1?
>
> It's determined by RECLAIM_DISTANCE.
>
> build_zonelists():
>
> /*
> * If another node is sufficiently far away then it is better
> * to reclaim pages in a zone before going off node.
> */
> if (distance > RECLAIM_DISTANCE)
> zone_reclaim_mode = 1;
>
> Since Linux v3.0 RECLAIM_DISTANCE is increased from 20 to 30 by this commit.
> It may well help your case, too.
>
Even with that, it's known that zone_reclaim() can be a disaster when
it runs into problems. This should be fixed in 3.1 by the following
commits;
[cd38b115 mm: page allocator: initialise ZLC for first zone eligible for zone_reclaim]
[76d3fbf8 mm: page allocator: reconsider zones for allocation after direct reclaim]
The description in cd38b115 has the interesting details.
--
Mel Gorman
SUSE Labs
^ permalink raw reply
* [PATCH v2 -next] 6LoWPAN: fix skb_copy call
From: Alexander Smirnov @ 2011-09-01 12:54 UTC (permalink / raw)
To: davem-fT/PcQaiUtIeIZ0/mPfg9Q
Cc: eric.dumazet-Re5JQEeQqe8AvxtiuMwx3w,
netdev-u79uwXL29TY76Z2rM5mHXA,
kernel-janitors-u79uwXL29TY76Z2rM5mHXA,
linux-zigbee-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f
In-Reply-To: <1314879675-31989-1-git-send-email-alex.bluesman.smirnov-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
This patch fixes 2 issues in lowpan_skb_deliver function:
1. Check for return status of skb_copy call;
2. Use skb_copy with proper GFP flag depending on context.
Signed-off-by: Alexander Smirnov <alex.bluesman.smirnov-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
---
net/ieee802154/6lowpan.c | 18 +++++++++++++++---
1 files changed, 15 insertions(+), 3 deletions(-)
diff --git a/net/ieee802154/6lowpan.c b/net/ieee802154/6lowpan.c
index cf304cc..16100be 100644
--- a/net/ieee802154/6lowpan.c
+++ b/net/ieee802154/6lowpan.c
@@ -477,9 +477,15 @@ static int lowpan_skb_deliver(struct sk_buff *skb, struct ipv6hdr *hdr)
struct sk_buff *new;
struct lowpan_dev_record *entry;
int stat = NET_RX_SUCCESS;
+ gfp_t mask;
- new = skb_copy_expand(skb, sizeof(struct ipv6hdr), skb_tailroom(skb),
- GFP_KERNEL);
+ if (in_interrupt())
+ mask = GFP_ATOMIC;
+ else
+ mask = GFP_KERNEL;
+
+ new = skb_copy_expand(skb, sizeof(struct ipv6hdr),
+ skb_tailroom(skb), mask);
kfree_skb(skb);
if (NULL == new)
@@ -495,7 +501,13 @@ static int lowpan_skb_deliver(struct sk_buff *skb, struct ipv6hdr *hdr)
rcu_read_lock();
list_for_each_entry_rcu(entry, &lowpan_devices, list)
if (lowpan_dev_info(entry->ldev)->real_dev == new->dev) {
- skb = skb_copy(new, GFP_KERNEL);
+ skb = skb_copy(new, mask);
+
+ if (NULL == skb) {
+ stat = -ENOMEM;
+ break;
+ }
+
skb->dev = entry->ldev;
if (in_interrupt())
--
1.7.2.5
------------------------------------------------------------------------------
Special Offer -- Download ArcSight Logger for FREE!
Finally, a world-class log management solution at an even better
price-free! And you'll get a free "Love Thy Logs" t-shirt when you
download Logger. Secure your free ArcSight Logger TODAY!
http://p.sf.net/sfu/arcsisghtdev2dev
^ permalink raw reply related
* e1000e - BUG: sleeping function called from invalid context
From: Francois Romieu @ 2011-09-01 12:20 UTC (permalink / raw)
To: netdev
Cc: Jeff Kirsher, Jesse Brandeburg, Bruce Allan, Carolyn Wyborny,
Don Skidmore, Greg Rose, PJ Waskiewicz, Alex Duyck, John Ronciak
I got this one while running plain 'ip link show' with linus's post
3.1.0-rc3 (CONFIG_DEBUG_ATOMIC_SLEEP=y, 82544 LOM with Intel DP55KG
motherboard):
[18628.524980] BUG: sleeping function called from invalid context at /home/romieu/git/linux-2.6-ref/kernel/mutex.c:85
[18628.524987] in_atomic(): 1, irqs_disabled(): 0, pid: 1204, name: irqbalance
[18628.524993] Pid: 1204, comm: irqbalance Not tainted 3.1.0-rc3+ #4
[18628.524996] Call Trace:
[18628.525007] [<ffffffff810421a1>] __might_sleep+0xeb/0xf0
[18628.525032] [<ffffffff814a9dd8>] mutex_lock+0x24/0x4a
[18628.525040] [<ffffffff8124dc82>] ? vsnprintf+0x83/0x44c
[18628.525057] [<ffffffffa01e1697>] e1000_acquire_swflag_ich8lan+0x27/0x138 [e1000e]
[18628.525078] [<ffffffffa01f0bae>] e1000e_update_stats+0x158/0x750 [e1000e]
[18628.525098] [<ffffffffa01f11e8>] e1000e_get_stats64+0x42/0x143 [e1000e]
[18628.525105] [<ffffffff813f4986>] dev_get_stats+0x38/0x7a
[18628.525110] [<ffffffff813f49f0>] dev_seq_printf_stats+0x28/0xf8
[18628.525118] [<ffffffff813f33e2>] ? dev_seq_start+0x1f/0x70
[18628.525123] [<ffffffff813f4ae2>] dev_seq_show+0x22/0x26
The path looks the same in linus's (9e79e3e9dd9672b37ac9412e9a926714306551fe)
and in davem's net-next (3857e3ee2209b7289c434103e366f765ec82a22d) branches:
e1000e_get_stats64
-> spin_lock(&adapter->stats64_lock);
e1000e_update_stats
-> e1000e_update_phy_stats
-> e1000_acquire_swflag_ich8lan (through hw->phy.ops.acquire)
-> mutex_lock(&swflag_mutex);
Can you fix it ?
(either turn stats64_lock into a mutex or remove it - and swflag_mutex as
well ? - and use the rtnl sem in your work tasks from a quick glance at
the code)
Thanks.
--
Ueimor
^ permalink raw reply
* Re: [PATCH v2 -next] 6LoWPAN: fix skb_copy call
From: Alexander Smirnov @ 2011-09-01 12:34 UTC (permalink / raw)
To: Eric Dumazet
Cc: davem, dbaryshkov, slapin, linux-zigbee-devel, netdev,
kernel-janitors
In-Reply-To: <1314878443.2823.6.camel@edumazet-HP-Compaq-6005-Pro-SFF-PC>
Hi Eric,
hmm, I think you are right.
First 6LoWPAN implementation was developed as a part of MAC layer and
code was based on this layer approach. But now 6lowpan is
MAC-independent, it's just a netif_rx hook and looks like I missed
this moment during migration.
sorry for confusion.
With best regards,
Alexander
2011/9/1 Eric Dumazet <eric.dumazet@gmail.com>:
> Le jeudi 01 septembre 2011 à 16:54 +0400, Alexander Smirnov a écrit :
>> This patch fixes 2 issues in lowpan_skb_deliver function:
>> 1. Check for return status of skb_copy call;
>> 2. Use skb_copy with proper GFP flag depending on context.
>>
>> Signed-off-by: Alexander Smirnov <alex.bluesman.smirnov@gmail.com>
>> ---
>> net/ieee802154/6lowpan.c | 18 +++++++++++++++---
>> 1 files changed, 15 insertions(+), 3 deletions(-)
>>
>> diff --git a/net/ieee802154/6lowpan.c b/net/ieee802154/6lowpan.c
>> index cf304cc..16100be 100644
>> --- a/net/ieee802154/6lowpan.c
>> +++ b/net/ieee802154/6lowpan.c
>> @@ -477,9 +477,15 @@ static int lowpan_skb_deliver(struct sk_buff *skb, struct ipv6hdr *hdr)
>> struct sk_buff *new;
>> struct lowpan_dev_record *entry;
>> int stat = NET_RX_SUCCESS;
>> + gfp_t mask;
>>
>> - new = skb_copy_expand(skb, sizeof(struct ipv6hdr), skb_tailroom(skb),
>> - GFP_KERNEL);
>> + if (in_interrupt())
>> + mask = GFP_ATOMIC;
>> + else
>> + mask = GFP_KERNEL;
>
> I am not sure to understand if lowpan_skb_deliver() can be called in
> pure process context. I feel we are in softirq handler or we have
> disabled BH, so GFP_ATOMIC is the only choice.
>
> If you are unsure, you could use following helper :
>
> mask = gfp_any();
>
>> +
>> + new = skb_copy_expand(skb, sizeof(struct ipv6hdr),
>> + skb_tailroom(skb), mask);
>> kfree_skb(skb);
>>
>
>
^ permalink raw reply
* Re: [PATCH 2/2] Add a netlink attribute INET_DIAG_SECCTX
From: Paul Moore @ 2011-09-01 12:28 UTC (permalink / raw)
To: Rongqing Li; +Cc: netdev, selinux, linux-security-module
In-Reply-To: <4E5F5153.6070708@windriver.com>
On Thursday, September 01, 2011 05:33:07 PM Rongqing Li wrote:
> On 09/01/2011 05:18 AM, Paul Moore wrote:
> > On Wednesday, August 31, 2011 04:36:17 PM rongqing.li@windriver.com wrote:
> >> From: Roy.Li<rongqing.li@windriver.com>
> >>
> >> Add a new netlink attribute INET_DIAG_SECCTX to dump the security
> >> context of TCP sockets.
> >
> > You'll have to forgive me, I'm not familiar with the netlink code used
> > by
> > netstat and friends, but is there anyway to report back the security
> > context of UDP sockets? Or does the code below handle that already?
> >
> > In general, AF_INET and AF_INET6 sockets, regardless of any upper level
> > protocols, have security contexts associated with them and it would be
> > nice to see them in netstat.
>
> Yes, this is real concern, If the dumping tcp security context can be
> accepted by netdev, I am planning to implement it for ipv4 udp socket, unix
> socket. then ipv6..
Great, I'm glad to hear you're planning on implementing this for more than
just TCP.
I understand your desire to have the basic idea accepted with only TCP
implemented - and that is fine with me - but I would like to see support for
all of the protocols merged at the same time. In other words, seeking the
basic ACKs for TCP from the davem, et al is okay but I'd like to defer merging
TCP support until you have everything implemented and ready to be merged.
--
paul moore
www.paul-moore.com
^ permalink raw reply
* [PATCH 1/1 -next] 6LoWPAN: fix skb_copy call
From: Alexander Smirnov @ 2011-09-01 12:21 UTC (permalink / raw)
To: davem-fT/PcQaiUtIeIZ0/mPfg9Q
Cc: eric.dumazet-Re5JQEeQqe8AvxtiuMwx3w,
netdev-u79uwXL29TY76Z2rM5mHXA,
kernel-janitors-u79uwXL29TY76Z2rM5mHXA,
linux-zigbee-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f
This patch fixes 2 issues in lowpan_skb_deliver function:
1. Check for return status of skb_copy call;
2. Use skb_copy with proper GFP flag depending on context.
Signed-off-by: Alexander Smirnov <alex.bluesman.smirnov-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
---
net/ieee802154/6lowpan.c | 18 +++++++++++++++---
1 files changed, 15 insertions(+), 3 deletions(-)
diff --git a/net/ieee802154/6lowpan.c b/net/ieee802154/6lowpan.c
index cf304cc..cac1361 100644
--- a/net/ieee802154/6lowpan.c
+++ b/net/ieee802154/6lowpan.c
@@ -477,9 +477,15 @@ static int lowpan_skb_deliver(struct sk_buff *skb, struct ipv6hdr *hdr)
struct sk_buff *new;
struct lowpan_dev_record *entry;
int stat = NET_RX_SUCCESS;
+ gfp_t mask;
- new = skb_copy_expand(skb, sizeof(struct ipv6hdr), skb_tailroom(skb),
- GFP_KERNEL);
+ if (in_interrupt())
+ mask = GFP_ATOMIC;
+ else
+ mask = GFP_KERNEL;
+
+ new = skb_copy_expand(skb, sizeof(struct ipv6hdr),
+ skb_tailroom(skb), mask);
kfree_skb(skb);
if (NULL == new)
@@ -495,7 +501,13 @@ static int lowpan_skb_deliver(struct sk_buff *skb, struct ipv6hdr *hdr)
rcu_read_lock();
list_for_each_entry_rcu(entry, &lowpan_devices, list)
if (lowpan_dev_info(entry->ldev)->real_dev == new->dev) {
- skb = skb_copy(new, GFP_KERNEL);
+ skb = skb_copy(new, mask);
+
+ if (NULL == skb) {
+ kfree_skb(new);
+ return -ENOMEM;
+ }
+
skb->dev = entry->ldev;
if (in_interrupt())
--
1.7.2.5
------------------------------------------------------------------------------
Special Offer -- Download ArcSight Logger for FREE!
Finally, a world-class log management solution at an even better
price-free! And you'll get a free "Love Thy Logs" t-shirt when you
download Logger. Secure your free ArcSight Logger TODAY!
http://p.sf.net/sfu/arcsisghtdev2dev
^ permalink raw reply related
* Re: [PATCH v2 -next] 6LoWPAN: fix skb_copy call
From: Daniel Baluta @ 2011-09-01 12:10 UTC (permalink / raw)
To: Alexander Smirnov
Cc: davem, dbaryshkov, slapin, linux-zigbee-devel, netdev,
eric.dumazet, kernel-janitors
In-Reply-To: <1314881653-1104-1-git-send-email-alex.bluesman.smirnov@gmail.com>
> + if (NULL == skb) {
> + stat = -ENOMEM;
> + break;
> + }
This can hurt our eyes :). I think the common convention
is to use: "if (skb == NULL) " or simply "if (!skb) "
thanks,
Daniel.
^ permalink raw reply
* Re: [PATCH v2 -next] 6LoWPAN: fix skb_copy call
From: Eric Dumazet @ 2011-09-01 12:00 UTC (permalink / raw)
To: Alexander Smirnov
Cc: davem, dbaryshkov, slapin, linux-zigbee-devel, netdev,
kernel-janitors
In-Reply-To: <1314881653-1104-1-git-send-email-alex.bluesman.smirnov@gmail.com>
Le jeudi 01 septembre 2011 à 16:54 +0400, Alexander Smirnov a écrit :
> This patch fixes 2 issues in lowpan_skb_deliver function:
> 1. Check for return status of skb_copy call;
> 2. Use skb_copy with proper GFP flag depending on context.
>
> Signed-off-by: Alexander Smirnov <alex.bluesman.smirnov@gmail.com>
> ---
> net/ieee802154/6lowpan.c | 18 +++++++++++++++---
> 1 files changed, 15 insertions(+), 3 deletions(-)
>
> diff --git a/net/ieee802154/6lowpan.c b/net/ieee802154/6lowpan.c
> index cf304cc..16100be 100644
> --- a/net/ieee802154/6lowpan.c
> +++ b/net/ieee802154/6lowpan.c
> @@ -477,9 +477,15 @@ static int lowpan_skb_deliver(struct sk_buff *skb, struct ipv6hdr *hdr)
> struct sk_buff *new;
> struct lowpan_dev_record *entry;
> int stat = NET_RX_SUCCESS;
> + gfp_t mask;
>
> - new = skb_copy_expand(skb, sizeof(struct ipv6hdr), skb_tailroom(skb),
> - GFP_KERNEL);
> + if (in_interrupt())
> + mask = GFP_ATOMIC;
> + else
> + mask = GFP_KERNEL;
I am not sure to understand if lowpan_skb_deliver() can be called in
pure process context. I feel we are in softirq handler or we have
disabled BH, so GFP_ATOMIC is the only choice.
If you are unsure, you could use following helper :
mask = gfp_any();
> +
> + new = skb_copy_expand(skb, sizeof(struct ipv6hdr),
> + skb_tailroom(skb), mask);
> kfree_skb(skb);
>
^ permalink raw reply
* Re: [PATCH net-next] net: linkwatch: allow vlans to get carrier changes faster
From: HAYASAKA Mitsuo @ 2011-09-01 11:53 UTC (permalink / raw)
To: Eric Dumazet
Cc: Herbert Xu, Stephen Hemminger, Patrick McHardy, David S. Miller,
MichałMirosław, Tom Herbert, Jesse Gross, netdev,
linux-kernel, yrl.pp-manager.tt
In-Reply-To: <1314783118.2801.13.camel@edumazet-HP-Compaq-6005-Pro-SFF-PC>
Hi Eric,
I checked this patch solves the time-lag of IFF_RUNNING flag consistency
between vlan and real devices.
Cheers.
Tested-by: Mitsuo Hayasaka <mitsuo.hayasaka.hu@hitachi.com>
(2011/08/31 18:31), Eric Dumazet wrote:
> There is a time-lag of IFF_RUNNING flag consistency between vlan and
> real devices when the real devices are in problem such as link or cable
> broken.
>
> This leads to a degradation of Availability such as a delay of failover
> in HA systems using vlan since the detection of the problem at real
> device is delayed.
>
> We can avoid the linkwatch delay (~1 sec) for devices linked to another
> ones, since delay is already done for the realdev.
>
> Based on a previous patch from Mitsuo Hayasaka
>
> Reported-by: Mitsuo Hayasaka <mitsuo.hayasaka.hu@hitachi.com>
> Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
> Cc: Herbert Xu <herbert@gondor.apana.org.au>
> Cc: Patrick McHardy <kaber@trash.net>
> Cc: "Michał Mirosław" <mirq-linux@rere.qmqm.pl>
> Cc: Tom Herbert <therbert@google.com>
> Cc: Stephen Hemminger <shemminger@vyatta.com>
> Cc: Jesse Gross <jesse@nicira.com>
> ---
> net/core/link_watch.c | 9 +++++++--
> 1 file changed, 7 insertions(+), 2 deletions(-)
>
> diff --git a/net/core/link_watch.c b/net/core/link_watch.c
> index 357bd4e..c3519c6 100644
> --- a/net/core/link_watch.c
> +++ b/net/core/link_watch.c
> @@ -78,8 +78,13 @@ static void rfc2863_policy(struct net_device *dev)
>
> static bool linkwatch_urgent_event(struct net_device *dev)
> {
> - return netif_running(dev) && netif_carrier_ok(dev) &&
> - qdisc_tx_changing(dev);
> + if (!netif_running(dev))
> + return false;
> +
> + if (dev->ifindex != dev->iflink)
> + return true;
> +
> + return netif_carrier_ok(dev) && qdisc_tx_changing(dev);
> }
>
>
>
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at http://www.tux.org/lkml/
>
^ permalink raw reply
* Re: [PATCH 1/1 -next] 6LoWPAN: fix skb_copy call
From: Eric Dumazet @ 2011-09-01 11:30 UTC (permalink / raw)
To: Alexander Smirnov
Cc: davem, dbaryshkov, slapin, linux-zigbee-devel, netdev,
kernel-janitors
In-Reply-To: <1314879675-31989-1-git-send-email-alex.bluesman.smirnov@gmail.com>
Le jeudi 01 septembre 2011 à 16:21 +0400, Alexander Smirnov a écrit :
> This patch fixes 2 issues in lowpan_skb_deliver function:
> 1. Check for return status of skb_copy call;
> 2. Use skb_copy with proper GFP flag depending on context.
>
Reported-by: Eric Dumazet <eric.dumazet@gmail.com>
patch adds a new bug, see below
> Signed-off-by: Alexander Smirnov <alex.bluesman.smirnov@gmail.com>
> ---
> net/ieee802154/6lowpan.c | 18 +++++++++++++++---
> 1 files changed, 15 insertions(+), 3 deletions(-)
>
> diff --git a/net/ieee802154/6lowpan.c b/net/ieee802154/6lowpan.c
> index cf304cc..cac1361 100644
> --- a/net/ieee802154/6lowpan.c
> +++ b/net/ieee802154/6lowpan.c
> @@ -477,9 +477,15 @@ static int lowpan_skb_deliver(struct sk_buff *skb, struct ipv6hdr *hdr)
> struct sk_buff *new;
> struct lowpan_dev_record *entry;
> int stat = NET_RX_SUCCESS;
> + gfp_t mask;
>
> - new = skb_copy_expand(skb, sizeof(struct ipv6hdr), skb_tailroom(skb),
> - GFP_KERNEL);
> + if (in_interrupt())
> + mask = GFP_ATOMIC;
> + else
> + mask = GFP_KERNEL;
> +
> + new = skb_copy_expand(skb, sizeof(struct ipv6hdr),
> + skb_tailroom(skb), mask);
> kfree_skb(skb);
>
> if (NULL == new)
> @@ -495,7 +501,13 @@ static int lowpan_skb_deliver(struct sk_buff *skb, struct ipv6hdr *hdr)
> rcu_read_lock();
> list_for_each_entry_rcu(entry, &lowpan_devices, list)
> if (lowpan_dev_info(entry->ldev)->real_dev == new->dev) {
> - skb = skb_copy(new, GFP_KERNEL);
> + skb = skb_copy(new, mask);
> +
> + if (NULL == skb) {
> + kfree_skb(new);
rcu_read_unlock() missing.
just do :
stat = -ENOMEM;
break; (to exit from list_for_each_entry_rcu())
> + return -ENOMEM;
> + }
> +
> skb->dev = entry->ldev;
>
> if (in_interrupt())
^ permalink raw reply
* RE: [PATCH 1/3] bnx2x: remove TPA_ENABLE_FLAG
From: Vladislav Zolotarov @ 2011-09-01 10:52 UTC (permalink / raw)
To: Michał Mirosław
Cc: Michal Schmidt, netdev@vger.kernel.org, Dmitry Kravkov,
Eilon Greenstein
In-Reply-To: <CAHXqBFJR=5zTZeq+HnfRp2rb9yX3L=Kjwi_1AyWU2EDqZ=gCWQ@mail.gmail.com>
> If I understand correctly, bnx2x_reload_if_running() failure does not
> mean exactly that features change failed. It means that device failed
> to initialize, possibly because of other (transient?) conditions. So
> unless reverting features change and retrying the initialization is
> known to allow the device to be brought back,
In a general case u can't be sure which (if at all) features change caused
the failure. So, u should return the configuration to the last known "good" one.
> there's no difference
> whether old or new dev->features value is kept and which set is
> reported by ethtool.
Well, I disagree with u on this one - I think that if the state change operation
(of any object, in our case it's a netdev) fails, the current state should remain unchanged.
Thanks,
vlad
>
> Best Regards,
> Michał Mirosław
^ permalink raw reply
* Re: [PATCH 1/3] bnx2x: remove TPA_ENABLE_FLAG
From: Michał Mirosław @ 2011-09-01 9:37 UTC (permalink / raw)
To: Vladislav Zolotarov
Cc: Michal Schmidt, netdev@vger.kernel.org, Dmitry Kravkov,
Eilon Greenstein
In-Reply-To: <8628FE4E7912BF47A96AE7DD7BAC0AAD01067097B03C@SJEXCHCCR02.corp.ad.broadcom.com>
W dniu 1 września 2011 10:37 użytkownik Vladislav Zolotarov
<vladz@broadcom.com> napisał:
>> -----Original Message-----
>> From: netdev-owner@vger.kernel.org [mailto:netdev-
>> owner@vger.kernel.org] On Behalf Of Michal Miroslaw
>> Sent: Wednesday, August 31, 2011 9:05 PM
>> To: Vladislav Zolotarov
>> Cc: Michal Schmidt; netdev@vger.kernel.org; Dmitry Kravkov; Eilon
>> Greenstein
>> Subject: Re: [PATCH 1/3] bnx2x: remove TPA_ENABLE_FLAG
>>
>> 2011/8/31 Vladislav Zolotarov <vladz@broadcom.com>:
>> >> -----Original Message-----
>> >> From: Michal Schmidt [mailto:mschmidt@redhat.com]
>> >> Sent: Wednesday, August 31, 2011 6:59 PM
>> >> To: Vladislav Zolotarov
>> >> Cc: netdev@vger.kernel.org; Dmitry Kravkov; Eilon Greenstein;
>> >> mirqus@gmail.com
>> >> Subject: Re: [PATCH 1/3] bnx2x: remove TPA_ENABLE_FLAG
>> >>
>> >> On Wed, 31 Aug 2011 18:16:30 +0300 Vlad Zolotarov wrote:
>> >> > On Wednesday 31 August 2011 18:00:34 Michal Schmidt wrote:
>> >> > > if (bnx2x_reload) {
>> >> > > - if (bp->recovery_state == BNX2X_RECOVERY_DONE)
>> >> > > + if (bp->recovery_state == BNX2X_RECOVERY_DONE) {
>> >> > > + /*
>> >> > > + * Cheat! Normally dev->features will be
>> >> > > set after we
>> >> > > + * return, but that's too late. We need to
>> >> > > know how to
>> >> > > + * configure the NIC when reloading it, so
>> >> > > update
>> >> > > + * the features early.
>> >> > > + */
>> >> > > + dev->features = features;
>> >> > > return bnx2x_reload_if_running(dev);
>> >> >
>> >> > NACK
>> >> >
>> >> > This is bogus - what if bnx2x_reload_if_running(dev)
>> >> > (bnx2x_nic_load()) failes? The original dev->features would be
>> >> > lost...
>> >>
>> >> Well, yes, but since the NIC would be now not working, do we really
>> >> care about its features? :-)
>> >
>> > U r kidding, right? ;)
>> > We care about the consistency in the netdev features state - if we
>> failed
>> > to configure the requested feature and returned an error on e.g.
>> "ethtool -K ethX lro on"
>> > call, it's expected that a subsequent ethtool -k ethX call won't
>> report the requested
>> > feature (LRO) as set.
>>
>> If bnx2x_reload_if_running() failure means that NIC is disabled, then
>> Michal is right that there's no point in caring about dev->features,
>> sice 'load' operation (NIC configuration) needs to be done again
>> anyway.
> Michal, it's a matter of a consistent semantics/behavior of the ethtool callbacks just as I described above.
> As long as dev->features may be queried both when device is down I'm afraid I can't agree with u.
If I understand correctly, bnx2x_reload_if_running() failure does not
mean exactly that features change failed. It means that device failed
to initialize, possibly because of other (transient?) conditions. So
unless reverting features change and retrying the initialization is
known to allow the device to be brought back, there's no difference
whether old or new dev->features value is kept and which set is
reported by ethtool.
Best Regards,
Michał Mirosław
^ permalink raw reply
* Re: [PATCH 2/2] Add a netlink attribute INET_DIAG_SECCTX
From: Rongqing Li @ 2011-09-01 9:33 UTC (permalink / raw)
To: Paul Moore; +Cc: netdev, selinux, linux-security-module
In-Reply-To: <2593215.lUI7et83Qv@sifl>
On 09/01/2011 05:18 AM, Paul Moore wrote:
> On Wednesday, August 31, 2011 04:36:17 PM rongqing.li@windriver.com wrote:
>> From: Roy.Li<rongqing.li@windriver.com>
>>
>> Add a new netlink attribute INET_DIAG_SECCTX to dump the security
>> context of TCP sockets.
>
> You'll have to forgive me, I'm not familiar with the netlink code used by
> netstat and friends, but is there anyway to report back the security context
> of UDP sockets? Or does the code below handle that already?
>
> In general, AF_INET and AF_INET6 sockets, regardless of any upper level
> protocols, have security contexts associated with them and it would be nice to
> see them in netstat.
>
Yes, this is real concern, If the dumping tcp security context can be
accepted
by netdev, I am planning to implement it for ipv4 udp socket, unix socket.
then ipv6..
>> diff --git a/net/ipv4/inet_diag.c b/net/ipv4/inet_diag.c
>> index 389a2e6..1faf752 100644
>> --- a/net/ipv4/inet_diag.c
>> +++ b/net/ipv4/inet_diag.c
>> @@ -34,6 +34,8 @@
>>
>> #include<linux/inet_diag.h>
>>
>> +#define MAX_SECCTX_LEN 128
>
> I'll echo Stephen's concerns that this is too small. A MCS/MLS system with a
> moderate number of categories could bump into this limit without too much
> difficulty.
>
I will reconsider this as Stephen's suggestion, just size the buffer
appropriately
for the actual secctx length, so that, your next question will be fixed
since we
have enough memory to place the security context.
>> struct inet_diag_entry {
>> @@ -108,6 +110,25 @@ static int inet_csk_diag_fill(struct sock *sk,
>> icsk->icsk_ca_ops->name);
>> }
>>
>> + if (ext& (1<< (INET_DIAG_SECCTX - 1))) {
>> + u32 ctxlen = 0;
>> + void *secctx;
>> + int error;
>> +
>> + error = security_sk_getsecctx(sk,&secctx,&ctxlen);
>> +
>> + if (!error&& ctxlen) {
>> + if (ctxlen< MAX_SECCTX_LEN) {
>> + strcpy(INET_DIAG_PUT(skb, INET_DIAG_SECCTX,
>> + ctxlen + 1), secctx);
>> + } else {
>> + strcpy(INET_DIAG_PUT(skb, INET_DIAG_SECCTX,
>> + 2), "-");
>
> Is the "-" string a special value already interpreted by the userspace tools?
> If not, you might consider using a string that would indicate an out-of-space
> condition occurred; at first glance I thought the "-" string indicated no
> context.
>
>> + }
>> + security_release_secctx(secctx, ctxlen);
>> + }
>> + }
>> +
>> r->idiag_family = sk->sk_family;
>> r->idiag_state = sk->sk_state;
>> r->idiag_timer = 0;
>> @@ -246,7 +267,7 @@ static int sk_diag_fill(struct sock *sk, struct sk_buff
>> *skb, static int inet_diag_get_exact(struct sk_buff *in_skb,
>> const struct nlmsghdr *nlh)
>> {
>> - int err;
>> + int err, len;
>> struct sock *sk;
>> struct inet_diag_req *req = NLMSG_DATA(nlh);
>> struct sk_buff *rep;
>> @@ -293,10 +314,17 @@ static int inet_diag_get_exact(struct sk_buff *in_skb,
>> goto out;
>>
>> err = -ENOMEM;
>> - rep = alloc_skb(NLMSG_SPACE((sizeof(struct inet_diag_msg) +
>> - sizeof(struct inet_diag_meminfo) +
>> - handler->idiag_info_size + 64)),
>> - GFP_KERNEL);
>> + len = sizeof(struct inet_diag_msg) + 64;
>> +
>> + len += (req->idiag_ext& (1<< (INET_DIAG_MEMINFO - 1))) ?
>> + sizeof(struct inet_diag_meminfo) : 0;
>> + len += (req->idiag_ext& (1<< (INET_DIAG_INFO - 1))) ?
>> + handler->idiag_info_size : 0;
>> + len += (req->idiag_ext& (1<< (INET_DIAG_SECCTX - 1))) ?
>> + MAX_SECCTX_LEN : 0;
>> +
>> + rep = alloc_skb(NLMSG_SPACE(len), GFP_KERNEL);
>
> How much of a problem would it be if you just allocated an entire page (or 4k
> in the case of huge pages) and used that? Is memory usage a concern here?
>
The memory usage is main concern, or else the 4k page is good idea.
Other side is that this function is few called, so the 4k maybe acceptable.
--
Best Reagrds,
Roy | RongQing Li
^ permalink raw reply
* Re: [patch 1/3 -next] 6LoWPAN: use kfree_skb() instead of kfree()
From: Alexander Smirnov @ 2011-09-01 9:26 UTC (permalink / raw)
To: Eric Dumazet
Cc: Dan Carpenter, Dmitry Eremin-Solenikov, Sergey Lapin,
David S. Miller, open list:IEEE 802.15.4 SUB...,
open list:NETWORKING [GENERAL], kernel-janitors
In-Reply-To: <1314715248.2935.25.camel@edumazet-HP-Compaq-6005-Pro-SFF-PC>
Hi Dan, Eric,
thank you a lot for the finds, that were my faults.
With best regards,
Alexander
2011/8/30 Eric Dumazet <eric.dumazet@gmail.com>:
> Le mardi 30 août 2011 à 16:45 +0300, Dan Carpenter a écrit :
>> Use kfree_skb() to free sbk_buffs.
>>
>> Signed-off-by: Dan Carpenter <error27@gmail.com>
>>
>> diff --git a/net/ieee802154/6lowpan.c b/net/ieee802154/6lowpan.c
>> index cf304cc..8a9dbaa 100644
>> --- a/net/ieee802154/6lowpan.c
>> +++ b/net/ieee802154/6lowpan.c
>> @@ -674,7 +674,7 @@ lowpan_process_data(struct sk_buff *skb)
>> sizeof(hdr));
>> return lowpan_skb_deliver(skb, &hdr);
>> drop:
>> - kfree(skb);
>> + kfree_skb(skb);
>> return -EINVAL;
>> }
>>
>
> Another bug is the skb_copy() done in lowpan_skb_deliver()
>
> 1) No check of skb_copy() return
>
> 2.1) Use of GFP_KERNEL : Is it safe at this point ? Aren’t we in
> softirq ?
>
> 2.2) If GFP_KERNEL is safe, why do we later do :
>
> if (in_interrupt())
> stat = netif_rx(skb);
> else
> stat = netif_rx_ni(skb);
>
>
>
>
^ permalink raw reply
* [PATCH 2/2] mii: Remove references to DP83840 PHY in mii.h
From: Mark Einon @ 2011-09-01 9:22 UTC (permalink / raw)
To: netdev; +Cc: bhutchings, davem, Mark Einon
In-Reply-To: <1314868937-2536-1-git-send-email-mark.einon@gmail.com>
There are references to this PHY chip in the generic mii.h header, so removing them.
Re-jiggle the changed comments, in response to points raised by Ben Hutchings.
Signed-off-by: Mark Einon <mark.einon@gmail.com>
---
include/linux/mii.h | 6 +++---
1 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/include/linux/mii.h b/include/linux/mii.h
index d9f7750..2774823 100644
--- a/include/linux/mii.h
+++ b/include/linux/mii.h
@@ -39,12 +39,12 @@
#define BMCR_CTST 0x0080 /* Collision test */
#define BMCR_FULLDPLX 0x0100 /* Full duplex */
#define BMCR_ANRESTART 0x0200 /* Auto negotiation restart */
-#define BMCR_ISOLATE 0x0400 /* Disconnect DP83840 from MII */
-#define BMCR_PDOWN 0x0800 /* Powerdown the DP83840 */
+#define BMCR_ISOLATE 0x0400 /* Isolate data paths from MII */
+#define BMCR_PDOWN 0x0800 /* Enable low power state */
#define BMCR_ANENABLE 0x1000 /* Enable auto negotiation */
#define BMCR_SPEED100 0x2000 /* Select 100Mbps */
#define BMCR_LOOPBACK 0x4000 /* TXD loopback bits */
-#define BMCR_RESET 0x8000 /* Reset the DP83840 */
+#define BMCR_RESET 0x8000 /* Reset to default state */
/* Basic mode status register. */
#define BMSR_ERCAP 0x0001 /* Ext-reg capability */
--
1.7.6
^ permalink raw reply related
* [PATCH 1/2] [TRIVIAL] mii: Convert spaces to tabs in mii.h
From: Mark Einon @ 2011-09-01 9:22 UTC (permalink / raw)
To: netdev; +Cc: bhutchings, davem, Mark Einon
In-Reply-To: <1314804928-7353-1-git-send-email-mark.einon@gmail.com>
Whitespace changes - spaces converted to tabs after each define name and value
Signed-off-by: Mark Einon <mark.einon@gmail.com>
---
include/linux/mii.h | 210 +++++++++++++++++++++++++--------------------------
1 files changed, 104 insertions(+), 106 deletions(-)
diff --git a/include/linux/mii.h b/include/linux/mii.h
index 103113a..d9f7750 100644
--- a/include/linux/mii.h
+++ b/include/linux/mii.h
@@ -11,131 +11,130 @@
#include <linux/types.h>
/* Generic MII registers. */
-
-#define MII_BMCR 0x00 /* Basic mode control register */
-#define MII_BMSR 0x01 /* Basic mode status register */
-#define MII_PHYSID1 0x02 /* PHYS ID 1 */
-#define MII_PHYSID2 0x03 /* PHYS ID 2 */
-#define MII_ADVERTISE 0x04 /* Advertisement control reg */
-#define MII_LPA 0x05 /* Link partner ability reg */
-#define MII_EXPANSION 0x06 /* Expansion register */
-#define MII_CTRL1000 0x09 /* 1000BASE-T control */
-#define MII_STAT1000 0x0a /* 1000BASE-T status */
-#define MII_ESTATUS 0x0f /* Extended Status */
-#define MII_DCOUNTER 0x12 /* Disconnect counter */
-#define MII_FCSCOUNTER 0x13 /* False carrier counter */
-#define MII_NWAYTEST 0x14 /* N-way auto-neg test reg */
-#define MII_RERRCOUNTER 0x15 /* Receive error counter */
-#define MII_SREVISION 0x16 /* Silicon revision */
-#define MII_RESV1 0x17 /* Reserved... */
-#define MII_LBRERROR 0x18 /* Lpback, rx, bypass error */
-#define MII_PHYADDR 0x19 /* PHY address */
-#define MII_RESV2 0x1a /* Reserved... */
-#define MII_TPISTATUS 0x1b /* TPI status for 10mbps */
-#define MII_NCONFIG 0x1c /* Network interface config */
+#define MII_BMCR 0x00 /* Basic mode control register */
+#define MII_BMSR 0x01 /* Basic mode status register */
+#define MII_PHYSID1 0x02 /* PHYS ID 1 */
+#define MII_PHYSID2 0x03 /* PHYS ID 2 */
+#define MII_ADVERTISE 0x04 /* Advertisement control reg */
+#define MII_LPA 0x05 /* Link partner ability reg */
+#define MII_EXPANSION 0x06 /* Expansion register */
+#define MII_CTRL1000 0x09 /* 1000BASE-T control */
+#define MII_STAT1000 0x0a /* 1000BASE-T status */
+#define MII_ESTATUS 0x0f /* Extended Status */
+#define MII_DCOUNTER 0x12 /* Disconnect counter */
+#define MII_FCSCOUNTER 0x13 /* False carrier counter */
+#define MII_NWAYTEST 0x14 /* N-way auto-neg test reg */
+#define MII_RERRCOUNTER 0x15 /* Receive error counter */
+#define MII_SREVISION 0x16 /* Silicon revision */
+#define MII_RESV1 0x17 /* Reserved... */
+#define MII_LBRERROR 0x18 /* Lpback, rx, bypass error */
+#define MII_PHYADDR 0x19 /* PHY address */
+#define MII_RESV2 0x1a /* Reserved... */
+#define MII_TPISTATUS 0x1b /* TPI status for 10mbps */
+#define MII_NCONFIG 0x1c /* Network interface config */
/* Basic mode control register. */
-#define BMCR_RESV 0x003f /* Unused... */
-#define BMCR_SPEED1000 0x0040 /* MSB of Speed (1000) */
-#define BMCR_CTST 0x0080 /* Collision test */
-#define BMCR_FULLDPLX 0x0100 /* Full duplex */
-#define BMCR_ANRESTART 0x0200 /* Auto negotiation restart */
-#define BMCR_ISOLATE 0x0400 /* Disconnect DP83840 from MII */
-#define BMCR_PDOWN 0x0800 /* Powerdown the DP83840 */
-#define BMCR_ANENABLE 0x1000 /* Enable auto negotiation */
-#define BMCR_SPEED100 0x2000 /* Select 100Mbps */
-#define BMCR_LOOPBACK 0x4000 /* TXD loopback bits */
-#define BMCR_RESET 0x8000 /* Reset the DP83840 */
+#define BMCR_RESV 0x003f /* Unused... */
+#define BMCR_SPEED1000 0x0040 /* MSB of Speed (1000) */
+#define BMCR_CTST 0x0080 /* Collision test */
+#define BMCR_FULLDPLX 0x0100 /* Full duplex */
+#define BMCR_ANRESTART 0x0200 /* Auto negotiation restart */
+#define BMCR_ISOLATE 0x0400 /* Disconnect DP83840 from MII */
+#define BMCR_PDOWN 0x0800 /* Powerdown the DP83840 */
+#define BMCR_ANENABLE 0x1000 /* Enable auto negotiation */
+#define BMCR_SPEED100 0x2000 /* Select 100Mbps */
+#define BMCR_LOOPBACK 0x4000 /* TXD loopback bits */
+#define BMCR_RESET 0x8000 /* Reset the DP83840 */
/* Basic mode status register. */
-#define BMSR_ERCAP 0x0001 /* Ext-reg capability */
-#define BMSR_JCD 0x0002 /* Jabber detected */
-#define BMSR_LSTATUS 0x0004 /* Link status */
-#define BMSR_ANEGCAPABLE 0x0008 /* Able to do auto-negotiation */
-#define BMSR_RFAULT 0x0010 /* Remote fault detected */
-#define BMSR_ANEGCOMPLETE 0x0020 /* Auto-negotiation complete */
-#define BMSR_RESV 0x00c0 /* Unused... */
-#define BMSR_ESTATEN 0x0100 /* Extended Status in R15 */
-#define BMSR_100HALF2 0x0200 /* Can do 100BASE-T2 HDX */
-#define BMSR_100FULL2 0x0400 /* Can do 100BASE-T2 FDX */
-#define BMSR_10HALF 0x0800 /* Can do 10mbps, half-duplex */
-#define BMSR_10FULL 0x1000 /* Can do 10mbps, full-duplex */
-#define BMSR_100HALF 0x2000 /* Can do 100mbps, half-duplex */
-#define BMSR_100FULL 0x4000 /* Can do 100mbps, full-duplex */
-#define BMSR_100BASE4 0x8000 /* Can do 100mbps, 4k packets */
+#define BMSR_ERCAP 0x0001 /* Ext-reg capability */
+#define BMSR_JCD 0x0002 /* Jabber detected */
+#define BMSR_LSTATUS 0x0004 /* Link status */
+#define BMSR_ANEGCAPABLE 0x0008 /* Able to do auto-negotiation */
+#define BMSR_RFAULT 0x0010 /* Remote fault detected */
+#define BMSR_ANEGCOMPLETE 0x0020 /* Auto-negotiation complete */
+#define BMSR_RESV 0x00c0 /* Unused... */
+#define BMSR_ESTATEN 0x0100 /* Extended Status in R15 */
+#define BMSR_100HALF2 0x0200 /* Can do 100BASE-T2 HDX */
+#define BMSR_100FULL2 0x0400 /* Can do 100BASE-T2 FDX */
+#define BMSR_10HALF 0x0800 /* Can do 10mbps, half-duplex */
+#define BMSR_10FULL 0x1000 /* Can do 10mbps, full-duplex */
+#define BMSR_100HALF 0x2000 /* Can do 100mbps, half-duplex */
+#define BMSR_100FULL 0x4000 /* Can do 100mbps, full-duplex */
+#define BMSR_100BASE4 0x8000 /* Can do 100mbps, 4k packets */
/* Advertisement control register. */
-#define ADVERTISE_SLCT 0x001f /* Selector bits */
-#define ADVERTISE_CSMA 0x0001 /* Only selector supported */
-#define ADVERTISE_10HALF 0x0020 /* Try for 10mbps half-duplex */
-#define ADVERTISE_1000XFULL 0x0020 /* Try for 1000BASE-X full-duplex */
-#define ADVERTISE_10FULL 0x0040 /* Try for 10mbps full-duplex */
-#define ADVERTISE_1000XHALF 0x0040 /* Try for 1000BASE-X half-duplex */
-#define ADVERTISE_100HALF 0x0080 /* Try for 100mbps half-duplex */
-#define ADVERTISE_1000XPAUSE 0x0080 /* Try for 1000BASE-X pause */
-#define ADVERTISE_100FULL 0x0100 /* Try for 100mbps full-duplex */
-#define ADVERTISE_1000XPSE_ASYM 0x0100 /* Try for 1000BASE-X asym pause */
-#define ADVERTISE_100BASE4 0x0200 /* Try for 100mbps 4k packets */
-#define ADVERTISE_PAUSE_CAP 0x0400 /* Try for pause */
-#define ADVERTISE_PAUSE_ASYM 0x0800 /* Try for asymetric pause */
-#define ADVERTISE_RESV 0x1000 /* Unused... */
-#define ADVERTISE_RFAULT 0x2000 /* Say we can detect faults */
-#define ADVERTISE_LPACK 0x4000 /* Ack link partners response */
-#define ADVERTISE_NPAGE 0x8000 /* Next page bit */
-
-#define ADVERTISE_FULL (ADVERTISE_100FULL | ADVERTISE_10FULL | \
- ADVERTISE_CSMA)
-#define ADVERTISE_ALL (ADVERTISE_10HALF | ADVERTISE_10FULL | \
- ADVERTISE_100HALF | ADVERTISE_100FULL)
+#define ADVERTISE_SLCT 0x001f /* Selector bits */
+#define ADVERTISE_CSMA 0x0001 /* Only selector supported */
+#define ADVERTISE_10HALF 0x0020 /* Try for 10mbps half-duplex */
+#define ADVERTISE_1000XFULL 0x0020 /* Try for 1000BASE-X full-duplex */
+#define ADVERTISE_10FULL 0x0040 /* Try for 10mbps full-duplex */
+#define ADVERTISE_1000XHALF 0x0040 /* Try for 1000BASE-X half-duplex */
+#define ADVERTISE_100HALF 0x0080 /* Try for 100mbps half-duplex */
+#define ADVERTISE_1000XPAUSE 0x0080 /* Try for 1000BASE-X pause */
+#define ADVERTISE_100FULL 0x0100 /* Try for 100mbps full-duplex */
+#define ADVERTISE_1000XPSE_ASYM 0x0100 /* Try for 1000BASE-X asym pause */
+#define ADVERTISE_100BASE4 0x0200 /* Try for 100mbps 4k packets */
+#define ADVERTISE_PAUSE_CAP 0x0400 /* Try for pause */
+#define ADVERTISE_PAUSE_ASYM 0x0800 /* Try for asymetric pause */
+#define ADVERTISE_RESV 0x1000 /* Unused... */
+#define ADVERTISE_RFAULT 0x2000 /* Say we can detect faults */
+#define ADVERTISE_LPACK 0x4000 /* Ack link partners response */
+#define ADVERTISE_NPAGE 0x8000 /* Next page bit */
+
+#define ADVERTISE_FULL (ADVERTISE_100FULL | ADVERTISE_10FULL | \
+ ADVERTISE_CSMA)
+#define ADVERTISE_ALL (ADVERTISE_10HALF | ADVERTISE_10FULL | \
+ ADVERTISE_100HALF | ADVERTISE_100FULL)
/* Link partner ability register. */
-#define LPA_SLCT 0x001f /* Same as advertise selector */
-#define LPA_10HALF 0x0020 /* Can do 10mbps half-duplex */
-#define LPA_1000XFULL 0x0020 /* Can do 1000BASE-X full-duplex */
-#define LPA_10FULL 0x0040 /* Can do 10mbps full-duplex */
-#define LPA_1000XHALF 0x0040 /* Can do 1000BASE-X half-duplex */
-#define LPA_100HALF 0x0080 /* Can do 100mbps half-duplex */
-#define LPA_1000XPAUSE 0x0080 /* Can do 1000BASE-X pause */
-#define LPA_100FULL 0x0100 /* Can do 100mbps full-duplex */
-#define LPA_1000XPAUSE_ASYM 0x0100 /* Can do 1000BASE-X pause asym*/
-#define LPA_100BASE4 0x0200 /* Can do 100mbps 4k packets */
-#define LPA_PAUSE_CAP 0x0400 /* Can pause */
-#define LPA_PAUSE_ASYM 0x0800 /* Can pause asymetrically */
-#define LPA_RESV 0x1000 /* Unused... */
-#define LPA_RFAULT 0x2000 /* Link partner faulted */
-#define LPA_LPACK 0x4000 /* Link partner acked us */
-#define LPA_NPAGE 0x8000 /* Next page bit */
+#define LPA_SLCT 0x001f /* Same as advertise selector */
+#define LPA_10HALF 0x0020 /* Can do 10mbps half-duplex */
+#define LPA_1000XFULL 0x0020 /* Can do 1000BASE-X full-duplex */
+#define LPA_10FULL 0x0040 /* Can do 10mbps full-duplex */
+#define LPA_1000XHALF 0x0040 /* Can do 1000BASE-X half-duplex */
+#define LPA_100HALF 0x0080 /* Can do 100mbps half-duplex */
+#define LPA_1000XPAUSE 0x0080 /* Can do 1000BASE-X pause */
+#define LPA_100FULL 0x0100 /* Can do 100mbps full-duplex */
+#define LPA_1000XPAUSE_ASYM 0x0100 /* Can do 1000BASE-X pause asym*/
+#define LPA_100BASE4 0x0200 /* Can do 100mbps 4k packets */
+#define LPA_PAUSE_CAP 0x0400 /* Can pause */
+#define LPA_PAUSE_ASYM 0x0800 /* Can pause asymetrically */
+#define LPA_RESV 0x1000 /* Unused... */
+#define LPA_RFAULT 0x2000 /* Link partner faulted */
+#define LPA_LPACK 0x4000 /* Link partner acked us */
+#define LPA_NPAGE 0x8000 /* Next page bit */
#define LPA_DUPLEX (LPA_10FULL | LPA_100FULL)
#define LPA_100 (LPA_100FULL | LPA_100HALF | LPA_100BASE4)
/* Expansion register for auto-negotiation. */
-#define EXPANSION_NWAY 0x0001 /* Can do N-way auto-nego */
-#define EXPANSION_LCWP 0x0002 /* Got new RX page code word */
-#define EXPANSION_ENABLENPAGE 0x0004 /* This enables npage words */
-#define EXPANSION_NPCAPABLE 0x0008 /* Link partner supports npage */
-#define EXPANSION_MFAULTS 0x0010 /* Multiple faults detected */
-#define EXPANSION_RESV 0xffe0 /* Unused... */
+#define EXPANSION_NWAY 0x0001 /* Can do N-way auto-nego */
+#define EXPANSION_LCWP 0x0002 /* Got new RX page code word */
+#define EXPANSION_ENABLENPAGE 0x0004 /* This enables npage words */
+#define EXPANSION_NPCAPABLE 0x0008 /* Link partner supports npage */
+#define EXPANSION_MFAULTS 0x0010 /* Multiple faults detected */
+#define EXPANSION_RESV 0xffe0 /* Unused... */
-#define ESTATUS_1000_TFULL 0x2000 /* Can do 1000BT Full */
-#define ESTATUS_1000_THALF 0x1000 /* Can do 1000BT Half */
+#define ESTATUS_1000_TFULL 0x2000 /* Can do 1000BT Full */
+#define ESTATUS_1000_THALF 0x1000 /* Can do 1000BT Half */
/* N-way test register. */
-#define NWAYTEST_RESV1 0x00ff /* Unused... */
-#define NWAYTEST_LOOPBACK 0x0100 /* Enable loopback for N-way */
-#define NWAYTEST_RESV2 0xfe00 /* Unused... */
+#define NWAYTEST_RESV1 0x00ff /* Unused... */
+#define NWAYTEST_LOOPBACK 0x0100 /* Enable loopback for N-way */
+#define NWAYTEST_RESV2 0xfe00 /* Unused... */
/* 1000BASE-T Control register */
-#define ADVERTISE_1000FULL 0x0200 /* Advertise 1000BASE-T full duplex */
-#define ADVERTISE_1000HALF 0x0100 /* Advertise 1000BASE-T half duplex */
+#define ADVERTISE_1000FULL 0x0200 /* Advertise 1000BASE-T full duplex */
+#define ADVERTISE_1000HALF 0x0100 /* Advertise 1000BASE-T half duplex */
#define CTL1000_AS_MASTER 0x0800
#define CTL1000_ENABLE_MASTER 0x1000
/* 1000BASE-T Status register */
-#define LPA_1000LOCALRXOK 0x2000 /* Link partner local receiver status */
-#define LPA_1000REMRXOK 0x1000 /* Link partner remote receiver status */
-#define LPA_1000FULL 0x0800 /* Link partner 1000BASE-T full duplex */
-#define LPA_1000HALF 0x0400 /* Link partner 1000BASE-T half duplex */
+#define LPA_1000LOCALRXOK 0x2000 /* Link partner local receiver status */
+#define LPA_1000REMRXOK 0x1000 /* Link partner remote receiver status */
+#define LPA_1000FULL 0x0800 /* Link partner 1000BASE-T full duplex */
+#define LPA_1000HALF 0x0400 /* Link partner 1000BASE-T half duplex */
/* Flow control flags */
#define FLOW_CTRL_TX 0x01
@@ -149,7 +148,7 @@ struct mii_ioctl_data {
__u16 val_out;
};
-#ifdef __KERNEL__
+#ifdef __KERNEL__
#include <linux/if.h>
@@ -180,7 +179,7 @@ extern unsigned int mii_check_media (struct mii_if_info *mii,
unsigned int ok_to_print,
unsigned int init_media);
extern int generic_mii_ioctl(struct mii_if_info *mii_if,
- struct mii_ioctl_data *mii_data, int cmd,
+ struct mii_ioctl_data *mii_data, int cmd,
unsigned int *duplex_changed);
@@ -189,7 +188,6 @@ static inline struct mii_ioctl_data *if_mii(struct ifreq *rq)
return (struct mii_ioctl_data *) &rq->ifr_ifru;
}
-
/**
* mii_nway_result
* @negotiated: value of MII ANAR and'd with ANLPAR
--
1.7.6
^ permalink raw reply related
* Re: [PATCH] mii: Remove references to DP83840 PHY in mii.h
From: Mark Einon @ 2011-09-01 9:22 UTC (permalink / raw)
To: Ben Hutchings; +Cc: netdev, davem
In-Reply-To: <1314812070.3274.19.camel@bwh-desktop>
On 31 August 2011 18:34, Ben Hutchings <bhutchings@solarflare.com> wrote:
>
> Since you're trying to improve these comments, I think this could do
> with further improvement. When this bit is set, the PHY's data paths
> are isolated from the MII (or other interface to the MAC). The control
> path is still connected to the management interface (MDIO), which is
> important when we want to clear this bit! So it would be better to say
> something like 'Isolate data paths fromn MII'.
>
> This selects a low-power state (if implemented). It doesn't entirely
> turn the PHY off, and at least the management interface must stil be
> functional. So it would be better to say 'Request low-power state'.
Hi Ben,
Fair points, hope I've addressed these in the revised patch.
> This formatting change is unrelated. If you're going to fix formatting
> then please convert spaces to tabs after each name and value.
>
Done, and broken out into a separate patch.
Cheers,
Mark
^ permalink raw reply
* RE: [PATCH 1/3] bnx2x: remove TPA_ENABLE_FLAG
From: Vladislav Zolotarov @ 2011-09-01 8:37 UTC (permalink / raw)
To: Michał Mirosław
Cc: Michal Schmidt, netdev@vger.kernel.org, Dmitry Kravkov,
Eilon Greenstein
In-Reply-To: <CAHXqBF+f=3yM88CJ+FpNELBb+Sof5q1=pTXm303-QN7y6M9Dsg@mail.gmail.com>
> -----Original Message-----
> From: netdev-owner@vger.kernel.org [mailto:netdev-
> owner@vger.kernel.org] On Behalf Of Michal Miroslaw
> Sent: Wednesday, August 31, 2011 9:05 PM
> To: Vladislav Zolotarov
> Cc: Michal Schmidt; netdev@vger.kernel.org; Dmitry Kravkov; Eilon
> Greenstein
> Subject: Re: [PATCH 1/3] bnx2x: remove TPA_ENABLE_FLAG
>
> 2011/8/31 Vladislav Zolotarov <vladz@broadcom.com>:
> >> -----Original Message-----
> >> From: Michal Schmidt [mailto:mschmidt@redhat.com]
> >> Sent: Wednesday, August 31, 2011 6:59 PM
> >> To: Vladislav Zolotarov
> >> Cc: netdev@vger.kernel.org; Dmitry Kravkov; Eilon Greenstein;
> >> mirqus@gmail.com
> >> Subject: Re: [PATCH 1/3] bnx2x: remove TPA_ENABLE_FLAG
> >>
> >> On Wed, 31 Aug 2011 18:16:30 +0300 Vlad Zolotarov wrote:
> >> > On Wednesday 31 August 2011 18:00:34 Michal Schmidt wrote:
> >> > > if (bnx2x_reload) {
> >> > > - if (bp->recovery_state == BNX2X_RECOVERY_DONE)
> >> > > + if (bp->recovery_state == BNX2X_RECOVERY_DONE) {
> >> > > + /*
> >> > > + * Cheat! Normally dev->features will be
> >> > > set after we
> >> > > + * return, but that's too late. We need to
> >> > > know how to
> >> > > + * configure the NIC when reloading it, so
> >> > > update
> >> > > + * the features early.
> >> > > + */
> >> > > + dev->features = features;
> >> > > return bnx2x_reload_if_running(dev);
> >> >
> >> > NACK
> >> >
> >> > This is bogus - what if bnx2x_reload_if_running(dev)
> >> > (bnx2x_nic_load()) failes? The original dev->features would be
> >> > lost...
> >>
> >> Well, yes, but since the NIC would be now not working, do we really
> >> care about its features? :-)
> >
> > U r kidding, right? ;)
> > We care about the consistency in the netdev features state - if we
> failed
> > to configure the requested feature and returned an error on e.g.
> "ethtool -K ethX lro on"
> > call, it's expected that a subsequent ethtool -k ethX call won't
> report the requested
> > feature (LRO) as set.
>
> If bnx2x_reload_if_running() failure means that NIC is disabled, then
> Michal is right that there's no point in caring about dev->features,
> sice 'load' operation (NIC configuration) needs to be done again
> anyway.
Michal, it's a matter of a consistent semantics/behavior of the ethtool callbacks just as I described above.
As long as dev->features may be queried both when device is down I'm afraid I can't agree with u.
Thanks,
vlad
>
> Best Regards,
> Michał Mirosław
> --
> To unsubscribe from this list: send the line "unsubscribe netdev" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* [linux-firmware v4 1/2] rtl_nic: update firmware for RTL8111E-VL
From: Hayes Wang @ 2011-09-01 7:07 UTC (permalink / raw)
To: dwmw2; +Cc: romieu, netdev, Hayes Wang
Updated firmware with stability fixes.
Version: 0.0.2
Signed-off-by: Hayes Wang <hayeswang@realtek.com>
---
WHENCE | 2 ++
rtl_nic/rtl8168e-3.fw | Bin 2804 -> 3552 bytes
2 files changed, 2 insertions(+), 0 deletions(-)
diff --git a/WHENCE b/WHENCE
index a47b307..3803906 100644
--- a/WHENCE
+++ b/WHENCE
@@ -1657,7 +1657,9 @@ File: rtl_nic/rtl8168d-2.fw
File: rtl_nic/rtl8105e-1.fw
File: rtl_nic/rtl8168e-1.fw
File: rtl_nic/rtl8168e-2.fw
+
File: rtl_nic/rtl8168e-3.fw
+Version: 0.0.2
Licence:
* Copyright © 2011, Realtek Semiconductor Corporation
diff --git a/rtl_nic/rtl8168e-3.fw b/rtl_nic/rtl8168e-3.fw
index cb494071d0273c7b3102b97552f4bc7b756c0e17..525f467e04229c52fbc38676b2bbdc93832bc945 100644
GIT binary patch
literal 3552
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
G_V+)RiLX5X
literal 2804
zcmaKuS!|S56vyvuXDEwdX=z8WolZ+xrAP=!Vq#-Nc`(M9m<Srf13vJiQ4@-BIfa&`
zMS>d`6R?UeXp0DaGtxc~Ow<@#AOWSxH%JAQw21-A(sulv@B5~F;_~q2-gE9*{^x(s
zJu}W#sjG16T$w8jxh!jsTkSNBzTQ=$cQ3}A^PHP)Mp<?7_Vv!~b}qHVg}!E6^Ecaa
zhfmgFTN>J?u(?)9sXFmvo4q7vYMSp0SElP4GJ2TRHD>fnTi?j&5!S;mW%Q`YZ)UX1
z<d-uVi<N20Wi-K>U`?@(F3G5{4)4oon)L)SwfH$4IpT&j{MJ>M`xqL)kaQJVo32nd
zmeFOlj%KvBf^`JhR%G8V;^Xi!U9={r)D{;VUM=cT<8VP#+eHtdi(eBhi;2c;pA)Sw
z?jICg!`}SjJ4FwwXqzXR-!8hN4f{&uyl7=BI_%n_I_ypNR#dl3v>n|y<p1iBXwxat
z3;RXi!KQ6MwD(=n?u6*u&7v#F*;|9m`d%mxB1?<tAT|?NyVr?s$Jbp3TSjy@`@tK+
zJ+hL+YU~}uj{Wv%Ov4(=Nn(1}1Dx4T{7QqpakQ4Y5{;rIU`!bYKZ`!FS#&A;k^4li
zCyC>Uc2d{fS<x&!wq3vud0vy~Li71fbpE}>v3-~5`}i!j{kNhoMEoaJi&jVcmvJ@=
zJMWU{F6zpG?OF=Ha)DgTI|2MP5x?2sDxRfkMQg(|4@?$kPBG4$JL1%d)<xo61@m~E
zxuSC;XRpG4azyk7ybaw1;|9@f#5Vr=o)7r`tzL9F_$%@2rnal0JQ=xiTA;fg)lCm{
zx1zckfo^YA5X<-Fek|Uu=7?@47|`wHzT(*CxUbe<xfgn{6h4-KYlxgrgJ=I_^lAEM
zIr_EK@ezI8iy!^ySnIpl{|TonME4Adj?zEHT7RHctM?}L#^~Lyr@+Gbhar|uYI}5^
zXtTxG%YBh!UWe$9&mhxJ)tmW{JGe)CXOEN9!}i#5aBd|}pJ?U`-&xUfVC<)-(|kL2
zh^_}q`Z>`l1<_~W*uniHmDrx+>lZzL1Ra>VW1@S(WAEn>y>aXw(c|>!R`T@0-I=85
z*)VR=_XxR8UBMrWMeJ7p5Vei%;X6UUk8<DO_Rfp`^1J9C#7x6q0zR|g@ZkGmsP{O_
z(;uU(N%I4%^-@O@@1*YbzLY!j^(~@zWpD4Tr+xi4c&g>S!PA97V$BX$YVvWsCi*&Y
z{e1U}u4KQMyY8F?Pb-6at+u;39o*+;<AfR0F$o>^LR{0uPx98b1U1^5Zp{-DKAPz1
zI^xBt`_mkEIUL~Xq>dEWYw#UDi0ypQmazZL_H%e%P_(7C6!lCu+l$yP4Bkp@7<VIi
z7h&5vKz?$L&lGYb;Hnxwk2AwkjgMC%dWAmE(ns-x=m*3$t~$w60*9^aJBX72-wgA;
z6=180_~t_2o4h&S7oJPtdEA$nTksu$-+$x7n?Nst+n*(tgPtG9H&JwAb1*Mb?Ysdy
zkMLu@m%wke_-6|u_&Cc_XQJpA;mZ6RH5ShX76m-GkD2kD*^EC;&DQrL;2-23%|40V
z=DW=&<J_ZHP4CEIcXfa|uF?mwP(F%02{|6hUn3`wE$@g6_^=re-@u#UtYr{i^foI-
zcrV76=^SsW*|5;FzRu%K2ycemu_}6Rzvuun$>b#Qi*bsx#&X;uM+^NsM4Y}&<Redx
zFHQ~qoVpzJ^$hEAW|qyHRZ~Q()-VIWbF!cJ1~>im{8Vz-`~JVLoPJ1tB3k(VpR;cq
z549yM4sWVk$qW8X<XXk|Uzp~?dm}aE3&HPpjQ6?tvjF3!v&>}THF4M7;BBXOiog9s
zF>vEIZ8AI_W~DZNKJ5$Yws{?ujYFHW#^(WkJG!`Y<!z7G1&-)U&tto>L9`)HUyyrg
zPV@=(`B&iJVbPyF^k9Cnhkmj>Slwfy59L$Fqy2}R%G%R#hg|&c<--4_g@POZZ(97n
VdHX+Uxf?6kf6?+D|9>1#e*sYqwB!H)
--
1.7.6
^ permalink raw reply related
* [linux-firmware v4 2/2] rtl_nic: add new firmware for RTL8111F
From: Hayes Wang @ 2011-09-01 7:07 UTC (permalink / raw)
To: dwmw2; +Cc: romieu, netdev, Hayes Wang
In-Reply-To: <1314860833-4000-1-git-send-email-hayeswang@realtek.com>
Add new firmware:
1. rtl_nic/rtl8168f-1.fw
version: 0.0.2
2. rtl_nic/rtl8168f-2.fw
version: 0.0.2
Signed-off-by: Hayes Wang <hayeswang@realtek.com>
---
WHENCE | 6 ++++++
rtl_nic/rtl8168f-1.fw | Bin 0 -> 3024 bytes
rtl_nic/rtl8168f-2.fw | Bin 0 -> 336 bytes
3 files changed, 6 insertions(+), 0 deletions(-)
create mode 100644 rtl_nic/rtl8168f-1.fw
create mode 100644 rtl_nic/rtl8168f-2.fw
diff --git a/WHENCE b/WHENCE
index 3803906..ea3918c 100644
--- a/WHENCE
+++ b/WHENCE
@@ -1661,6 +1661,12 @@ File: rtl_nic/rtl8168e-2.fw
File: rtl_nic/rtl8168e-3.fw
Version: 0.0.2
+File: rtl_nic/rtl8168f-1.fw
+Version: 0.0.2
+
+File: rtl_nic/rtl8168f-2.fw
+Version: 0.0.2
+
Licence:
* Copyright © 2011, Realtek Semiconductor Corporation
*
diff --git a/rtl_nic/rtl8168f-1.fw b/rtl_nic/rtl8168f-1.fw
new file mode 100644
index 0000000000000000000000000000000000000000..ffb1dd137eebeb2394acbfcf14c96a6091e73a06
GIT binary patch
literal 3024
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
MzqYOImd5}71$?3tJpcdz
literal 0
HcmV?d00001
diff --git a/rtl_nic/rtl8168f-2.fw b/rtl_nic/rtl8168f-2.fw
new file mode 100644
index 0000000000000000000000000000000000000000..880a223f35ab98b5367d2d1ee788ac0c9b05d762
GIT binary patch
literal 336
zcmXw!y-EX75QUEk8YD%wS#>~kA+_0i?~<^j5w%s2yud<;R)L6ETFfJeRqT8MpCOem
z;a{vRY(+5f%(A&~_=YnxoI3z;eKXE|FTXqph3mLZNL-#~KJ}hGd*{?4HN@bw7lJ!3
z21jSb$z*g<c<=I%B_ZqkZolhs2ka|$pg@e}HxhD&DYQX9#U6cJtpRgj*M<^B?QsO#
zTX(Bnn{9J;qrRmLYKmB!x1tZmvFKODALB%HLAJ;ja+7=||DHtOs{Xt2S@eVah3K68
pbi(+!%m6bidzA}pqXtCe%=|h92o_7bN9aXW9hLp^-}iP7@DF!bO921?
literal 0
HcmV?d00001
--
1.7.6
^ 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