From bea3348eef27e6044b6161fd04c3152215f96411 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Wed, 3 Oct 2007 16:41:36 -0700 Subject: [NET]: Make NAPI polling independent of struct net_device objects. Several devices have multiple independant RX queues per net device, and some have a single interrupt doorbell for several queues. In either case, it's easier to support layouts like that if the structure representing the poll is independant from the net device itself. The signature of the ->poll() call back goes from: int foo_poll(struct net_device *dev, int *budget) to int foo_poll(struct napi_struct *napi, int budget) The caller is returned the number of RX packets processed (or the number of "NAPI credits" consumed if you want to get abstract). The callee no longer messes around bumping dev->quota, *budget, etc. because that is all handled in the caller upon return. The napi_struct is to be embedded in the device driver private data structures. Furthermore, it is the driver's responsibility to disable all NAPI instances in it's ->stop() device close handler. Since the napi_struct is privatized into the driver's private data structures, only the driver knows how to get at all of the napi_struct instances it may have per-device. With lots of help and suggestions from Rusty Russell, Roland Dreier, Michael Chan, Jeff Garzik, and Jamal Hadi Salim. Bug fixes from Thomas Graf, Roland Dreier, Peter Zijlstra, Joseph Fannin, Scott Wood, Hans J. Koch, and Michael Chan. [ Ported to current tree and all drivers converted. Integrated Stephen's follow-on kerneldoc additions, and restored poll_list handling to the old style to fix mutual exclusion issues. -DaveM ] Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- include/linux/netdevice.h | 361 +++++++++++++++++++++++++++++++++++++--------- include/linux/netpoll.h | 55 +++++-- 2 files changed, 330 insertions(+), 86 deletions(-) (limited to 'include/linux') diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index e679b2751665..b93575db8cce 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -31,6 +31,7 @@ #ifdef __KERNEL__ #include +#include #include #include #include @@ -38,6 +39,7 @@ #include #include #include +#include struct vlan_group; struct ethtool_ops; @@ -258,7 +260,6 @@ enum netdev_state_t __LINK_STATE_PRESENT, __LINK_STATE_SCHED, __LINK_STATE_NOCARRIER, - __LINK_STATE_RX_SCHED, __LINK_STATE_LINKWATCH_PENDING, __LINK_STATE_DORMANT, __LINK_STATE_QDISC_RUNNING, @@ -277,6 +278,110 @@ struct netdev_boot_setup { extern int __init netdev_boot_setup(char *str); +/* + * Structure for NAPI scheduling similar to tasklet but with weighting + */ +struct napi_struct { + /* The poll_list must only be managed by the entity which + * changes the state of the NAPI_STATE_SCHED bit. This means + * whoever atomically sets that bit can add this napi_struct + * to the per-cpu poll_list, and whoever clears that bit + * can remove from the list right before clearing the bit. + */ + struct list_head poll_list; + + unsigned long state; + int weight; + int (*poll)(struct napi_struct *, int); +#ifdef CONFIG_NETPOLL + spinlock_t poll_lock; + int poll_owner; + struct net_device *dev; + struct list_head dev_list; +#endif +}; + +enum +{ + NAPI_STATE_SCHED, /* Poll is scheduled */ +}; + +extern void FASTCALL(__napi_schedule(struct napi_struct *n)); + +/** + * napi_schedule_prep - check if napi can be scheduled + * @n: napi context + * + * Test if NAPI routine is already running, and if not mark + * it as running. This is used as a condition variable + * insure only one NAPI poll instance runs + */ +static inline int napi_schedule_prep(struct napi_struct *n) +{ + return !test_and_set_bit(NAPI_STATE_SCHED, &n->state); +} + +/** + * napi_schedule - schedule NAPI poll + * @n: napi context + * + * Schedule NAPI poll routine to be called if it is not already + * running. + */ +static inline void napi_schedule(struct napi_struct *n) +{ + if (napi_schedule_prep(n)) + __napi_schedule(n); +} + +/** + * napi_complete - NAPI processing complete + * @n: napi context + * + * Mark NAPI processing as complete. + */ +static inline void __napi_complete(struct napi_struct *n) +{ + BUG_ON(!test_bit(NAPI_STATE_SCHED, &n->state)); + list_del(&n->poll_list); + smp_mb__before_clear_bit(); + clear_bit(NAPI_STATE_SCHED, &n->state); +} + +static inline void napi_complete(struct napi_struct *n) +{ + local_irq_disable(); + __napi_complete(n); + local_irq_enable(); +} + +/** + * napi_disable - prevent NAPI from scheduling + * @n: napi context + * + * Stop NAPI from being scheduled on this context. + * Waits till any outstanding processing completes. + */ +static inline void napi_disable(struct napi_struct *n) +{ + while (test_and_set_bit(NAPI_STATE_SCHED, &n->state)) + msleep_interruptible(1); +} + +/** + * napi_enable - enable NAPI scheduling + * @n: napi context + * + * Resume NAPI from being scheduled on this context. + * Must be paired with napi_disable. + */ +static inline void napi_enable(struct napi_struct *n) +{ + BUG_ON(!test_bit(NAPI_STATE_SCHED, &n->state)); + smp_mb__before_clear_bit(); + clear_bit(NAPI_STATE_SCHED, &n->state); +} + /* * The DEVICE structure. * Actually, this whole structure is a big mistake. It mixes I/O @@ -319,6 +424,9 @@ struct net_device unsigned long state; struct list_head dev_list; +#ifdef CONFIG_NETPOLL + struct list_head napi_list; +#endif /* The device initialization function. Called only once. */ int (*init)(struct net_device *dev); @@ -430,12 +538,6 @@ struct net_device /* * Cache line mostly used on receive path (including eth_type_trans()) */ - struct list_head poll_list ____cacheline_aligned_in_smp; - /* Link to poll list */ - - int (*poll) (struct net_device *dev, int *quota); - int quota; - int weight; unsigned long last_rx; /* Time of last Rx */ /* Interface address info used in eth_type_trans() */ unsigned char dev_addr[MAX_ADDR_LEN]; /* hw address, (before bcast @@ -582,6 +684,12 @@ struct net_device #define NETDEV_ALIGN 32 #define NETDEV_ALIGN_CONST (NETDEV_ALIGN - 1) +/** + * netdev_priv - access network device private data + * @dev: network device + * + * Get network device private data + */ static inline void *netdev_priv(const struct net_device *dev) { return dev->priv; @@ -593,6 +701,23 @@ static inline void *netdev_priv(const struct net_device *dev) */ #define SET_NETDEV_DEV(net, pdev) ((net)->dev.parent = (pdev)) +static inline void netif_napi_add(struct net_device *dev, + struct napi_struct *napi, + int (*poll)(struct napi_struct *, int), + int weight) +{ + INIT_LIST_HEAD(&napi->poll_list); + napi->poll = poll; + napi->weight = weight; +#ifdef CONFIG_NETPOLL + napi->dev = dev; + list_add(&napi->dev_list, &dev->napi_list); + spin_lock_init(&napi->poll_lock); + napi->poll_owner = -1; +#endif + set_bit(NAPI_STATE_SCHED, &napi->state); +} + struct packet_type { __be16 type; /* This is really htons(ether_type). */ struct net_device *dev; /* NULL is wildcarded here */ @@ -678,7 +803,6 @@ static inline int unregister_gifconf(unsigned int family) * Incoming packets are placed on per-cpu queues so that * no locking is needed. */ - struct softnet_data { struct net_device *output_queue; @@ -686,7 +810,7 @@ struct softnet_data struct list_head poll_list; struct sk_buff *completion_queue; - struct net_device backlog_dev; /* Sorry. 8) */ + struct napi_struct backlog; #ifdef CONFIG_NET_DMA struct dma_chan *net_dma; #endif @@ -704,11 +828,24 @@ static inline void netif_schedule(struct net_device *dev) __netif_schedule(dev); } +/** + * netif_start_queue - allow transmit + * @dev: network device + * + * Allow upper layers to call the device hard_start_xmit routine. + */ static inline void netif_start_queue(struct net_device *dev) { clear_bit(__LINK_STATE_XOFF, &dev->state); } +/** + * netif_wake_queue - restart transmit + * @dev: network device + * + * Allow upper layers to call the device hard_start_xmit routine. + * Used for flow control when transmit resources are available. + */ static inline void netif_wake_queue(struct net_device *dev) { #ifdef CONFIG_NETPOLL_TRAP @@ -721,16 +858,35 @@ static inline void netif_wake_queue(struct net_device *dev) __netif_schedule(dev); } +/** + * netif_stop_queue - stop transmitted packets + * @dev: network device + * + * Stop upper layers calling the device hard_start_xmit routine. + * Used for flow control when transmit resources are unavailable. + */ static inline void netif_stop_queue(struct net_device *dev) { set_bit(__LINK_STATE_XOFF, &dev->state); } +/** + * netif_queue_stopped - test if transmit queue is flowblocked + * @dev: network device + * + * Test if transmit queue on device is currently unable to send. + */ static inline int netif_queue_stopped(const struct net_device *dev) { return test_bit(__LINK_STATE_XOFF, &dev->state); } +/** + * netif_running - test if up + * @dev: network device + * + * Test if the device has been brought up. + */ static inline int netif_running(const struct net_device *dev) { return test_bit(__LINK_STATE_START, &dev->state); @@ -742,6 +898,14 @@ static inline int netif_running(const struct net_device *dev) * done at the overall netdevice level. * Also test the device if we're multiqueue. */ + +/** + * netif_start_subqueue - allow sending packets on subqueue + * @dev: network device + * @queue_index: sub queue index + * + * Start individual transmit queue of a device with multiple transmit queues. + */ static inline void netif_start_subqueue(struct net_device *dev, u16 queue_index) { #ifdef CONFIG_NETDEVICES_MULTIQUEUE @@ -749,6 +913,13 @@ static inline void netif_start_subqueue(struct net_device *dev, u16 queue_index) #endif } +/** + * netif_stop_subqueue - stop sending packets on subqueue + * @dev: network device + * @queue_index: sub queue index + * + * Stop individual transmit queue of a device with multiple transmit queues. + */ static inline void netif_stop_subqueue(struct net_device *dev, u16 queue_index) { #ifdef CONFIG_NETDEVICES_MULTIQUEUE @@ -760,6 +931,13 @@ static inline void netif_stop_subqueue(struct net_device *dev, u16 queue_index) #endif } +/** + * netif_subqueue_stopped - test status of subqueue + * @dev: network device + * @queue_index: sub queue index + * + * Check individual transmit queue of a device with multiple transmit queues. + */ static inline int netif_subqueue_stopped(const struct net_device *dev, u16 queue_index) { @@ -771,6 +949,14 @@ static inline int netif_subqueue_stopped(const struct net_device *dev, #endif } + +/** + * netif_wake_subqueue - allow sending packets on subqueue + * @dev: network device + * @queue_index: sub queue index + * + * Resume individual transmit queue of a device with multiple transmit queues. + */ static inline void netif_wake_subqueue(struct net_device *dev, u16 queue_index) { #ifdef CONFIG_NETDEVICES_MULTIQUEUE @@ -784,6 +970,13 @@ static inline void netif_wake_subqueue(struct net_device *dev, u16 queue_index) #endif } +/** + * netif_is_multiqueue - test if device has multiple transmit queues + * @dev: network device + * + * Check if device has multiple transmit queues + * Always falls if NETDEVICE_MULTIQUEUE is not configured + */ static inline int netif_is_multiqueue(const struct net_device *dev) { #ifdef CONFIG_NETDEVICES_MULTIQUEUE @@ -796,20 +989,7 @@ static inline int netif_is_multiqueue(const struct net_device *dev) /* Use this variant when it is known for sure that it * is executing from interrupt context. */ -static inline void dev_kfree_skb_irq(struct sk_buff *skb) -{ - if (atomic_dec_and_test(&skb->users)) { - struct softnet_data *sd; - unsigned long flags; - - local_irq_save(flags); - sd = &__get_cpu_var(softnet_data); - skb->next = sd->completion_queue; - sd->completion_queue = skb; - raise_softirq_irqoff(NET_TX_SOFTIRQ); - local_irq_restore(flags); - } -} +extern void dev_kfree_skb_irq(struct sk_buff *skb); /* Use this variant in places where it could be invoked * either from interrupt or non-interrupt context. @@ -833,18 +1013,28 @@ extern int dev_set_mac_address(struct net_device *, extern int dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev); -extern void dev_init(void); - extern int netdev_budget; /* Called by rtnetlink.c:rtnl_unlock() */ extern void netdev_run_todo(void); +/** + * dev_put - release reference to device + * @dev: network device + * + * Hold reference to device to keep it from being freed. + */ static inline void dev_put(struct net_device *dev) { atomic_dec(&dev->refcnt); } +/** + * dev_hold - get reference to device + * @dev: network device + * + * Release reference to device to allow it to be freed. + */ static inline void dev_hold(struct net_device *dev) { atomic_inc(&dev->refcnt); @@ -861,6 +1051,12 @@ static inline void dev_hold(struct net_device *dev) extern void linkwatch_fire_event(struct net_device *dev); +/** + * netif_carrier_ok - test if carrier present + * @dev: network device + * + * Check if carrier is present on device + */ static inline int netif_carrier_ok(const struct net_device *dev) { return !test_bit(__LINK_STATE_NOCARRIER, &dev->state); @@ -872,30 +1068,66 @@ extern void netif_carrier_on(struct net_device *dev); extern void netif_carrier_off(struct net_device *dev); +/** + * netif_dormant_on - mark device as dormant. + * @dev: network device + * + * Mark device as dormant (as per RFC2863). + * + * The dormant state indicates that the relevant interface is not + * actually in a condition to pass packets (i.e., it is not 'up') but is + * in a "pending" state, waiting for some external event. For "on- + * demand" interfaces, this new state identifies the situation where the + * interface is waiting for events to place it in the up state. + * + */ static inline void netif_dormant_on(struct net_device *dev) { if (!test_and_set_bit(__LINK_STATE_DORMANT, &dev->state)) linkwatch_fire_event(dev); } +/** + * netif_dormant_off - set device as not dormant. + * @dev: network device + * + * Device is not in dormant state. + */ static inline void netif_dormant_off(struct net_device *dev) { if (test_and_clear_bit(__LINK_STATE_DORMANT, &dev->state)) linkwatch_fire_event(dev); } +/** + * netif_dormant - test if carrier present + * @dev: network device + * + * Check if carrier is present on device + */ static inline int netif_dormant(const struct net_device *dev) { return test_bit(__LINK_STATE_DORMANT, &dev->state); } +/** + * netif_oper_up - test if device is operational + * @dev: network device + * + * Check if carrier is operational + */ static inline int netif_oper_up(const struct net_device *dev) { return (dev->operstate == IF_OPER_UP || dev->operstate == IF_OPER_UNKNOWN /* backward compat */); } -/* Hot-plugging. */ +/** + * netif_device_present - is device available or removed + * @dev: network device + * + * Check if device has not been removed from system. + */ static inline int netif_device_present(struct net_device *dev) { return test_bit(__LINK_STATE_PRESENT, &dev->state); @@ -955,46 +1187,38 @@ static inline u32 netif_msg_init(int debug_value, int default_msg_enable_bits) return (1 << debug_value) - 1; } -/* Test if receive needs to be scheduled */ -static inline int __netif_rx_schedule_prep(struct net_device *dev) -{ - return !test_and_set_bit(__LINK_STATE_RX_SCHED, &dev->state); -} - /* Test if receive needs to be scheduled but only if up */ -static inline int netif_rx_schedule_prep(struct net_device *dev) +static inline int netif_rx_schedule_prep(struct net_device *dev, + struct napi_struct *napi) { - return netif_running(dev) && __netif_rx_schedule_prep(dev); + return netif_running(dev) && napi_schedule_prep(napi); } /* Add interface to tail of rx poll list. This assumes that _prep has * already been called and returned 1. */ - -extern void __netif_rx_schedule(struct net_device *dev); +static inline void __netif_rx_schedule(struct net_device *dev, + struct napi_struct *napi) +{ + dev_hold(dev); + __napi_schedule(napi); +} /* Try to reschedule poll. Called by irq handler. */ -static inline void netif_rx_schedule(struct net_device *dev) +static inline void netif_rx_schedule(struct net_device *dev, + struct napi_struct *napi) { - if (netif_rx_schedule_prep(dev)) - __netif_rx_schedule(dev); + if (netif_rx_schedule_prep(dev, napi)) + __netif_rx_schedule(dev, napi); } -/* Try to reschedule poll. Called by dev->poll() after netif_rx_complete(). - * Do not inline this? - */ -static inline int netif_rx_reschedule(struct net_device *dev, int undo) +/* Try to reschedule poll. Called by dev->poll() after netif_rx_complete(). */ +static inline int netif_rx_reschedule(struct net_device *dev, + struct napi_struct *napi) { - if (netif_rx_schedule_prep(dev)) { - unsigned long flags; - - dev->quota += undo; - - local_irq_save(flags); - list_add_tail(&dev->poll_list, &__get_cpu_var(softnet_data).poll_list); - __raise_softirq_irqoff(NET_RX_SOFTIRQ); - local_irq_restore(flags); + if (napi_schedule_prep(napi)) { + __netif_rx_schedule(dev, napi); return 1; } return 0; @@ -1003,12 +1227,11 @@ static inline int netif_rx_reschedule(struct net_device *dev, int undo) /* same as netif_rx_complete, except that local_irq_save(flags) * has already been issued */ -static inline void __netif_rx_complete(struct net_device *dev) +static inline void __netif_rx_complete(struct net_device *dev, + struct napi_struct *napi) { - BUG_ON(!test_bit(__LINK_STATE_RX_SCHED, &dev->state)); - list_del(&dev->poll_list); - smp_mb__before_clear_bit(); - clear_bit(__LINK_STATE_RX_SCHED, &dev->state); + __napi_complete(napi); + dev_put(dev); } /* Remove interface from poll list: it must be in the poll list @@ -1016,28 +1239,22 @@ static inline void __netif_rx_complete(struct net_device *dev) * it completes the work. The device cannot be out of poll list at this * moment, it is BUG(). */ -static inline void netif_rx_complete(struct net_device *dev) +static inline void netif_rx_complete(struct net_device *dev, + struct napi_struct *napi) { unsigned long flags; local_irq_save(flags); - __netif_rx_complete(dev); + __netif_rx_complete(dev, napi); local_irq_restore(flags); } -static inline void netif_poll_disable(struct net_device *dev) -{ - while (test_and_set_bit(__LINK_STATE_RX_SCHED, &dev->state)) - /* No hurry. */ - schedule_timeout_interruptible(1); -} - -static inline void netif_poll_enable(struct net_device *dev) -{ - smp_mb__before_clear_bit(); - clear_bit(__LINK_STATE_RX_SCHED, &dev->state); -} - +/** + * netif_tx_lock - grab network device transmit lock + * @dev: network device + * + * Get network device transmit lock + */ static inline void netif_tx_lock(struct net_device *dev) { spin_lock(&dev->_xmit_lock); diff --git a/include/linux/netpoll.h b/include/linux/netpoll.h index 29930b71a9aa..08dcc39ec18d 100644 --- a/include/linux/netpoll.h +++ b/include/linux/netpoll.h @@ -25,8 +25,6 @@ struct netpoll { struct netpoll_info { atomic_t refcnt; - spinlock_t poll_lock; - int poll_owner; int rx_flags; spinlock_t rx_lock; struct netpoll *rx_np; /* netpoll that registered an rx_hook */ @@ -64,32 +62,61 @@ static inline int netpoll_rx(struct sk_buff *skb) return ret; } -static inline void *netpoll_poll_lock(struct net_device *dev) +static inline int netpoll_receive_skb(struct sk_buff *skb) { + if (!list_empty(&skb->dev->napi_list)) + return netpoll_rx(skb); + return 0; +} + +static inline void *netpoll_poll_lock(struct napi_struct *napi) +{ + struct net_device *dev = napi->dev; + rcu_read_lock(); /* deal with race on ->npinfo */ - if (dev->npinfo) { - spin_lock(&dev->npinfo->poll_lock); - dev->npinfo->poll_owner = smp_processor_id(); - return dev->npinfo; + if (dev && dev->npinfo) { + spin_lock(&napi->poll_lock); + napi->poll_owner = smp_processor_id(); + return napi; } return NULL; } static inline void netpoll_poll_unlock(void *have) { - struct netpoll_info *npi = have; + struct napi_struct *napi = have; - if (npi) { - npi->poll_owner = -1; - spin_unlock(&npi->poll_lock); + if (napi) { + napi->poll_owner = -1; + spin_unlock(&napi->poll_lock); } rcu_read_unlock(); } +static inline void netpoll_netdev_init(struct net_device *dev) +{ + INIT_LIST_HEAD(&dev->napi_list); +} + #else -#define netpoll_rx(a) 0 -#define netpoll_poll_lock(a) NULL -#define netpoll_poll_unlock(a) +static inline int netpoll_rx(struct sk_buff *skb) +{ + return 0; +} +static inline int netpoll_receive_skb(struct sk_buff *skb) +{ + return 0; +} +static inline void *netpoll_poll_lock(struct napi_struct *napi) +{ + return NULL; +} +static inline void netpoll_poll_unlock(void *have) +{ +} +static inline void netpoll_netdev_init(struct net_device *dev) +{ +} #endif #endif -- cgit v1.2.3 From 71c87e0cedca843162206c698cfa02e5fea9e2e3 Mon Sep 17 00:00:00 2001 From: Jan-Bernd Themann Date: Wed, 8 Aug 2007 22:38:05 -0700 Subject: [NET]: Generic Large Receive Offload for TCP traffic This patch provides generic Large Receive Offload (LRO) functionality for IPv4/TCP traffic. LRO combines received tcp packets to a single larger tcp packet and passes them then to the network stack in order to increase performance (throughput). The interface supports two modes: Drivers can either pass SKBs or fragment lists to the LRO engine. Signed-off-by: Jan-Bernd Themann Signed-off-by: David S. Miller --- include/linux/inet_lro.h | 177 ++++++++++++++ net/ipv4/Kconfig | 8 + net/ipv4/Makefile | 1 + net/ipv4/inet_lro.c | 600 +++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 786 insertions(+) create mode 100644 include/linux/inet_lro.h create mode 100644 net/ipv4/inet_lro.c (limited to 'include/linux') diff --git a/include/linux/inet_lro.h b/include/linux/inet_lro.h new file mode 100644 index 000000000000..e1fc1d16d3cd --- /dev/null +++ b/include/linux/inet_lro.h @@ -0,0 +1,177 @@ +/* + * linux/include/linux/inet_lro.h + * + * Large Receive Offload (ipv4 / tcp) + * + * (C) Copyright IBM Corp. 2007 + * + * Authors: + * Jan-Bernd Themann + * Christoph Raisch + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef __INET_LRO_H_ +#define __INET_LRO_H_ + +#include +#include + +/* + * LRO statistics + */ + +struct net_lro_stats { + unsigned long aggregated; + unsigned long flushed; + unsigned long no_desc; +}; + +/* + * LRO descriptor for a tcp session + */ +struct net_lro_desc { + struct sk_buff *parent; + struct sk_buff *last_skb; + struct skb_frag_struct *next_frag; + struct iphdr *iph; + struct tcphdr *tcph; + struct vlan_group *vgrp; + __wsum data_csum; + u32 tcp_rcv_tsecr; + u32 tcp_rcv_tsval; + u32 tcp_ack; + u32 tcp_next_seq; + u32 skb_tot_frags_len; + u16 ip_tot_len; + u16 tcp_saw_tstamp; /* timestamps enabled */ + u16 tcp_window; + u16 vlan_tag; + int pkt_aggr_cnt; /* counts aggregated packets */ + int vlan_packet; + int mss; + int active; +}; + +/* + * Large Receive Offload (LRO) Manager + * + * Fields must be set by driver + */ + +struct net_lro_mgr { + struct net_device *dev; + struct net_lro_stats stats; + + /* LRO features */ + unsigned long features; +#define LRO_F_NAPI 1 /* Pass packets to stack via NAPI */ +#define LRO_F_EXTRACT_VLAN_ID 2 /* Set flag if VLAN IDs are extracted + from received packets and eth protocol + is still ETH_P_8021Q */ + + u32 ip_summed; /* Set in non generated SKBs in page mode */ + u32 ip_summed_aggr; /* Set in aggregated SKBs: CHECKSUM_UNNECESSARY + * or CHECKSUM_NONE */ + + int max_desc; /* Max number of LRO descriptors */ + int max_aggr; /* Max number of LRO packets to be aggregated */ + + struct net_lro_desc *lro_arr; /* Array of LRO descriptors */ + + /* + * Optimized driver functions + * + * get_skb_header: returns tcp and ip header for packet in SKB + */ + int (*get_skb_header)(struct sk_buff *skb, void **ip_hdr, + void **tcpudp_hdr, u64 *hdr_flags, void *priv); + + /* hdr_flags: */ +#define LRO_IPV4 1 /* ip_hdr is IPv4 header */ +#define LRO_TCP 2 /* tcpudp_hdr is TCP header */ + + /* + * get_frag_header: returns mac, tcp and ip header for packet in SKB + * + * @hdr_flags: Indicate what kind of LRO has to be done + * (IPv4/IPv6/TCP/UDP) + */ + int (*get_frag_header)(struct skb_frag_struct *frag, void **mac_hdr, + void **ip_hdr, void **tcpudp_hdr, u64 *hdr_flags, + void *priv); +}; + +/* + * Processes a SKB + * + * @lro_mgr: LRO manager to use + * @skb: SKB to aggregate + * @priv: Private data that may be used by driver functions + * (for example get_tcp_ip_hdr) + */ + +void lro_receive_skb(struct net_lro_mgr *lro_mgr, + struct sk_buff *skb, + void *priv); + +/* + * Processes a SKB with VLAN HW acceleration support + */ + +void lro_vlan_hwaccel_receive_skb(struct net_lro_mgr *lro_mgr, + struct sk_buff *skb, + struct vlan_group *vgrp, + u16 vlan_tag, + void *priv); + +/* + * Processes a fragment list + * + * This functions aggregate fragments and generate SKBs do pass + * the packets to the stack. + * + * @lro_mgr: LRO manager to use + * @frags: Fragment to be processed. Must contain entire header in first + * element. + * @len: Length of received data + * @true_size: Actual size of memory the fragment is consuming + * @priv: Private data that may be used by driver functions + * (for example get_tcp_ip_hdr) + */ + +void lro_receive_frags(struct net_lro_mgr *lro_mgr, + struct skb_frag_struct *frags, + int len, int true_size, void *priv, __wsum sum); + +void lro_vlan_hwaccel_receive_frags(struct net_lro_mgr *lro_mgr, + struct skb_frag_struct *frags, + int len, int true_size, + struct vlan_group *vgrp, + u16 vlan_tag, + void *priv, __wsum sum); + +/* + * Forward all aggregated SKBs held by lro_mgr to network stack + */ + +void lro_flush_all(struct net_lro_mgr *lro_mgr); + +void lro_flush_pkt(struct net_lro_mgr *lro_mgr, + struct iphdr *iph, struct tcphdr *tcph); + +#endif diff --git a/net/ipv4/Kconfig b/net/ipv4/Kconfig index fb7909774254..d894f616c3d6 100644 --- a/net/ipv4/Kconfig +++ b/net/ipv4/Kconfig @@ -394,6 +394,14 @@ config INET_XFRM_MODE_BEET If unsure, say Y. +config INET_LRO + tristate "Large Receive Offload (ipv4/tcp)" + + ---help--- + Support for Large Receive Offload (ipv4/tcp). + + If unsure, say Y. + config INET_DIAG tristate "INET: socket monitoring interface" default y diff --git a/net/ipv4/Makefile b/net/ipv4/Makefile index fbf1674e0c2a..a02c36d0a13e 100644 --- a/net/ipv4/Makefile +++ b/net/ipv4/Makefile @@ -25,6 +25,7 @@ obj-$(CONFIG_INET_ESP) += esp4.o obj-$(CONFIG_INET_IPCOMP) += ipcomp.o obj-$(CONFIG_INET_XFRM_TUNNEL) += xfrm4_tunnel.o obj-$(CONFIG_INET_XFRM_MODE_BEET) += xfrm4_mode_beet.o +obj-$(CONFIG_INET_LRO) += inet_lro.o obj-$(CONFIG_INET_TUNNEL) += tunnel4.o obj-$(CONFIG_INET_XFRM_MODE_TRANSPORT) += xfrm4_mode_transport.o obj-$(CONFIG_INET_XFRM_MODE_TUNNEL) += xfrm4_mode_tunnel.o diff --git a/net/ipv4/inet_lro.c b/net/ipv4/inet_lro.c new file mode 100644 index 000000000000..20bc593bb963 --- /dev/null +++ b/net/ipv4/inet_lro.c @@ -0,0 +1,600 @@ +/* + * linux/net/ipv4/inet_lro.c + * + * Large Receive Offload (ipv4 / tcp) + * + * (C) Copyright IBM Corp. 2007 + * + * Authors: + * Jan-Bernd Themann + * Christoph Raisch + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + + +#include +#include +#include + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Jan-Bernd Themann "); +MODULE_DESCRIPTION("Large Receive Offload (ipv4 / tcp)"); + +#define TCP_HDR_LEN(tcph) (tcph->doff << 2) +#define IP_HDR_LEN(iph) (iph->ihl << 2) +#define TCP_PAYLOAD_LENGTH(iph, tcph) \ + (ntohs(iph->tot_len) - IP_HDR_LEN(iph) - TCP_HDR_LEN(tcph)) + +#define IPH_LEN_WO_OPTIONS 5 +#define TCPH_LEN_WO_OPTIONS 5 +#define TCPH_LEN_W_TIMESTAMP 8 + +#define LRO_MAX_PG_HLEN 64 + +#define LRO_INC_STATS(lro_mgr, attr) { lro_mgr->stats.attr++; } + +/* + * Basic tcp checks whether packet is suitable for LRO + */ + +static int lro_tcp_ip_check(struct iphdr *iph, struct tcphdr *tcph, + int len, struct net_lro_desc *lro_desc) +{ + /* check ip header: don't aggregate padded frames */ + if (ntohs(iph->tot_len) != len) + return -1; + + if (TCP_PAYLOAD_LENGTH(iph, tcph) == 0) + return -1; + + if (iph->ihl != IPH_LEN_WO_OPTIONS) + return -1; + + if (tcph->cwr || tcph->ece || tcph->urg || !tcph->ack + || tcph->rst || tcph->syn || tcph->fin) + return -1; + + if (INET_ECN_is_ce(ipv4_get_dsfield(iph))) + return -1; + + if (tcph->doff != TCPH_LEN_WO_OPTIONS + && tcph->doff != TCPH_LEN_W_TIMESTAMP) + return -1; + + /* check tcp options (only timestamp allowed) */ + if (tcph->doff == TCPH_LEN_W_TIMESTAMP) { + u32 *topt = (u32 *)(tcph + 1); + + if (*topt != htonl((TCPOPT_NOP << 24) | (TCPOPT_NOP << 16) + | (TCPOPT_TIMESTAMP << 8) + | TCPOLEN_TIMESTAMP)) + return -1; + + /* timestamp should be in right order */ + topt++; + if (lro_desc && after(ntohl(lro_desc->tcp_rcv_tsval), + ntohl(*topt))) + return -1; + + /* timestamp reply should not be zero */ + topt++; + if (*topt == 0) + return -1; + } + + return 0; +} + +static void lro_update_tcp_ip_header(struct net_lro_desc *lro_desc) +{ + struct iphdr *iph = lro_desc->iph; + struct tcphdr *tcph = lro_desc->tcph; + u32 *p; + __wsum tcp_hdr_csum; + + tcph->ack_seq = lro_desc->tcp_ack; + tcph->window = lro_desc->tcp_window; + + if (lro_desc->tcp_saw_tstamp) { + p = (u32 *)(tcph + 1); + *(p+2) = lro_desc->tcp_rcv_tsecr; + } + + iph->tot_len = htons(lro_desc->ip_tot_len); + + iph->check = 0; + iph->check = ip_fast_csum((u8 *)lro_desc->iph, iph->ihl); + + tcph->check = 0; + tcp_hdr_csum = csum_partial((u8 *)tcph, TCP_HDR_LEN(tcph), 0); + lro_desc->data_csum = csum_add(lro_desc->data_csum, tcp_hdr_csum); + tcph->check = csum_tcpudp_magic(iph->saddr, iph->daddr, + lro_desc->ip_tot_len - + IP_HDR_LEN(iph), IPPROTO_TCP, + lro_desc->data_csum); +} + +static __wsum lro_tcp_data_csum(struct iphdr *iph, struct tcphdr *tcph, int len) +{ + __wsum tcp_csum; + __wsum tcp_hdr_csum; + __wsum tcp_ps_hdr_csum; + + tcp_csum = ~csum_unfold(tcph->check); + tcp_hdr_csum = csum_partial((u8 *)tcph, TCP_HDR_LEN(tcph), tcp_csum); + + tcp_ps_hdr_csum = csum_tcpudp_nofold(iph->saddr, iph->daddr, + len + TCP_HDR_LEN(tcph), + IPPROTO_TCP, 0); + + return csum_sub(csum_sub(tcp_csum, tcp_hdr_csum), + tcp_ps_hdr_csum); +} + +static void lro_init_desc(struct net_lro_desc *lro_desc, struct sk_buff *skb, + struct iphdr *iph, struct tcphdr *tcph, + u16 vlan_tag, struct vlan_group *vgrp) +{ + int nr_frags; + u32 *ptr; + u32 tcp_data_len = TCP_PAYLOAD_LENGTH(iph, tcph); + + nr_frags = skb_shinfo(skb)->nr_frags; + lro_desc->parent = skb; + lro_desc->next_frag = &(skb_shinfo(skb)->frags[nr_frags]); + lro_desc->iph = iph; + lro_desc->tcph = tcph; + lro_desc->tcp_next_seq = ntohl(tcph->seq) + tcp_data_len; + lro_desc->tcp_ack = ntohl(tcph->ack_seq); + lro_desc->tcp_window = tcph->window; + + lro_desc->pkt_aggr_cnt = 1; + lro_desc->ip_tot_len = ntohs(iph->tot_len); + + if (tcph->doff == 8) { + ptr = (u32 *)(tcph+1); + lro_desc->tcp_saw_tstamp = 1; + lro_desc->tcp_rcv_tsval = *(ptr+1); + lro_desc->tcp_rcv_tsecr = *(ptr+2); + } + + lro_desc->mss = tcp_data_len; + lro_desc->vgrp = vgrp; + lro_desc->vlan_tag = vlan_tag; + lro_desc->active = 1; + + lro_desc->data_csum = lro_tcp_data_csum(iph, tcph, + tcp_data_len); +} + +static inline void lro_clear_desc(struct net_lro_desc *lro_desc) +{ + memset(lro_desc, 0, sizeof(struct net_lro_desc)); +} + +static void lro_add_common(struct net_lro_desc *lro_desc, struct iphdr *iph, + struct tcphdr *tcph, int tcp_data_len) +{ + struct sk_buff *parent = lro_desc->parent; + u32 *topt; + + lro_desc->pkt_aggr_cnt++; + lro_desc->ip_tot_len += tcp_data_len; + lro_desc->tcp_next_seq += tcp_data_len; + lro_desc->tcp_window = tcph->window; + lro_desc->tcp_ack = tcph->ack_seq; + + /* don't update tcp_rcv_tsval, would not work with PAWS */ + if (lro_desc->tcp_saw_tstamp) { + topt = (u32 *) (tcph + 1); + lro_desc->tcp_rcv_tsecr = *(topt + 2); + } + + lro_desc->data_csum = csum_block_add(lro_desc->data_csum, + lro_tcp_data_csum(iph, tcph, + tcp_data_len), + parent->len); + + parent->len += tcp_data_len; + parent->data_len += tcp_data_len; + if (tcp_data_len > lro_desc->mss) + lro_desc->mss = tcp_data_len; +} + +static void lro_add_packet(struct net_lro_desc *lro_desc, struct sk_buff *skb, + struct iphdr *iph, struct tcphdr *tcph) +{ + struct sk_buff *parent = lro_desc->parent; + int tcp_data_len = TCP_PAYLOAD_LENGTH(iph, tcph); + + lro_add_common(lro_desc, iph, tcph, tcp_data_len); + + skb_pull(skb, (skb->len - tcp_data_len)); + parent->truesize += skb->truesize; + + if (lro_desc->last_skb) + lro_desc->last_skb->next = skb; + else + skb_shinfo(parent)->frag_list = skb; + + lro_desc->last_skb = skb; +} + +static void lro_add_frags(struct net_lro_desc *lro_desc, + int len, int hlen, int truesize, + struct skb_frag_struct *skb_frags, + struct iphdr *iph, struct tcphdr *tcph) +{ + struct sk_buff *skb = lro_desc->parent; + int tcp_data_len = TCP_PAYLOAD_LENGTH(iph, tcph); + + lro_add_common(lro_desc, iph, tcph, tcp_data_len); + + skb->truesize += truesize; + + skb_frags[0].page_offset += hlen; + skb_frags[0].size -= hlen; + + while (tcp_data_len > 0) { + *(lro_desc->next_frag) = *skb_frags; + tcp_data_len -= skb_frags->size; + lro_desc->next_frag++; + skb_frags++; + skb_shinfo(skb)->nr_frags++; + } +} + +static int lro_check_tcp_conn(struct net_lro_desc *lro_desc, + struct iphdr *iph, + struct tcphdr *tcph) +{ + if ((lro_desc->iph->saddr != iph->saddr) + || (lro_desc->iph->daddr != iph->daddr) + || (lro_desc->tcph->source != tcph->source) + || (lro_desc->tcph->dest != tcph->dest)) + return -1; + return 0; +} + +static struct net_lro_desc *lro_get_desc(struct net_lro_mgr *lro_mgr, + struct net_lro_desc *lro_arr, + struct iphdr *iph, + struct tcphdr *tcph) +{ + struct net_lro_desc *lro_desc = NULL; + struct net_lro_desc *tmp; + int max_desc = lro_mgr->max_desc; + int i; + + for (i = 0; i < max_desc; i++) { + tmp = &lro_arr[i]; + if (tmp->active) + if (!lro_check_tcp_conn(tmp, iph, tcph)) { + lro_desc = tmp; + goto out; + } + } + + for (i = 0; i < max_desc; i++) { + if (!lro_arr[i].active) { + lro_desc = &lro_arr[i]; + goto out; + } + } + + LRO_INC_STATS(lro_mgr, no_desc); +out: + return lro_desc; +} + +static void lro_flush(struct net_lro_mgr *lro_mgr, + struct net_lro_desc *lro_desc) +{ + if (lro_desc->pkt_aggr_cnt > 1) + lro_update_tcp_ip_header(lro_desc); + + skb_shinfo(lro_desc->parent)->gso_size = lro_desc->mss; + + if (lro_desc->vgrp) { + if (test_bit(LRO_F_NAPI, &lro_mgr->features)) + vlan_hwaccel_receive_skb(lro_desc->parent, + lro_desc->vgrp, + lro_desc->vlan_tag); + else + vlan_hwaccel_rx(lro_desc->parent, + lro_desc->vgrp, + lro_desc->vlan_tag); + + } else { + if (test_bit(LRO_F_NAPI, &lro_mgr->features)) + netif_receive_skb(lro_desc->parent); + else + netif_rx(lro_desc->parent); + } + + LRO_INC_STATS(lro_mgr, flushed); + lro_clear_desc(lro_desc); +} + +static int __lro_proc_skb(struct net_lro_mgr *lro_mgr, struct sk_buff *skb, + struct vlan_group *vgrp, u16 vlan_tag, void *priv) +{ + struct net_lro_desc *lro_desc; + struct iphdr *iph; + struct tcphdr *tcph; + u64 flags; + int vlan_hdr_len = 0; + + if (!lro_mgr->get_skb_header + || lro_mgr->get_skb_header(skb, (void *)&iph, (void *)&tcph, + &flags, priv)) + goto out; + + if (!(flags & LRO_IPV4) || !(flags & LRO_TCP)) + goto out; + + lro_desc = lro_get_desc(lro_mgr, lro_mgr->lro_arr, iph, tcph); + if (!lro_desc) + goto out; + + if ((skb->protocol == htons(ETH_P_8021Q)) + && !test_bit(LRO_F_EXTRACT_VLAN_ID, &lro_mgr->features)) + vlan_hdr_len = VLAN_HLEN; + + if (!lro_desc->active) { /* start new lro session */ + if (lro_tcp_ip_check(iph, tcph, skb->len - vlan_hdr_len, NULL)) + goto out; + + skb->ip_summed = lro_mgr->ip_summed_aggr; + lro_init_desc(lro_desc, skb, iph, tcph, vlan_tag, vgrp); + LRO_INC_STATS(lro_mgr, aggregated); + return 0; + } + + if (lro_desc->tcp_next_seq != ntohl(tcph->seq)) + goto out2; + + if (lro_tcp_ip_check(iph, tcph, skb->len, lro_desc)) + goto out2; + + lro_add_packet(lro_desc, skb, iph, tcph); + LRO_INC_STATS(lro_mgr, aggregated); + + if ((lro_desc->pkt_aggr_cnt >= lro_mgr->max_aggr) || + lro_desc->parent->len > (0xFFFF - lro_mgr->dev->mtu)) + lro_flush(lro_mgr, lro_desc); + + return 0; + +out2: /* send aggregated SKBs to stack */ + lro_flush(lro_mgr, lro_desc); + +out: /* Original SKB has to be posted to stack */ + skb->ip_summed = lro_mgr->ip_summed; + return 1; +} + + +static struct sk_buff *lro_gen_skb(struct net_lro_mgr *lro_mgr, + struct skb_frag_struct *frags, + int len, int true_size, + void *mac_hdr, + int hlen, __wsum sum, + u32 ip_summed) +{ + struct sk_buff *skb; + struct skb_frag_struct *skb_frags; + int data_len = len; + int hdr_len = min(len, hlen); + + skb = netdev_alloc_skb(lro_mgr->dev, hlen); + if (!skb) + return NULL; + + skb->len = len; + skb->data_len = len - hdr_len; + skb->truesize += true_size; + skb->tail += hdr_len; + + memcpy(skb->data, mac_hdr, hdr_len); + + skb_frags = skb_shinfo(skb)->frags; + while (data_len > 0) { + *skb_frags = *frags; + data_len -= frags->size; + skb_frags++; + frags++; + skb_shinfo(skb)->nr_frags++; + } + + skb_shinfo(skb)->frags[0].page_offset += hdr_len; + skb_shinfo(skb)->frags[0].size -= hdr_len; + + skb->ip_summed = ip_summed; + skb->csum = sum; + skb->protocol = eth_type_trans(skb, lro_mgr->dev); + return skb; +} + +static struct sk_buff *__lro_proc_segment(struct net_lro_mgr *lro_mgr, + struct skb_frag_struct *frags, + int len, int true_size, + struct vlan_group *vgrp, + u16 vlan_tag, void *priv, __wsum sum) +{ + struct net_lro_desc *lro_desc; + struct iphdr *iph; + struct tcphdr *tcph; + struct sk_buff *skb; + u64 flags; + void *mac_hdr; + int mac_hdr_len; + int hdr_len = LRO_MAX_PG_HLEN; + int vlan_hdr_len = 0; + + if (!lro_mgr->get_frag_header + || lro_mgr->get_frag_header(frags, (void *)&mac_hdr, (void *)&iph, + (void *)&tcph, &flags, priv)) { + mac_hdr = page_address(frags->page) + frags->page_offset; + goto out1; + } + + if (!(flags & LRO_IPV4) || !(flags & LRO_TCP)) + goto out1; + + hdr_len = (int)((void *)(tcph) + TCP_HDR_LEN(tcph) - mac_hdr); + mac_hdr_len = (int)((void *)(iph) - mac_hdr); + + lro_desc = lro_get_desc(lro_mgr, lro_mgr->lro_arr, iph, tcph); + if (!lro_desc) + goto out1; + + if (!lro_desc->active) { /* start new lro session */ + if (lro_tcp_ip_check(iph, tcph, len - mac_hdr_len, NULL)) + goto out1; + + skb = lro_gen_skb(lro_mgr, frags, len, true_size, mac_hdr, + hdr_len, 0, lro_mgr->ip_summed_aggr); + if (!skb) + goto out; + + if ((skb->protocol == htons(ETH_P_8021Q)) + && !test_bit(LRO_F_EXTRACT_VLAN_ID, &lro_mgr->features)) + vlan_hdr_len = VLAN_HLEN; + + iph = (void *)(skb->data + vlan_hdr_len); + tcph = (void *)((u8 *)skb->data + vlan_hdr_len + + IP_HDR_LEN(iph)); + + lro_init_desc(lro_desc, skb, iph, tcph, 0, NULL); + LRO_INC_STATS(lro_mgr, aggregated); + return 0; + } + + if (lro_desc->tcp_next_seq != ntohl(tcph->seq)) + goto out2; + + if (lro_tcp_ip_check(iph, tcph, len - mac_hdr_len, lro_desc)) + goto out2; + + lro_add_frags(lro_desc, len, hdr_len, true_size, frags, iph, tcph); + LRO_INC_STATS(lro_mgr, aggregated); + + if ((skb_shinfo(lro_desc->parent)->nr_frags >= lro_mgr->max_aggr) || + lro_desc->parent->len > (0xFFFF - lro_mgr->dev->mtu)) + lro_flush(lro_mgr, lro_desc); + + return NULL; + +out2: /* send aggregated packets to the stack */ + lro_flush(lro_mgr, lro_desc); + +out1: /* Original packet has to be posted to the stack */ + skb = lro_gen_skb(lro_mgr, frags, len, true_size, mac_hdr, + hdr_len, sum, lro_mgr->ip_summed); +out: + return skb; +} + +void lro_receive_skb(struct net_lro_mgr *lro_mgr, + struct sk_buff *skb, + void *priv) +{ + if (__lro_proc_skb(lro_mgr, skb, NULL, 0, priv)) { + if (test_bit(LRO_F_NAPI, &lro_mgr->features)) + netif_receive_skb(skb); + else + netif_rx(skb); + } +} +EXPORT_SYMBOL(lro_receive_skb); + +void lro_vlan_hwaccel_receive_skb(struct net_lro_mgr *lro_mgr, + struct sk_buff *skb, + struct vlan_group *vgrp, + u16 vlan_tag, + void *priv) +{ + if (__lro_proc_skb(lro_mgr, skb, vgrp, vlan_tag, priv)) { + if (test_bit(LRO_F_NAPI, &lro_mgr->features)) + vlan_hwaccel_receive_skb(skb, vgrp, vlan_tag); + else + vlan_hwaccel_rx(skb, vgrp, vlan_tag); + } +} +EXPORT_SYMBOL(lro_vlan_hwaccel_receive_skb); + +void lro_receive_frags(struct net_lro_mgr *lro_mgr, + struct skb_frag_struct *frags, + int len, int true_size, void *priv, __wsum sum) +{ + struct sk_buff *skb; + + skb = __lro_proc_segment(lro_mgr, frags, len, true_size, NULL, 0, + priv, sum); + if (!skb) + return; + + if (test_bit(LRO_F_NAPI, &lro_mgr->features)) + netif_receive_skb(skb); + else + netif_rx(skb); +} +EXPORT_SYMBOL(lro_receive_frags); + +void lro_vlan_hwaccel_receive_frags(struct net_lro_mgr *lro_mgr, + struct skb_frag_struct *frags, + int len, int true_size, + struct vlan_group *vgrp, + u16 vlan_tag, void *priv, __wsum sum) +{ + struct sk_buff *skb; + + skb = __lro_proc_segment(lro_mgr, frags, len, true_size, vgrp, + vlan_tag, priv, sum); + if (!skb) + return; + + if (test_bit(LRO_F_NAPI, &lro_mgr->features)) + vlan_hwaccel_receive_skb(skb, vgrp, vlan_tag); + else + vlan_hwaccel_rx(skb, vgrp, vlan_tag); +} +EXPORT_SYMBOL(lro_vlan_hwaccel_receive_frags); + +void lro_flush_all(struct net_lro_mgr *lro_mgr) +{ + int i; + struct net_lro_desc *lro_desc = lro_mgr->lro_arr; + + for (i = 0; i < lro_mgr->max_desc; i++) { + if (lro_desc[i].active) + lro_flush(lro_mgr, &lro_desc[i]); + } +} +EXPORT_SYMBOL(lro_flush_all); + +void lro_flush_pkt(struct net_lro_mgr *lro_mgr, + struct iphdr *iph, struct tcphdr *tcph) +{ + struct net_lro_desc *lro_desc; + + lro_desc = lro_get_desc(lro_mgr, lro_mgr->lro_arr, iph, tcph); + if (lro_desc->active) + lro_flush(lro_mgr, lro_desc); +} +EXPORT_SYMBOL(lro_flush_pkt); -- cgit v1.2.3 From d738cd8fca948e45d53120247cb7a5f5be3ca09e Mon Sep 17 00:00:00 2001 From: Ilpo Järvinen Date: Sat, 24 Mar 2007 21:03:23 -0700 Subject: [TCP]: Add highest_sack seqno, points to globally highest SACK MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It is guaranteed to be valid only when !tp->sacked_out. In most cases this seqno is available in the last ACK but there is no guarantee for that. The new fast recovery loss marking algorithm needs this as entry point. Signed-off-by: Ilpo Järvinen Signed-off-by: David S. Miller --- include/linux/tcp.h | 2 ++ net/ipv4/tcp_input.c | 8 +++++++- 2 files changed, 9 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/tcp.h b/include/linux/tcp.h index c6b9f92e8289..c072f88afb97 100644 --- a/include/linux/tcp.h +++ b/include/linux/tcp.h @@ -333,6 +333,8 @@ struct tcp_sock { struct tcp_sack_block_wire recv_sack_cache[4]; + u32 highest_sack; /* Start seq of globally highest revd SACK (valid only in slowpath) */ + /* from STCP, retrans queue hinting */ struct sk_buff* lost_skb_hint; diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index f893e90061eb..813f2049b85d 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c @@ -979,8 +979,10 @@ tcp_sacktag_write_queue(struct sock *sk, struct sk_buff *ack_skb, u32 prior_snd_ int i; int first_sack_index; - if (!tp->sacked_out) + if (!tp->sacked_out) { tp->fackets_out = 0; + tp->highest_sack = tp->snd_una; + } prior_fackets = tp->fackets_out; /* Check for D-SACK. */ @@ -1217,6 +1219,10 @@ tcp_sacktag_write_queue(struct sock *sk, struct sk_buff *ack_skb, u32 prior_snd_ if (fack_count > tp->fackets_out) tp->fackets_out = fack_count; + + if (after(TCP_SKB_CB(skb)->seq, + tp->highest_sack)) + tp->highest_sack = TCP_SKB_CB(skb)->seq; } else { if (dup_sack && (sacked&TCPCB_RETRANS)) reord = min(fack_count, reord); -- cgit v1.2.3 From 539d243fdd7900fa5a544c7c154dc3ddf627e840 Mon Sep 17 00:00:00 2001 From: Ilpo Järvinen Date: Sun, 27 May 2007 02:03:20 -0700 Subject: [TCP]: Access to highest_sack obsoletes forward_cnt_hint MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In addition, added a reference about the purpose of the loop. Signed-off-by: Ilpo Järvinen Signed-off-by: David S. Miller --- include/linux/tcp.h | 1 - net/ipv4/tcp_output.c | 23 +++++++++-------------- 2 files changed, 9 insertions(+), 15 deletions(-) (limited to 'include/linux') diff --git a/include/linux/tcp.h b/include/linux/tcp.h index c072f88afb97..d64734389fb6 100644 --- a/include/linux/tcp.h +++ b/include/linux/tcp.h @@ -346,7 +346,6 @@ struct tcp_sock { int fastpath_cnt_hint; int lost_cnt_hint; int retransmit_cnt_hint; - int forward_cnt_hint; u16 advmss; /* Advertised MSS */ u16 prior_ssthresh; /* ssthresh saved at recovery start */ diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index 666d8a58d14a..b11025e8a49e 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c @@ -1945,33 +1945,28 @@ void tcp_xmit_retransmit_queue(struct sock *sk) * and retransmission... Both ways have their merits... * * For now we do not retransmit anything, while we have some new - * segments to send. + * segments to send. In the other cases, follow rule 3 for + * NextSeg() specified in RFC3517. */ if (tcp_may_send_now(sk)) return; - if (tp->forward_skb_hint) { + /* If nothing is SACKed, highest_sack in the loop won't be valid */ + if (!tp->sacked_out) + return; + + if (tp->forward_skb_hint) skb = tp->forward_skb_hint; - packet_cnt = tp->forward_cnt_hint; - } else{ + else skb = tcp_write_queue_head(sk); - packet_cnt = 0; - } tcp_for_write_queue_from(skb, sk) { if (skb == tcp_send_head(sk)) break; - tp->forward_cnt_hint = packet_cnt; tp->forward_skb_hint = skb; - /* Similar to the retransmit loop above we - * can pretend that the retransmitted SKB - * we send out here will be composed of one - * real MSS sized packet because tcp_retransmit_skb() - * will fragment it if necessary. - */ - if (++packet_cnt > tp->fackets_out) + if (after(TCP_SKB_CB(skb)->seq, tp->highest_sack)) break; if (tcp_packets_in_flight(tp) >= tp->snd_cwnd) -- cgit v1.2.3 From b5860bbac7be1381626f3dc8a0cb970a60fcefb4 Mon Sep 17 00:00:00 2001 From: Ilpo Järvinen Date: Thu, 9 Aug 2007 14:33:18 +0300 Subject: [TCP]: Tighten tcp_sock's belt, drop left_out MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It is easily calculable when needed and user are not that many after all. Signed-off-by: Ilpo Järvinen Signed-off-by: David S. Miller --- include/linux/tcp.h | 1 - include/net/tcp.h | 4 ++-- net/ipv4/tcp_input.c | 11 ++--------- net/ipv4/tcp_minisocks.c | 1 - net/ipv4/tcp_output.c | 12 +++--------- 5 files changed, 7 insertions(+), 22 deletions(-) (limited to 'include/linux') diff --git a/include/linux/tcp.h b/include/linux/tcp.h index d64734389fb6..1f12fa0b67d7 100644 --- a/include/linux/tcp.h +++ b/include/linux/tcp.h @@ -304,7 +304,6 @@ struct tcp_sock { u32 rtt_seq; /* sequence number to update rttvar */ u32 packets_out; /* Packets which are "in flight" */ - u32 left_out; /* Packets which leaved network */ u32 retrans_out; /* Retransmitted packets out */ /* * Options received (usually on last packet, some only on SYN packets). diff --git a/include/net/tcp.h b/include/net/tcp.h index 9d3438f6b52f..299872d461c7 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h @@ -735,7 +735,8 @@ static inline void tcp_ca_event(struct sock *sk, const enum tcp_ca_event event) */ static inline unsigned int tcp_packets_in_flight(const struct tcp_sock *tp) { - return (tp->packets_out - tp->left_out + tp->retrans_out); + return tp->packets_out - (tp->sacked_out + tp->lost_out) + + tp->retrans_out; } /* If cwnd > ssthresh, we may raise ssthresh to be half-way to cwnd. @@ -757,7 +758,6 @@ static inline void tcp_sync_left_out(struct tcp_sock *tp) { BUG_ON(tp->rx_opt.sack_ok && (tp->sacked_out + tp->lost_out > tp->packets_out)); - tp->left_out = tp->sacked_out + tp->lost_out; } extern void tcp_enter_cwr(struct sock *sk, const int set_ssthresh); diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index ea690afa592a..957e0fb8afb7 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c @@ -1346,8 +1346,6 @@ tcp_sacktag_write_queue(struct sock *sk, struct sk_buff *ack_skb, u32 prior_snd_ } } - tp->left_out = tp->sacked_out + tp->lost_out; - if ((reord < tp->fackets_out) && icsk->icsk_ca_state != TCP_CA_Loss && (!tp->frto_highmark || after(tp->snd_una, tp->frto_highmark))) tcp_update_reordering(sk, ((tp->fackets_out + 1) - reord), 0); @@ -1408,7 +1406,6 @@ static void tcp_remove_reno_sacks(struct sock *sk, int acked) static inline void tcp_reset_reno_sack(struct tcp_sock *tp) { tp->sacked_out = 0; - tp->left_out = tp->lost_out; } int tcp_use_frto(struct sock *sk) @@ -1573,7 +1570,6 @@ static void tcp_enter_frto_loss(struct sock *sk, int allowed_segments, int flag) void tcp_clear_retrans(struct tcp_sock *tp) { - tp->left_out = 0; tp->retrans_out = 0; tp->fackets_out = 0; @@ -1973,7 +1969,7 @@ static void DBGUNDO(struct sock *sk, const char *msg) printk(KERN_DEBUG "Undo %s %u.%u.%u.%u/%u c%u l%u ss%u/%u p%u\n", msg, NIPQUAD(inet->daddr), ntohs(inet->dport), - tp->snd_cwnd, tp->left_out, + tp->snd_cwnd, tp->sacked_out + tp->lost_out, tp->snd_ssthresh, tp->prior_ssthresh, tp->packets_out); } @@ -2102,7 +2098,6 @@ static int tcp_try_undo_loss(struct sock *sk) DBGUNDO(sk, "partial loss"); tp->lost_out = 0; - tp->left_out = tp->sacked_out; tcp_undo_cwr(sk, 1); NET_INC_STATS_BH(LINUX_MIB_TCPLOSSUNDO); inet_csk(sk)->icsk_retransmits = 0; @@ -2126,8 +2121,6 @@ static void tcp_try_to_open(struct sock *sk, int flag) { struct tcp_sock *tp = tcp_sk(sk); - tcp_sync_left_out(tp); - if (tp->retrans_out == 0) tp->retrans_stamp = 0; @@ -2137,7 +2130,7 @@ static void tcp_try_to_open(struct sock *sk, int flag) if (inet_csk(sk)->icsk_ca_state != TCP_CA_CWR) { int state = TCP_CA_Open; - if (tp->left_out || tp->retrans_out || tp->undo_marker) + if (tp->sacked_out || tp->retrans_out || tp->undo_marker) state = TCP_CA_Disorder; if (inet_csk(sk)->icsk_ca_state != state) { diff --git a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c index 36a8fbd0e64e..fdfe89fe646b 100644 --- a/net/ipv4/tcp_minisocks.c +++ b/net/ipv4/tcp_minisocks.c @@ -405,7 +405,6 @@ struct sock *tcp_create_openreq_child(struct sock *sk, struct request_sock *req, newicsk->icsk_rto = TCP_TIMEOUT_INIT; newtp->packets_out = 0; - newtp->left_out = 0; newtp->retrans_out = 0; newtp->sacked_out = 0; newtp->fackets_out = 0; diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index 3c8c8e7f6f6d..7434944caa8f 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c @@ -732,10 +732,8 @@ int tcp_fragment(struct sock *sk, struct sk_buff *skb, u32 len, unsigned int mss if (TCP_SKB_CB(skb)->sacked & TCPCB_SACKED_RETRANS) tp->retrans_out -= diff; - if (TCP_SKB_CB(skb)->sacked & TCPCB_LOST) { + if (TCP_SKB_CB(skb)->sacked & TCPCB_LOST) tp->lost_out -= diff; - tp->left_out -= diff; - } if (diff > 0) { /* Adjust Reno SACK estimate. */ @@ -1727,15 +1725,11 @@ static void tcp_retrans_try_collapse(struct sock *sk, struct sk_buff *skb, int m TCP_SKB_CB(skb)->sacked |= TCP_SKB_CB(next_skb)->sacked&(TCPCB_EVER_RETRANS|TCPCB_AT_TAIL); if (TCP_SKB_CB(next_skb)->sacked&TCPCB_SACKED_RETRANS) tp->retrans_out -= tcp_skb_pcount(next_skb); - if (TCP_SKB_CB(next_skb)->sacked&TCPCB_LOST) { + if (TCP_SKB_CB(next_skb)->sacked&TCPCB_LOST) tp->lost_out -= tcp_skb_pcount(next_skb); - tp->left_out -= tcp_skb_pcount(next_skb); - } /* Reno case is special. Sigh... */ - if (!tp->rx_opt.sack_ok && tp->sacked_out) { + if (!tp->rx_opt.sack_ok && tp->sacked_out) tcp_dec_pcount_approx(&tp->sacked_out, next_skb); - tp->left_out -= tcp_skb_pcount(next_skb); - } /* Not quite right: it can be > snd.fack, but * it is better to underestimate fackets. -- cgit v1.2.3 From 13dae426318aae073028a4b3bd493104a991e800 Mon Sep 17 00:00:00 2001 From: Ilpo Järvinen Date: Fri, 10 Aug 2007 14:31:21 -0700 Subject: [TCP]: Update comment about highest_sack validity MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This stale info came from the original idea, which proved to be unnecessarily complex, sacked_out > 0 is easy to do and that when it's going to be needed anyway (it _can_ be valid also when sacked_out == 0 but there's not going to be a guarantee about it for now). Signed-off-by: Ilpo Järvinen Signed-off-by: David S. Miller --- include/linux/tcp.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/tcp.h b/include/linux/tcp.h index 1f12fa0b67d7..f8cf090e8f49 100644 --- a/include/linux/tcp.h +++ b/include/linux/tcp.h @@ -332,7 +332,8 @@ struct tcp_sock { struct tcp_sack_block_wire recv_sack_cache[4]; - u32 highest_sack; /* Start seq of globally highest revd SACK (valid only in slowpath) */ + u32 highest_sack; /* Start seq of globally highest revd SACK + * (validity guaranteed only if sacked_out > 0) */ /* from STCP, retrans queue hinting */ struct sk_buff* lost_skb_hint; -- cgit v1.2.3 From 0bcc1816188e570bde1d56a208996660f2633ae0 Mon Sep 17 00:00:00 2001 From: Satyam Sharma Date: Fri, 10 Aug 2007 15:35:05 -0700 Subject: [NET] netconsole: Support dynamic reconfiguration using configfs Based upon initial work by Keiichi Kii . This patch introduces support for dynamic reconfiguration (adding, removing and/or modifying parameters of netconsole targets at runtime) using a userspace interface exported via configfs. Documentation is also updated accordingly. Issues and brief design overview: (1) Kernel-initiated creation / destruction of kernel objects is not possible with configfs -- the lifetimes of the "config items" is managed exclusively from userspace. But netconsole must support boot/module params too, and these are parsed in kernel and hence netpolls must be setup from the kernel. Joel Becker suggested to separately manage the lifetimes of the two kinds of netconsole_target objects -- those created via configfs mkdir(2) from userspace and those specified from the boot/module option string. This adds complexity and some redundancy here and also means that boot/module param-created targets are not exposed through the configfs namespace (and hence cannot be updated / destroyed dynamically). However, this saves us from locking / refcounting complexities that would need to be introduced in configfs to support kernel-initiated item creation / destroy there. (2) In configfs, item creation takes place in the call chain of the mkdir(2) syscall in the driver subsystem. If we used an ioctl(2) to create / destroy objects from userspace, the special userspace program is able to fill out the structure to be passed into the ioctl and hence specify attributes such as local interface that are required at the time we set up the netpoll. For configfs, this information is not available at the time of mkdir(2). So, we keep all newly-created targets (via configfs) disabled by default. The user is expected to set various attributes appropriately (including the local network interface if required) and then write(2) "1" to the "enabled" attribute. Thus, netpoll_setup() is then called on the set parameters in the context of _this_ write(2) on the "enabled" attribute itself. This design enables the user to reconfigure existing netconsole targets at runtime to be attached to newly-come-up interfaces that may not have existed when netconsole was loaded or when the targets were actually created. All this effectively enables us to get rid of custom ioctls. (3) Ultra-paranoid configfs attribute show() and store() operations, with sanity and input range checking, using only safe string primitives, and compliant with the recommendations in Documentation/filesystems/sysfs.txt. (4) A new function netpoll_print_options() is created in the netpoll API, that just prints out the configured parameters for a netpoll structure. netpoll_parse_options() is modified to use that and it is also exported to be used from netconsole. Signed-off-by: Satyam Sharma Acked-by: Keiichi Kii Signed-off-by: Andrew Morton Signed-off-by: David S. Miller --- Documentation/networking/netconsole.txt | 68 ++++ drivers/net/Kconfig | 10 + drivers/net/netconsole.c | 605 ++++++++++++++++++++++++++++++-- include/linux/netpoll.h | 1 + net/core/netpoll.c | 44 ++- 5 files changed, 683 insertions(+), 45 deletions(-) (limited to 'include/linux') diff --git a/Documentation/networking/netconsole.txt b/Documentation/networking/netconsole.txt index 1aaa7383e41d..3c2f2b328638 100644 --- a/Documentation/networking/netconsole.txt +++ b/Documentation/networking/netconsole.txt @@ -3,6 +3,10 @@ started by Ingo Molnar , 2001.09.17 2.6 port and netpoll api by Matt Mackall , Sep 9 2003 Please send bug reports to Matt Mackall +and Satyam Sharma + +Introduction: +============= This module logs kernel printk messages over UDP allowing debugging of problem where disk logging fails and serial consoles are impractical. @@ -13,6 +17,9 @@ the specified interface as soon as possible. While this doesn't allow capture of early kernel panics, it does capture most of the boot process. +Sender and receiver configuration: +================================== + It takes a string configuration parameter "netconsole" in the following format: @@ -46,6 +53,67 @@ address. The remote host can run either 'netcat -u -l -p ' or syslogd. +Dynamic reconfiguration: +======================== + +Dynamic reconfigurability is a useful addition to netconsole that enables +remote logging targets to be dynamically added, removed, or have their +parameters reconfigured at runtime from a configfs-based userspace interface. +[ Note that the parameters of netconsole targets that were specified/created +from the boot/module option are not exposed via this interface, and hence +cannot be modified dynamically. ] + +To include this feature, select CONFIG_NETCONSOLE_DYNAMIC when building the +netconsole module (or kernel, if netconsole is built-in). + +Some examples follow (where configfs is mounted at the /sys/kernel/config +mountpoint). + +To add a remote logging target (target names can be arbitrary): + + cd /sys/kernel/config/netconsole/ + mkdir target1 + +Note that newly created targets have default parameter values (as mentioned +above) and are disabled by default -- they must first be enabled by writing +"1" to the "enabled" attribute (usually after setting parameters accordingly) +as described below. + +To remove a target: + + rmdir /sys/kernel/config/netconsole/othertarget/ + +The interface exposes these parameters of a netconsole target to userspace: + + enabled Is this target currently enabled? (read-write) + dev_name Local network interface name (read-write) + local_port Source UDP port to use (read-write) + remote_port Remote agent's UDP port (read-write) + local_ip Source IP address to use (read-write) + remote_ip Remote agent's IP address (read-write) + local_mac Local interface's MAC address (read-only) + remote_mac Remote agent's MAC address (read-write) + +The "enabled" attribute is also used to control whether the parameters of +a target can be updated or not -- you can modify the parameters of only +disabled targets (i.e. if "enabled" is 0). + +To update a target's parameters: + + cat enabled # check if enabled is 1 + echo 0 > enabled # disable the target (if required) + echo eth2 > dev_name # set local interface + echo 10.0.0.4 > remote_ip # update some parameter + echo cb:a9:87:65:43:21 > remote_mac # update more parameters + echo 1 > enabled # enable target again + +You can also update the local interface dynamically. This is especially +useful if you want to use interfaces that have newly come up (and may not +have existed when netconsole was loaded / initialized). + +Miscellaneous notes: +==================== + WARNING: the default target ethernet setting uses the broadcast ethernet address to send packets, which can cause increased load on other systems on the same ethernet segment. diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 40ff9a5269a2..10ed28ef3566 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -3082,6 +3082,16 @@ config NETCONSOLE If you want to log kernel messages over the network, enable this. See for details. +config NETCONSOLE_DYNAMIC + bool "Dynamic reconfiguration of logging targets (EXPERIMENTAL)" + depends on NETCONSOLE && SYSFS && EXPERIMENTAL + select CONFIGFS_FS + help + This option enables the ability to dynamically reconfigure target + parameters (interface, IP addresses, port numbers, MAC addresses) + at runtime through a userspace interface exported using configfs. + See for details. + config NETPOLL def_bool NETCONSOLE diff --git a/drivers/net/netconsole.c b/drivers/net/netconsole.c index 458c4d674a9e..69ef1eb03bea 100644 --- a/drivers/net/netconsole.c +++ b/drivers/net/netconsole.c @@ -41,6 +41,8 @@ #include #include #include +#include +#include MODULE_AUTHOR("Maintainer: Matt Mackall "); MODULE_DESCRIPTION("Console driver for network interfaces"); @@ -71,20 +73,100 @@ static DEFINE_SPINLOCK(target_list_lock); /** * struct netconsole_target - Represents a configured netconsole target. * @list: Links this target into the target_list. + * @item: Links us into the configfs subsystem hierarchy. + * @enabled: On / off knob to enable / disable target. + * Visible from userspace (read-write). + * We maintain a strict 1:1 correspondence between this and + * whether the corresponding netpoll is active or inactive. + * Also, other parameters of a target may be modified at + * runtime only when it is disabled (enabled == 0). * @np: The netpoll structure for this target. + * Contains the other userspace visible parameters: + * dev_name (read-write) + * local_port (read-write) + * remote_port (read-write) + * local_ip (read-write) + * remote_ip (read-write) + * local_mac (read-only) + * remote_mac (read-write) */ struct netconsole_target { struct list_head list; +#ifdef CONFIG_NETCONSOLE_DYNAMIC + struct config_item item; +#endif + int enabled; struct netpoll np; }; -/* Allocate new target and setup netpoll for it */ -static struct netconsole_target *alloc_target(char *target_config) +#ifdef CONFIG_NETCONSOLE_DYNAMIC + +static struct configfs_subsystem netconsole_subsys; + +static int __init dynamic_netconsole_init(void) +{ + config_group_init(&netconsole_subsys.su_group); + mutex_init(&netconsole_subsys.su_mutex); + return configfs_register_subsystem(&netconsole_subsys); +} + +static void __exit dynamic_netconsole_exit(void) +{ + configfs_unregister_subsystem(&netconsole_subsys); +} + +/* + * Targets that were created by parsing the boot/module option string + * do not exist in the configfs hierarchy (and have NULL names) and will + * never go away, so make these a no-op for them. + */ +static void netconsole_target_get(struct netconsole_target *nt) +{ + if (config_item_name(&nt->item)) + config_item_get(&nt->item); +} + +static void netconsole_target_put(struct netconsole_target *nt) +{ + if (config_item_name(&nt->item)) + config_item_put(&nt->item); +} + +#else /* !CONFIG_NETCONSOLE_DYNAMIC */ + +static int __init dynamic_netconsole_init(void) +{ + return 0; +} + +static void __exit dynamic_netconsole_exit(void) +{ +} + +/* + * No danger of targets going away from under us when dynamic + * reconfigurability is off. + */ +static void netconsole_target_get(struct netconsole_target *nt) +{ +} + +static void netconsole_target_put(struct netconsole_target *nt) +{ +} + +#endif /* CONFIG_NETCONSOLE_DYNAMIC */ + +/* Allocate new target (from boot/module param) and setup netpoll for it */ +static struct netconsole_target *alloc_param_target(char *target_config) { int err = -ENOMEM; struct netconsole_target *nt; - /* Allocate and initialize with defaults */ + /* + * Allocate and initialize with defaults. + * Note that these targets get their config_item fields zeroed-out. + */ nt = kzalloc(sizeof(*nt), GFP_KERNEL); if (!nt) { printk(KERN_ERR "netconsole: failed to allocate memory\n"); @@ -106,6 +188,8 @@ static struct netconsole_target *alloc_target(char *target_config) if (err) goto fail; + nt->enabled = 1; + return nt; fail: @@ -113,13 +197,469 @@ fail: return ERR_PTR(err); } -/* Cleanup netpoll for given target and free it */ -static void free_target(struct netconsole_target *nt) +/* Cleanup netpoll for given target (from boot/module param) and free it */ +static void free_param_target(struct netconsole_target *nt) { netpoll_cleanup(&nt->np); kfree(nt); } +#ifdef CONFIG_NETCONSOLE_DYNAMIC + +/* + * Our subsystem hierarchy is: + * + * /sys/kernel/config/netconsole/ + * | + * / + * | enabled + * | dev_name + * | local_port + * | remote_port + * | local_ip + * | remote_ip + * | local_mac + * | remote_mac + * | + * /... + */ + +struct netconsole_target_attr { + struct configfs_attribute attr; + ssize_t (*show)(struct netconsole_target *nt, + char *buf); + ssize_t (*store)(struct netconsole_target *nt, + const char *buf, + size_t count); +}; + +static struct netconsole_target *to_target(struct config_item *item) +{ + return item ? + container_of(item, struct netconsole_target, item) : + NULL; +} + +/* + * Wrapper over simple_strtol (base 10) with sanity and range checking. + * We return (signed) long only because we may want to return errors. + * Do not use this to convert numbers that are allowed to be negative. + */ +static long strtol10_check_range(const char *cp, long min, long max) +{ + long ret; + char *p = (char *) cp; + + WARN_ON(min < 0); + WARN_ON(max < min); + + ret = simple_strtol(p, &p, 10); + + if (*p && (*p != '\n')) { + printk(KERN_ERR "netconsole: invalid input\n"); + return -EINVAL; + } + if ((ret < min) || (ret > max)) { + printk(KERN_ERR "netconsole: input %ld must be between " + "%ld and %ld\n", ret, min, max); + return -EINVAL; + } + + return ret; +} + +/* + * Attribute operations for netconsole_target. + */ + +static ssize_t show_enabled(struct netconsole_target *nt, char *buf) +{ + return snprintf(buf, PAGE_SIZE, "%d\n", nt->enabled); +} + +static ssize_t show_dev_name(struct netconsole_target *nt, char *buf) +{ + return snprintf(buf, PAGE_SIZE, "%s\n", nt->np.dev_name); +} + +static ssize_t show_local_port(struct netconsole_target *nt, char *buf) +{ + return snprintf(buf, PAGE_SIZE, "%d\n", nt->np.local_port); +} + +static ssize_t show_remote_port(struct netconsole_target *nt, char *buf) +{ + return snprintf(buf, PAGE_SIZE, "%d\n", nt->np.remote_port); +} + +static ssize_t show_local_ip(struct netconsole_target *nt, char *buf) +{ + return snprintf(buf, PAGE_SIZE, "%d.%d.%d.%d\n", + HIPQUAD(nt->np.local_ip)); +} + +static ssize_t show_remote_ip(struct netconsole_target *nt, char *buf) +{ + return snprintf(buf, PAGE_SIZE, "%d.%d.%d.%d\n", + HIPQUAD(nt->np.remote_ip)); +} + +static ssize_t show_local_mac(struct netconsole_target *nt, char *buf) +{ + return snprintf(buf, PAGE_SIZE, "%02x:%02x:%02x:%02x:%02x:%02x\n", + nt->np.local_mac[0], nt->np.local_mac[1], + nt->np.local_mac[2], nt->np.local_mac[3], + nt->np.local_mac[4], nt->np.local_mac[5]); +} + +static ssize_t show_remote_mac(struct netconsole_target *nt, char *buf) +{ + return snprintf(buf, PAGE_SIZE, "%02x:%02x:%02x:%02x:%02x:%02x\n", + nt->np.remote_mac[0], nt->np.remote_mac[1], + nt->np.remote_mac[2], nt->np.remote_mac[3], + nt->np.remote_mac[4], nt->np.remote_mac[5]); +} + +/* + * This one is special -- targets created through the configfs interface + * are not enabled (and the corresponding netpoll activated) by default. + * The user is expected to set the desired parameters first (which + * would enable him to dynamically add new netpoll targets for new + * network interfaces as and when they come up). + */ +static ssize_t store_enabled(struct netconsole_target *nt, + const char *buf, + size_t count) +{ + int err; + long enabled; + + enabled = strtol10_check_range(buf, 0, 1); + if (enabled < 0) + return enabled; + + if (enabled) { /* 1 */ + + /* + * Skip netpoll_parse_options() -- all the attributes are + * already configured via configfs. Just print them out. + */ + netpoll_print_options(&nt->np); + + err = netpoll_setup(&nt->np); + if (err) + return err; + + printk(KERN_INFO "netconsole: network logging started\n"); + + } else { /* 0 */ + netpoll_cleanup(&nt->np); + } + + nt->enabled = enabled; + + return strnlen(buf, count); +} + +static ssize_t store_dev_name(struct netconsole_target *nt, + const char *buf, + size_t count) +{ + size_t len; + + if (nt->enabled) { + printk(KERN_ERR "netconsole: target (%s) is enabled, " + "disable to update parameters\n", + config_item_name(&nt->item)); + return -EINVAL; + } + + strlcpy(nt->np.dev_name, buf, IFNAMSIZ); + + /* Get rid of possible trailing newline from echo(1) */ + len = strnlen(nt->np.dev_name, IFNAMSIZ); + if (nt->np.dev_name[len - 1] == '\n') + nt->np.dev_name[len - 1] = '\0'; + + return strnlen(buf, count); +} + +static ssize_t store_local_port(struct netconsole_target *nt, + const char *buf, + size_t count) +{ + long local_port; +#define __U16_MAX ((__u16) ~0U) + + if (nt->enabled) { + printk(KERN_ERR "netconsole: target (%s) is enabled, " + "disable to update parameters\n", + config_item_name(&nt->item)); + return -EINVAL; + } + + local_port = strtol10_check_range(buf, 0, __U16_MAX); + if (local_port < 0) + return local_port; + + nt->np.local_port = local_port; + + return strnlen(buf, count); +} + +static ssize_t store_remote_port(struct netconsole_target *nt, + const char *buf, + size_t count) +{ + long remote_port; +#define __U16_MAX ((__u16) ~0U) + + if (nt->enabled) { + printk(KERN_ERR "netconsole: target (%s) is enabled, " + "disable to update parameters\n", + config_item_name(&nt->item)); + return -EINVAL; + } + + remote_port = strtol10_check_range(buf, 0, __U16_MAX); + if (remote_port < 0) + return remote_port; + + nt->np.remote_port = remote_port; + + return strnlen(buf, count); +} + +static ssize_t store_local_ip(struct netconsole_target *nt, + const char *buf, + size_t count) +{ + if (nt->enabled) { + printk(KERN_ERR "netconsole: target (%s) is enabled, " + "disable to update parameters\n", + config_item_name(&nt->item)); + return -EINVAL; + } + + nt->np.local_ip = ntohl(in_aton(buf)); + + return strnlen(buf, count); +} + +static ssize_t store_remote_ip(struct netconsole_target *nt, + const char *buf, + size_t count) +{ + if (nt->enabled) { + printk(KERN_ERR "netconsole: target (%s) is enabled, " + "disable to update parameters\n", + config_item_name(&nt->item)); + return -EINVAL; + } + + nt->np.remote_ip = ntohl(in_aton(buf)); + + return strnlen(buf, count); +} + +static ssize_t store_remote_mac(struct netconsole_target *nt, + const char *buf, + size_t count) +{ + u8 remote_mac[ETH_ALEN]; + char *p = (char *) buf; + int i; + + if (nt->enabled) { + printk(KERN_ERR "netconsole: target (%s) is enabled, " + "disable to update parameters\n", + config_item_name(&nt->item)); + return -EINVAL; + } + + for (i = 0; i < ETH_ALEN - 1; i++) { + remote_mac[i] = simple_strtoul(p, &p, 16); + if (*p != ':') + goto invalid; + p++; + } + remote_mac[ETH_ALEN - 1] = simple_strtoul(p, &p, 16); + if (*p && (*p != '\n')) + goto invalid; + + memcpy(nt->np.remote_mac, remote_mac, ETH_ALEN); + + return strnlen(buf, count); + +invalid: + printk(KERN_ERR "netconsole: invalid input\n"); + return -EINVAL; +} + +/* + * Attribute definitions for netconsole_target. + */ + +#define NETCONSOLE_TARGET_ATTR_RO(_name) \ +static struct netconsole_target_attr netconsole_target_##_name = \ + __CONFIGFS_ATTR(_name, S_IRUGO, show_##_name, NULL) + +#define NETCONSOLE_TARGET_ATTR_RW(_name) \ +static struct netconsole_target_attr netconsole_target_##_name = \ + __CONFIGFS_ATTR(_name, S_IRUGO | S_IWUSR, show_##_name, store_##_name) + +NETCONSOLE_TARGET_ATTR_RW(enabled); +NETCONSOLE_TARGET_ATTR_RW(dev_name); +NETCONSOLE_TARGET_ATTR_RW(local_port); +NETCONSOLE_TARGET_ATTR_RW(remote_port); +NETCONSOLE_TARGET_ATTR_RW(local_ip); +NETCONSOLE_TARGET_ATTR_RW(remote_ip); +NETCONSOLE_TARGET_ATTR_RO(local_mac); +NETCONSOLE_TARGET_ATTR_RW(remote_mac); + +static struct configfs_attribute *netconsole_target_attrs[] = { + &netconsole_target_enabled.attr, + &netconsole_target_dev_name.attr, + &netconsole_target_local_port.attr, + &netconsole_target_remote_port.attr, + &netconsole_target_local_ip.attr, + &netconsole_target_remote_ip.attr, + &netconsole_target_local_mac.attr, + &netconsole_target_remote_mac.attr, + NULL, +}; + +/* + * Item operations and type for netconsole_target. + */ + +static void netconsole_target_release(struct config_item *item) +{ + kfree(to_target(item)); +} + +static ssize_t netconsole_target_attr_show(struct config_item *item, + struct configfs_attribute *attr, + char *buf) +{ + ssize_t ret = -EINVAL; + struct netconsole_target *nt = to_target(item); + struct netconsole_target_attr *na = + container_of(attr, struct netconsole_target_attr, attr); + + if (na->show) + ret = na->show(nt, buf); + + return ret; +} + +static ssize_t netconsole_target_attr_store(struct config_item *item, + struct configfs_attribute *attr, + const char *buf, + size_t count) +{ + ssize_t ret = -EINVAL; + struct netconsole_target *nt = to_target(item); + struct netconsole_target_attr *na = + container_of(attr, struct netconsole_target_attr, attr); + + if (na->store) + ret = na->store(nt, buf, count); + + return ret; +} + +static struct configfs_item_operations netconsole_target_item_ops = { + .release = netconsole_target_release, + .show_attribute = netconsole_target_attr_show, + .store_attribute = netconsole_target_attr_store, +}; + +static struct config_item_type netconsole_target_type = { + .ct_attrs = netconsole_target_attrs, + .ct_item_ops = &netconsole_target_item_ops, + .ct_owner = THIS_MODULE, +}; + +/* + * Group operations and type for netconsole_subsys. + */ + +static struct config_item *make_netconsole_target(struct config_group *group, + const char *name) +{ + unsigned long flags; + struct netconsole_target *nt; + + /* + * Allocate and initialize with defaults. + * Target is disabled at creation (enabled == 0). + */ + nt = kzalloc(sizeof(*nt), GFP_KERNEL); + if (!nt) { + printk(KERN_ERR "netconsole: failed to allocate memory\n"); + return NULL; + } + + nt->np.name = "netconsole"; + strlcpy(nt->np.dev_name, "eth0", IFNAMSIZ); + nt->np.local_port = 6665; + nt->np.remote_port = 6666; + memset(nt->np.remote_mac, 0xff, ETH_ALEN); + + /* Initialize the config_item member */ + config_item_init_type_name(&nt->item, name, &netconsole_target_type); + + /* Adding, but it is disabled */ + spin_lock_irqsave(&target_list_lock, flags); + list_add(&nt->list, &target_list); + spin_unlock_irqrestore(&target_list_lock, flags); + + return &nt->item; +} + +static void drop_netconsole_target(struct config_group *group, + struct config_item *item) +{ + unsigned long flags; + struct netconsole_target *nt = to_target(item); + + spin_lock_irqsave(&target_list_lock, flags); + list_del(&nt->list); + spin_unlock_irqrestore(&target_list_lock, flags); + + /* + * The target may have never been enabled, or was manually disabled + * before being removed so netpoll may have already been cleaned up. + */ + if (nt->enabled) + netpoll_cleanup(&nt->np); + + config_item_put(&nt->item); +} + +static struct configfs_group_operations netconsole_subsys_group_ops = { + .make_item = make_netconsole_target, + .drop_item = drop_netconsole_target, +}; + +static struct config_item_type netconsole_subsys_type = { + .ct_group_ops = &netconsole_subsys_group_ops, + .ct_owner = THIS_MODULE, +}; + +/* The netconsole configfs subsystem */ +static struct configfs_subsystem netconsole_subsys = { + .su_group = { + .cg_item = { + .ci_namebuf = "netconsole", + .ci_type = &netconsole_subsys_type, + }, + }, +}; + +#endif /* CONFIG_NETCONSOLE_DYNAMIC */ + /* Handle network interface device notifications */ static int netconsole_netdev_event(struct notifier_block *this, unsigned long event, @@ -134,6 +674,7 @@ static int netconsole_netdev_event(struct notifier_block *this, spin_lock_irqsave(&target_list_lock, flags); list_for_each_entry(nt, &target_list, list) { + netconsole_target_get(nt); if (nt->np.dev == dev) { switch (event) { case NETDEV_CHANGEADDR: @@ -145,6 +686,7 @@ static int netconsole_netdev_event(struct notifier_block *this, break; } } + netconsole_target_put(nt); } spin_unlock_irqrestore(&target_list_lock, flags); @@ -169,7 +711,8 @@ static void write_msg(struct console *con, const char *msg, unsigned int len) spin_lock_irqsave(&target_list_lock, flags); list_for_each_entry(nt, &target_list, list) { - if (netif_running(nt->np.dev)) { + netconsole_target_get(nt); + if (nt->enabled && netif_running(nt->np.dev)) { /* * We nest this inside the for-each-target loop above * so that we're able to get as much logging out to @@ -184,6 +727,7 @@ static void write_msg(struct console *con, const char *msg, unsigned int len) left -= frag; } } + netconsole_target_put(nt); } spin_unlock_irqrestore(&target_list_lock, flags); } @@ -196,48 +740,52 @@ static struct console netconsole = { static int __init init_netconsole(void) { - int err = 0; + int err; struct netconsole_target *nt, *tmp; unsigned long flags; char *target_config; char *input = config; - if (!strnlen(input, MAX_PARAM_LENGTH)) { - printk(KERN_INFO "netconsole: not configured, aborting\n"); - goto out; - } - - while ((target_config = strsep(&input, ";"))) { - nt = alloc_target(target_config); - if (IS_ERR(nt)) { - err = PTR_ERR(nt); - goto fail; + if (strnlen(input, MAX_PARAM_LENGTH)) { + while ((target_config = strsep(&input, ";"))) { + nt = alloc_param_target(target_config); + if (IS_ERR(nt)) { + err = PTR_ERR(nt); + goto fail; + } + spin_lock_irqsave(&target_list_lock, flags); + list_add(&nt->list, &target_list); + spin_unlock_irqrestore(&target_list_lock, flags); } - spin_lock_irqsave(&target_list_lock, flags); - list_add(&nt->list, &target_list); - spin_unlock_irqrestore(&target_list_lock, flags); } err = register_netdevice_notifier(&netconsole_netdev_notifier); if (err) goto fail; + err = dynamic_netconsole_init(); + if (err) + goto undonotifier; + register_console(&netconsole); printk(KERN_INFO "netconsole: network logging started\n"); -out: return err; +undonotifier: + unregister_netdevice_notifier(&netconsole_netdev_notifier); + fail: printk(KERN_ERR "netconsole: cleaning up\n"); /* - * Remove all targets and destroy them. Skipping the list + * Remove all targets and destroy them (only targets created + * from the boot/module option exist here). Skipping the list * lock is safe here, and netpoll_cleanup() will sleep. */ list_for_each_entry_safe(nt, tmp, &target_list, list) { list_del(&nt->list); - free_target(nt); + free_param_target(nt); } return err; @@ -248,15 +796,20 @@ static void __exit cleanup_netconsole(void) struct netconsole_target *nt, *tmp; unregister_console(&netconsole); + dynamic_netconsole_exit(); unregister_netdevice_notifier(&netconsole_netdev_notifier); /* - * Remove all targets and destroy them. Skipping the list - * lock is safe here, and netpoll_cleanup() will sleep. + * Targets created via configfs pin references on our module + * and would first be rmdir(2)'ed from userspace. We reach + * here only when they are already destroyed, and only those + * created from the boot/module option are left, so remove and + * destroy them. Skipping the list lock is safe here, and + * netpoll_cleanup() will sleep. */ list_for_each_entry_safe(nt, tmp, &target_list, list) { list_del(&nt->list); - free_target(nt); + free_param_target(nt); } } diff --git a/include/linux/netpoll.h b/include/linux/netpoll.h index 08dcc39ec18d..20250d963d72 100644 --- a/include/linux/netpoll.h +++ b/include/linux/netpoll.h @@ -35,6 +35,7 @@ struct netpoll_info { void netpoll_poll(struct netpoll *np); void netpoll_send_udp(struct netpoll *np, const char *msg, int len); +void netpoll_print_options(struct netpoll *np); int netpoll_parse_options(struct netpoll *np, char *opt); int netpoll_setup(struct netpoll *np); int netpoll_trap(void); diff --git a/net/core/netpoll.c b/net/core/netpoll.c index abe6e3a4cc44..0952f936b292 100644 --- a/net/core/netpoll.c +++ b/net/core/netpoll.c @@ -532,6 +532,29 @@ out: return 0; } +void netpoll_print_options(struct netpoll *np) +{ + printk(KERN_INFO "%s: local port %d\n", + np->name, np->local_port); + printk(KERN_INFO "%s: local IP %d.%d.%d.%d\n", + np->name, HIPQUAD(np->local_ip)); + printk(KERN_INFO "%s: interface %s\n", + np->name, np->dev_name); + printk(KERN_INFO "%s: remote port %d\n", + np->name, np->remote_port); + printk(KERN_INFO "%s: remote IP %d.%d.%d.%d\n", + np->name, HIPQUAD(np->remote_ip)); + printk(KERN_INFO "%s: remote ethernet address " + "%02x:%02x:%02x:%02x:%02x:%02x\n", + np->name, + np->remote_mac[0], + np->remote_mac[1], + np->remote_mac[2], + np->remote_mac[3], + np->remote_mac[4], + np->remote_mac[5]); +} + int netpoll_parse_options(struct netpoll *np, char *opt) { char *cur=opt, *delim; @@ -544,7 +567,6 @@ int netpoll_parse_options(struct netpoll *np, char *opt) cur = delim; } cur++; - printk(KERN_INFO "%s: local port %d\n", np->name, np->local_port); if (*cur != '/') { if ((delim = strchr(cur, '/')) == NULL) @@ -552,9 +574,6 @@ int netpoll_parse_options(struct netpoll *np, char *opt) *delim = 0; np->local_ip = ntohl(in_aton(cur)); cur = delim; - - printk(KERN_INFO "%s: local IP %d.%d.%d.%d\n", - np->name, HIPQUAD(np->local_ip)); } cur++; @@ -568,8 +587,6 @@ int netpoll_parse_options(struct netpoll *np, char *opt) } cur++; - printk(KERN_INFO "%s: interface %s\n", np->name, np->dev_name); - if (*cur != '@') { /* dst port */ if ((delim = strchr(cur, '@')) == NULL) @@ -579,7 +596,6 @@ int netpoll_parse_options(struct netpoll *np, char *opt) cur = delim; } cur++; - printk(KERN_INFO "%s: remote port %d\n", np->name, np->remote_port); /* dst ip */ if ((delim = strchr(cur, '/')) == NULL) @@ -588,9 +604,6 @@ int netpoll_parse_options(struct netpoll *np, char *opt) np->remote_ip = ntohl(in_aton(cur)); cur = delim + 1; - printk(KERN_INFO "%s: remote IP %d.%d.%d.%d\n", - np->name, HIPQUAD(np->remote_ip)); - if (*cur != 0) { /* MAC address */ if ((delim = strchr(cur, ':')) == NULL) @@ -621,15 +634,7 @@ int netpoll_parse_options(struct netpoll *np, char *opt) np->remote_mac[5] = simple_strtol(cur, NULL, 16); } - printk(KERN_INFO "%s: remote ethernet address " - "%02x:%02x:%02x:%02x:%02x:%02x\n", - np->name, - np->remote_mac[0], - np->remote_mac[1], - np->remote_mac[2], - np->remote_mac[3], - np->remote_mac[4], - np->remote_mac[5]); + netpoll_print_options(np); return 0; @@ -831,6 +836,7 @@ void netpoll_set_trap(int trap) EXPORT_SYMBOL(netpoll_set_trap); EXPORT_SYMBOL(netpoll_trap); +EXPORT_SYMBOL(netpoll_print_options); EXPORT_SYMBOL(netpoll_parse_options); EXPORT_SYMBOL(netpoll_setup); EXPORT_SYMBOL(netpoll_cleanup); -- cgit v1.2.3 From 3ae7c0b2e3747b50c3a6c63ebb67469e0a6b3203 Mon Sep 17 00:00:00 2001 From: Jeff Garzik Date: Wed, 15 Aug 2007 16:00:51 -0700 Subject: [ETHTOOL]: Add ETHTOOL_[GS]FLAGS sub-ioctls Signed-off-by: Jeff Garzik Signed-off-by: David S. Miller --- include/linux/ethtool.h | 21 ++++++++++++++++ include/linux/netdevice.h | 1 + net/core/ethtool.c | 61 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 83 insertions(+) (limited to 'include/linux') diff --git a/include/linux/ethtool.h b/include/linux/ethtool.h index 23ccea811297..0e5de2fb960c 100644 --- a/include/linux/ethtool.h +++ b/include/linux/ethtool.h @@ -256,6 +256,19 @@ struct ethtool_perm_addr { __u8 data[0]; }; +/* boolean flags controlling per-interface behavior characteristics. + * When reading, the flag indicates whether or not a certain behavior + * is enabled/present. When writing, the flag indicates whether + * or not the driver should turn on (set) or off (clear) a behavior. + * + * Some behaviors may read-only (unconditionally absent or present). + * If such is the case, return EINVAL in the set-flags operation if the + * flag differs from the read-only value. + */ +enum ethtool_flags { + ETH_FLAG_LRO = (1 << 15), /* LRO is enabled */ +}; + #ifdef __KERNEL__ struct net_device; @@ -272,6 +285,8 @@ u32 ethtool_op_get_tso(struct net_device *dev); int ethtool_op_set_tso(struct net_device *dev, u32 data); u32 ethtool_op_get_ufo(struct net_device *dev); int ethtool_op_set_ufo(struct net_device *dev, u32 data); +u32 ethtool_op_get_flags(struct net_device *dev); +int ethtool_op_set_flags(struct net_device *dev, u32 data); /** * ðtool_ops - Alter and report network device settings @@ -307,6 +322,8 @@ int ethtool_op_set_ufo(struct net_device *dev, u32 data); * get_strings: Return a set of strings that describe the requested objects * phys_id: Identify the device * get_stats: Return statistics about the device + * get_flags: get 32-bit flags bitmap + * set_flags: set 32-bit flags bitmap * * Description: * @@ -369,6 +386,8 @@ struct ethtool_ops { void (*complete)(struct net_device *); u32 (*get_ufo)(struct net_device *); int (*set_ufo)(struct net_device *, u32); + u32 (*get_flags)(struct net_device *); + int (*set_flags)(struct net_device *, u32); }; #endif /* __KERNEL__ */ @@ -410,6 +429,8 @@ struct ethtool_ops { #define ETHTOOL_SUFO 0x00000022 /* Set UFO enable (ethtool_value) */ #define ETHTOOL_GGSO 0x00000023 /* Get GSO enable (ethtool_value) */ #define ETHTOOL_SGSO 0x00000024 /* Set GSO enable (ethtool_value) */ +#define ETHTOOL_GFLAGS 0x00000025 /* Get flags bitmap(ethtool_value) */ +#define ETHTOOL_SFLAGS 0x00000026 /* Set flags bitmap(ethtool_value) */ /* compatibility with older code */ #define SPARC_ETH_GSET ETHTOOL_GSET diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index b93575db8cce..8f00bdf95ef4 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -449,6 +449,7 @@ struct net_device #define NETIF_F_GSO 2048 /* Enable software GSO. */ #define NETIF_F_LLTX 4096 /* LockLess TX */ #define NETIF_F_MULTI_QUEUE 16384 /* Has multiple TX/RX queues */ +#define NETIF_F_LRO 32768 /* large receive offload */ /* Segmentation offload features */ #define NETIF_F_GSO_SHIFT 16 diff --git a/net/core/ethtool.c b/net/core/ethtool.c index c5e059352d43..6f8b78bcfd84 100644 --- a/net/core/ethtool.c +++ b/net/core/ethtool.c @@ -109,6 +109,32 @@ int ethtool_op_set_ufo(struct net_device *dev, u32 data) return 0; } +/* the following list of flags are the same as their associated + * NETIF_F_xxx values in include/linux/netdevice.h + */ +static const u32 flags_dup_features = + ETH_FLAG_LRO; + +u32 ethtool_op_get_flags(struct net_device *dev) +{ + /* in the future, this function will probably contain additional + * handling for flags which are not so easily handled + * by a simple masking operation + */ + + return dev->features & flags_dup_features; +} + +int ethtool_op_set_flags(struct net_device *dev, u32 data) +{ + if (data & ETH_FLAG_LRO) + dev->features |= NETIF_F_LRO; + else + dev->features &= ~NETIF_F_LRO; + + return 0; +} + /* Handlers for each ethtool command */ static int ethtool_get_settings(struct net_device *dev, void __user *useraddr) @@ -783,6 +809,33 @@ static int ethtool_get_perm_addr(struct net_device *dev, void __user *useraddr) return 0; } +static int ethtool_get_flags(struct net_device *dev, char __user *useraddr) +{ + struct ethtool_value edata = { ETHTOOL_GFLAGS }; + + if (!dev->ethtool_ops->get_flags) + return -EOPNOTSUPP; + + edata.data = dev->ethtool_ops->get_flags(dev); + + if (copy_to_user(useraddr, &edata, sizeof(edata))) + return -EFAULT; + return 0; +} + +static int ethtool_set_flags(struct net_device *dev, char __user *useraddr) +{ + struct ethtool_value edata; + + if (!dev->ethtool_ops->set_flags) + return -EOPNOTSUPP; + + if (copy_from_user(&edata, useraddr, sizeof(edata))) + return -EFAULT; + + return dev->ethtool_ops->set_flags(dev, edata.data); +} + /* The main entry point in this file. Called from net/core/dev.c */ int dev_ethtool(struct ifreq *ifr) @@ -935,6 +988,12 @@ int dev_ethtool(struct ifreq *ifr) case ETHTOOL_SGSO: rc = ethtool_set_gso(dev, useraddr); break; + case ETHTOOL_GFLAGS: + rc = ethtool_get_flags(dev, useraddr); + break; + case ETHTOOL_SFLAGS: + rc = ethtool_set_flags(dev, useraddr); + break; default: rc = -EOPNOTSUPP; } @@ -959,3 +1018,5 @@ EXPORT_SYMBOL(ethtool_op_set_tx_hw_csum); EXPORT_SYMBOL(ethtool_op_set_tx_ipv6_csum); EXPORT_SYMBOL(ethtool_op_set_ufo); EXPORT_SYMBOL(ethtool_op_get_ufo); +EXPORT_SYMBOL(ethtool_op_set_flags); +EXPORT_SYMBOL(ethtool_op_get_flags); -- cgit v1.2.3 From ff03d49f0ca1959246068b315d26e009da692ff2 Mon Sep 17 00:00:00 2001 From: Jeff Garzik Date: Wed, 15 Aug 2007 16:01:08 -0700 Subject: [ETHTOOL]: Introduce get_sset_count. Obsolete get_stats_count, self_test_count Signed-off-by: Jeff Garzik Signed-off-by: David S. Miller --- include/linux/ethtool.h | 7 ++-- net/core/ethtool.c | 95 ++++++++++++++++++++++++++++++++++++------------- 2 files changed, 75 insertions(+), 27 deletions(-) (limited to 'include/linux') diff --git a/include/linux/ethtool.h b/include/linux/ethtool.h index 0e5de2fb960c..f617998b87f1 100644 --- a/include/linux/ethtool.h +++ b/include/linux/ethtool.h @@ -376,11 +376,9 @@ struct ethtool_ops { int (*set_sg)(struct net_device *, u32); u32 (*get_tso)(struct net_device *); int (*set_tso)(struct net_device *, u32); - int (*self_test_count)(struct net_device *); void (*self_test)(struct net_device *, struct ethtool_test *, u64 *); void (*get_strings)(struct net_device *, u32 stringset, u8 *); int (*phys_id)(struct net_device *, u32); - int (*get_stats_count)(struct net_device *); void (*get_ethtool_stats)(struct net_device *, struct ethtool_stats *, u64 *); int (*begin)(struct net_device *); void (*complete)(struct net_device *); @@ -388,6 +386,11 @@ struct ethtool_ops { int (*set_ufo)(struct net_device *, u32); u32 (*get_flags)(struct net_device *); int (*set_flags)(struct net_device *, u32); + int (*get_sset_count)(struct net_device *, int); + + /* the following hooks are obsolete */ + int (*self_test_count)(struct net_device *);/* use get_sset_count */ + int (*get_stats_count)(struct net_device *);/* use get_sset_count */ }; #endif /* __KERNEL__ */ diff --git a/net/core/ethtool.c b/net/core/ethtool.c index 6f8b78bcfd84..1edae460d616 100644 --- a/net/core/ethtool.c +++ b/net/core/ethtool.c @@ -179,10 +179,23 @@ static int ethtool_get_drvinfo(struct net_device *dev, void __user *useraddr) info.cmd = ETHTOOL_GDRVINFO; ops->get_drvinfo(dev, &info); - if (ops->self_test_count) - info.testinfo_len = ops->self_test_count(dev); - if (ops->get_stats_count) - info.n_stats = ops->get_stats_count(dev); + if (ops->get_sset_count) { + int rc; + + rc = ops->get_sset_count(dev, ETH_SS_TEST); + if (rc >= 0) + info.testinfo_len = rc; + rc = ops->get_sset_count(dev, ETH_SS_STATS); + if (rc >= 0) + info.n_stats = rc; + } else { + /* code path for obsolete hooks */ + + if (ops->self_test_count) + info.testinfo_len = ops->self_test_count(dev); + if (ops->get_stats_count) + info.n_stats = ops->get_stats_count(dev); + } if (ops->get_regs_len) info.regdump_len = ops->get_regs_len(dev); if (ops->get_eeprom_len) @@ -669,16 +682,27 @@ static int ethtool_self_test(struct net_device *dev, char __user *useraddr) struct ethtool_test test; const struct ethtool_ops *ops = dev->ethtool_ops; u64 *data; - int ret; + int ret, test_len; - if (!ops->self_test || !ops->self_test_count) + if (!ops->self_test) + return -EOPNOTSUPP; + if (!ops->get_sset_count && !ops->self_test_count) return -EOPNOTSUPP; + if (ops->get_sset_count) + test_len = ops->get_sset_count(dev, ETH_SS_TEST); + else + /* code path for obsolete hook */ + test_len = ops->self_test_count(dev); + if (test_len < 0) + return test_len; + WARN_ON(test_len == 0); + if (copy_from_user(&test, useraddr, sizeof(test))) return -EFAULT; - test.len = ops->self_test_count(dev); - data = kmalloc(test.len * sizeof(u64), GFP_USER); + test.len = test_len; + data = kmalloc(test_len * sizeof(u64), GFP_USER); if (!data) return -ENOMEM; @@ -710,19 +734,29 @@ static int ethtool_get_strings(struct net_device *dev, void __user *useraddr) if (copy_from_user(&gstrings, useraddr, sizeof(gstrings))) return -EFAULT; - switch (gstrings.string_set) { - case ETH_SS_TEST: - if (!ops->self_test_count) - return -EOPNOTSUPP; - gstrings.len = ops->self_test_count(dev); - break; - case ETH_SS_STATS: - if (!ops->get_stats_count) - return -EOPNOTSUPP; - gstrings.len = ops->get_stats_count(dev); - break; - default: - return -EINVAL; + if (ops->get_sset_count) { + ret = ops->get_sset_count(dev, gstrings.string_set); + if (ret < 0) + return ret; + + gstrings.len = ret; + } else { + /* code path for obsolete hooks */ + + switch (gstrings.string_set) { + case ETH_SS_TEST: + if (!ops->self_test_count) + return -EOPNOTSUPP; + gstrings.len = ops->self_test_count(dev); + break; + case ETH_SS_STATS: + if (!ops->get_stats_count) + return -EOPNOTSUPP; + gstrings.len = ops->get_stats_count(dev); + break; + default: + return -EINVAL; + } } data = kmalloc(gstrings.len * ETH_GSTRING_LEN, GFP_USER); @@ -762,16 +796,27 @@ static int ethtool_get_stats(struct net_device *dev, void __user *useraddr) struct ethtool_stats stats; const struct ethtool_ops *ops = dev->ethtool_ops; u64 *data; - int ret; + int ret, n_stats; - if (!ops->get_ethtool_stats || !ops->get_stats_count) + if (!ops->get_ethtool_stats) return -EOPNOTSUPP; + if (!ops->get_sset_count && !ops->get_stats_count) + return -EOPNOTSUPP; + + if (ops->get_sset_count) + n_stats = ops->get_sset_count(dev, ETH_SS_STATS); + else + /* code path for obsolete hook */ + n_stats = ops->get_stats_count(dev); + if (n_stats < 0) + return n_stats; + WARN_ON(n_stats == 0); if (copy_from_user(&stats, useraddr, sizeof(stats))) return -EFAULT; - stats.n_stats = ops->get_stats_count(dev); - data = kmalloc(stats.n_stats * sizeof(u64), GFP_USER); + stats.n_stats = n_stats; + data = kmalloc(n_stats * sizeof(u64), GFP_USER); if (!data) return -ENOMEM; -- cgit v1.2.3 From 339bf024756690949f536777b921f34186eaa8b4 Mon Sep 17 00:00:00 2001 From: Jeff Garzik Date: Wed, 15 Aug 2007 16:01:32 -0700 Subject: [ETHTOOL]: Introduce ->{get,set}_priv_flags, ETHTOOL_[GS]PFLAGS Signed-off-by: Jeff Garzik Signed-off-by: David S. Miller --- include/linux/ethtool.h | 8 +++++++- net/core/ethtool.c | 38 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/ethtool.h b/include/linux/ethtool.h index f617998b87f1..71d4ada6f315 100644 --- a/include/linux/ethtool.h +++ b/include/linux/ethtool.h @@ -39,7 +39,8 @@ struct ethtool_drvinfo { char bus_info[ETHTOOL_BUSINFO_LEN]; /* Bus info for this IF. */ /* For PCI devices, use pci_name(pci_dev). */ char reserved1[32]; - char reserved2[16]; + char reserved2[12]; + __u32 n_priv_flags; /* number of flags valid in ETHTOOL_GPFLAGS */ __u32 n_stats; /* number of u64's from ETHTOOL_GSTATS */ __u32 testinfo_len; __u32 eedump_len; /* Size of data from ETHTOOL_GEEPROM (bytes) */ @@ -219,6 +220,7 @@ struct ethtool_pauseparam { enum ethtool_stringset { ETH_SS_TEST = 0, ETH_SS_STATS, + ETH_SS_PRIV_FLAGS, }; /* for passing string sets for data tagging */ @@ -386,6 +388,8 @@ struct ethtool_ops { int (*set_ufo)(struct net_device *, u32); u32 (*get_flags)(struct net_device *); int (*set_flags)(struct net_device *, u32); + u32 (*get_priv_flags)(struct net_device *); + int (*set_priv_flags)(struct net_device *, u32); int (*get_sset_count)(struct net_device *, int); /* the following hooks are obsolete */ @@ -434,6 +438,8 @@ struct ethtool_ops { #define ETHTOOL_SGSO 0x00000024 /* Set GSO enable (ethtool_value) */ #define ETHTOOL_GFLAGS 0x00000025 /* Get flags bitmap(ethtool_value) */ #define ETHTOOL_SFLAGS 0x00000026 /* Set flags bitmap(ethtool_value) */ +#define ETHTOOL_GPFLAGS 0x00000027 /* Get driver-private flags bitmap */ +#define ETHTOOL_SPFLAGS 0x00000028 /* Set driver-private flags bitmap */ /* compatibility with older code */ #define SPARC_ETH_GSET ETHTOOL_GSET diff --git a/net/core/ethtool.c b/net/core/ethtool.c index 1edae460d616..d255209dc110 100644 --- a/net/core/ethtool.c +++ b/net/core/ethtool.c @@ -188,6 +188,9 @@ static int ethtool_get_drvinfo(struct net_device *dev, void __user *useraddr) rc = ops->get_sset_count(dev, ETH_SS_STATS); if (rc >= 0) info.n_stats = rc; + rc = ops->get_sset_count(dev, ETH_SS_PRIV_FLAGS); + if (rc >= 0) + info.n_priv_flags = rc; } else { /* code path for obsolete hooks */ @@ -881,6 +884,33 @@ static int ethtool_set_flags(struct net_device *dev, char __user *useraddr) return dev->ethtool_ops->set_flags(dev, edata.data); } +static int ethtool_get_priv_flags(struct net_device *dev, char __user *useraddr) +{ + struct ethtool_value edata = { ETHTOOL_GPFLAGS }; + + if (!dev->ethtool_ops->get_priv_flags) + return -EOPNOTSUPP; + + edata.data = dev->ethtool_ops->get_priv_flags(dev); + + if (copy_to_user(useraddr, &edata, sizeof(edata))) + return -EFAULT; + return 0; +} + +static int ethtool_set_priv_flags(struct net_device *dev, char __user *useraddr) +{ + struct ethtool_value edata; + + if (!dev->ethtool_ops->set_priv_flags) + return -EOPNOTSUPP; + + if (copy_from_user(&edata, useraddr, sizeof(edata))) + return -EFAULT; + + return dev->ethtool_ops->set_priv_flags(dev, edata.data); +} + /* The main entry point in this file. Called from net/core/dev.c */ int dev_ethtool(struct ifreq *ifr) @@ -915,6 +945,8 @@ int dev_ethtool(struct ifreq *ifr) case ETHTOOL_GPERMADDR: case ETHTOOL_GUFO: case ETHTOOL_GGSO: + case ETHTOOL_GFLAGS: + case ETHTOOL_GPFLAGS: break; default: if (!capable(CAP_NET_ADMIN)) @@ -1039,6 +1071,12 @@ int dev_ethtool(struct ifreq *ifr) case ETHTOOL_SFLAGS: rc = ethtool_set_flags(dev, useraddr); break; + case ETHTOOL_GPFLAGS: + rc = ethtool_get_priv_flags(dev, useraddr); + break; + case ETHTOOL_SPFLAGS: + rc = ethtool_set_priv_flags(dev, useraddr); + break; default: rc = -EOPNOTSUPP; } -- cgit v1.2.3 From a272378d1128d1c60a463a315646c86d174ff74c Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Sun, 19 Aug 2007 17:16:05 -0700 Subject: [KTIME]: Introduce ktime_sub_ns and ktime_sub_us First user will be the DCCP transport networking protocol. Signed-off-by: Arnaldo Carvalho de Melo Signed-off-by: David S. Miller --- include/linux/ktime.h | 21 +++++++++++++++++++++ kernel/hrtimer.c | 24 ++++++++++++++++++++++++ 2 files changed, 45 insertions(+) (limited to 'include/linux') diff --git a/include/linux/ktime.h b/include/linux/ktime.h index dae7143644fe..a6ddec141f96 100644 --- a/include/linux/ktime.h +++ b/include/linux/ktime.h @@ -102,6 +102,13 @@ static inline ktime_t ktime_set(const long secs, const unsigned long nsecs) #define ktime_add_ns(kt, nsval) \ ({ (ktime_t){ .tv64 = (kt).tv64 + (nsval) }; }) +/* + * Subtract a scalar nanosecod from a ktime_t variable + * res = kt - nsval: + */ +#define ktime_sub_ns(kt, nsval) \ + ({ (ktime_t){ .tv64 = (kt).tv64 - (nsval) }; }) + /* convert a timespec to ktime_t format: */ static inline ktime_t timespec_to_ktime(struct timespec ts) { @@ -199,6 +206,15 @@ static inline ktime_t ktime_add(const ktime_t add1, const ktime_t add2) */ extern ktime_t ktime_add_ns(const ktime_t kt, u64 nsec); +/** + * ktime_sub_ns - Subtract a scalar nanoseconds value from a ktime_t variable + * @kt: minuend + * @nsec: the scalar nsec value to subtract + * + * Returns the subtraction of @nsec from @kt in ktime_t format + */ +extern ktime_t ktime_sub_ns(const ktime_t kt, u64 nsec); + /** * timespec_to_ktime - convert a timespec to ktime_t format * @ts: the timespec variable to convert @@ -289,6 +305,11 @@ static inline ktime_t ktime_add_us(const ktime_t kt, const u64 usec) return ktime_add_ns(kt, usec * 1000); } +static inline ktime_t ktime_sub_us(const ktime_t kt, const u64 usec) +{ + return ktime_sub_ns(kt, usec * 1000); +} + /* * The resolution of the clocks. The resolution value is returned in * the clock_getres() system call to give application programmers an diff --git a/kernel/hrtimer.c b/kernel/hrtimer.c index c21ca6bfaa66..dc8a4451d79b 100644 --- a/kernel/hrtimer.c +++ b/kernel/hrtimer.c @@ -277,6 +277,30 @@ ktime_t ktime_add_ns(const ktime_t kt, u64 nsec) } EXPORT_SYMBOL_GPL(ktime_add_ns); + +/** + * ktime_sub_ns - Subtract a scalar nanoseconds value from a ktime_t variable + * @kt: minuend + * @nsec: the scalar nsec value to subtract + * + * Returns the subtraction of @nsec from @kt in ktime_t format + */ +ktime_t ktime_sub_ns(const ktime_t kt, u64 nsec) +{ + ktime_t tmp; + + if (likely(nsec < NSEC_PER_SEC)) { + tmp.tv64 = nsec; + } else { + unsigned long rem = do_div(nsec, NSEC_PER_SEC); + + tmp = ktime_set((long)nsec, rem); + } + + return ktime_sub(kt, tmp); +} + +EXPORT_SYMBOL_GPL(ktime_sub_ns); # endif /* !CONFIG_KTIME_SCALAR */ /* -- cgit v1.2.3 From 19ac21465e15e476220909c01b23df847b6ffa30 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Sun, 19 Aug 2007 17:18:33 -0700 Subject: [DCCP]: Convert dccps_timestamp_time to ktime_t Signed-off-by: Arnaldo Carvalho de Melo Signed-off-by: David S. Miller --- include/linux/dccp.h | 3 ++- net/dccp/options.c | 13 +++++-------- 2 files changed, 7 insertions(+), 9 deletions(-) (limited to 'include/linux') diff --git a/include/linux/dccp.h b/include/linux/dccp.h index fda2148d8c85..3a4b96becfc4 100644 --- a/include/linux/dccp.h +++ b/include/linux/dccp.h @@ -215,6 +215,7 @@ struct dccp_so_feat { #ifdef __KERNEL__ #include +#include #include #include #include @@ -498,7 +499,7 @@ struct dccp_sock { __u64 dccps_gar; __be32 dccps_service; struct dccp_service_list *dccps_service_list; - struct timeval dccps_timestamp_time; + ktime_t dccps_timestamp_time; __u32 dccps_timestamp_echo; __u16 dccps_l_ack_ratio; __u16 dccps_r_ack_ratio; diff --git a/net/dccp/options.c b/net/dccp/options.c index 34d536d5f1a1..95b75d8354ff 100644 --- a/net/dccp/options.c +++ b/net/dccp/options.c @@ -158,7 +158,7 @@ int dccp_parse_options(struct sock *sk, struct sk_buff *skb) opt_recv->dccpor_timestamp = ntohl(*(__be32 *)value); dp->dccps_timestamp_echo = opt_recv->dccpor_timestamp; - dccp_timestamp(sk, &dp->dccps_timestamp_time); + dp->dccps_timestamp_time = ktime_get_real(); dccp_pr_debug("%s rx opt: TIMESTAMP=%u, ackno=%llu\n", dccp_role(sk), opt_recv->dccpor_timestamp, @@ -405,14 +405,12 @@ static int dccp_insert_option_timestamp_echo(struct sock *sk, struct sk_buff *skb) { struct dccp_sock *dp = dccp_sk(sk); - struct timeval now; __be32 tstamp_echo; - u32 elapsed_time; int len, elapsed_time_len; unsigned char *to; - - dccp_timestamp(sk, &now); - elapsed_time = timeval_delta(&now, &dp->dccps_timestamp_time) / 10; + const suseconds_t delta = ktime_us_delta(ktime_get_real(), + dp->dccps_timestamp_time); + u32 elapsed_time = delta / 10; elapsed_time_len = dccp_elapsed_time_len(elapsed_time); len = 6 + elapsed_time_len; @@ -438,8 +436,7 @@ static int dccp_insert_option_timestamp_echo(struct sock *sk, } dp->dccps_timestamp_echo = 0; - dp->dccps_timestamp_time.tv_sec = 0; - dp->dccps_timestamp_time.tv_usec = 0; + dp->dccps_timestamp_time = ktime_set(0, 0); return 0; } -- cgit v1.2.3 From 8fb8354af9b92ce3bd41083995f1fe26024d0959 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Sun, 19 Aug 2007 17:19:21 -0700 Subject: [DCCP]: Nuke dccp_timestamp and dccps_epoch, not used anymore Signed-off-by: Arnaldo Carvalho de Melo Signed-off-by: David S. Miller --- include/linux/dccp.h | 1 - net/dccp/dccp.h | 2 -- net/dccp/minisocks.c | 1 - net/dccp/options.c | 16 ---------------- net/dccp/proto.c | 1 - 5 files changed, 21 deletions(-) (limited to 'include/linux') diff --git a/include/linux/dccp.h b/include/linux/dccp.h index 3a4b96becfc4..a0441190dc71 100644 --- a/include/linux/dccp.h +++ b/include/linux/dccp.h @@ -512,7 +512,6 @@ struct dccp_sock { struct ccid *dccps_hc_rx_ccid; struct ccid *dccps_hc_tx_ccid; struct dccp_options_received dccps_options_received; - struct timeval dccps_epoch; enum dccp_role dccps_role:2; __u8 dccps_hc_rx_insert_options:1; __u8 dccps_hc_tx_insert_options:1; diff --git a/net/dccp/dccp.h b/net/dccp/dccp.h index 20a7bedfe996..6fbe293bb271 100644 --- a/net/dccp/dccp.h +++ b/net/dccp/dccp.h @@ -402,8 +402,6 @@ extern int dccp_insert_option(struct sock *sk, struct sk_buff *skb, unsigned char option, const void *value, unsigned char len); -extern void dccp_timestamp(const struct sock *sk, struct timeval *tv); - static inline suseconds_t timeval_usecs(const struct timeval *tv) { return tv->tv_sec * USEC_PER_SEC + tv->tv_usec; diff --git a/net/dccp/minisocks.c b/net/dccp/minisocks.c index e18e249ac49b..91685990d57e 100644 --- a/net/dccp/minisocks.c +++ b/net/dccp/minisocks.c @@ -112,7 +112,6 @@ struct sock *dccp_create_openreq_child(struct sock *sk, newdp->dccps_service_list = NULL; newdp->dccps_service = dreq->dreq_service; newicsk->icsk_rto = DCCP_TIMEOUT_INIT; - do_gettimeofday(&newdp->dccps_epoch); if (dccp_feat_clone(sk, newsk)) goto out_free; diff --git a/net/dccp/options.c b/net/dccp/options.c index 439e25daa963..167415677a75 100644 --- a/net/dccp/options.c +++ b/net/dccp/options.c @@ -370,22 +370,6 @@ int dccp_insert_option_elapsed_time(struct sock *sk, struct sk_buff *skb, EXPORT_SYMBOL_GPL(dccp_insert_option_elapsed_time); -void dccp_timestamp(const struct sock *sk, struct timeval *tv) -{ - const struct dccp_sock *dp = dccp_sk(sk); - - do_gettimeofday(tv); - tv->tv_sec -= dp->dccps_epoch.tv_sec; - tv->tv_usec -= dp->dccps_epoch.tv_usec; - - while (tv->tv_usec < 0) { - tv->tv_sec--; - tv->tv_usec += USEC_PER_SEC; - } -} - -EXPORT_SYMBOL_GPL(dccp_timestamp); - int dccp_insert_option_timestamp(struct sock *sk, struct sk_buff *skb) { __be32 now = htonl(((suseconds_t)ktime_to_us(ktime_get_real())) / 10); diff --git a/net/dccp/proto.c b/net/dccp/proto.c index 04b59ec4f512..8d545da35262 100644 --- a/net/dccp/proto.c +++ b/net/dccp/proto.c @@ -172,7 +172,6 @@ int dccp_init_sock(struct sock *sk, const __u8 ctl_sock_initialized) struct inet_connection_sock *icsk = inet_csk(sk); dccp_minisock_init(&dp->dccps_minisock); - do_gettimeofday(&dp->dccps_epoch); /* * FIXME: We're hardcoding the CCID, and doing this at this point makes -- cgit v1.2.3 From 18f02545a9a16c9a89778b91a162ad16d510bb32 Mon Sep 17 00:00:00 2001 From: Ilpo Järvinen Date: Fri, 24 Aug 2007 22:55:52 -0700 Subject: [TCP] MIB: Add counters for discarded SACK blocks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In DSACK case, some events are not extraordinary, such as packet duplication generated DSACK. They can arrive easily below snd_una when undo_marker is not set (TCP being in CA_Open), counting such DSACKs amoung SACK discards will likely just mislead if they occur in some scenario when there are other problems as well. Similarly, excessively delayed packets could cause "normal" DSACKs. Therefore, separate counters are allocated for DSACK events. Signed-off-by: Ilpo Järvinen Signed-off-by: David S. Miller --- include/linux/snmp.h | 3 +++ net/ipv4/proc.c | 3 +++ net/ipv4/tcp_input.c | 10 +++++++++- 3 files changed, 15 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/snmp.h b/include/linux/snmp.h index 802b3a38b041..d24c55473821 100644 --- a/include/linux/snmp.h +++ b/include/linux/snmp.h @@ -231,6 +231,9 @@ enum LINUX_MIB_TCPABORTONLINGER, /* TCPAbortOnLinger */ LINUX_MIB_TCPABORTFAILED, /* TCPAbortFailed */ LINUX_MIB_TCPMEMORYPRESSURES, /* TCPMemoryPressures */ + LINUX_MIB_TCPSACKDISCARD, /* TCPSACKDiscard */ + LINUX_MIB_TCPDSACKIGNOREDOLD, /* TCPSACKIgnoredOld */ + LINUX_MIB_TCPDSACKIGNOREDNOUNDO, /* TCPSACKIgnoredNoUndo */ __LINUX_MIB_MAX }; diff --git a/net/ipv4/proc.c b/net/ipv4/proc.c index 3b690cf2a4ee..986d1c83a000 100644 --- a/net/ipv4/proc.c +++ b/net/ipv4/proc.c @@ -244,6 +244,9 @@ static const struct snmp_mib snmp4_net_list[] = { SNMP_MIB_ITEM("TCPAbortOnLinger", LINUX_MIB_TCPABORTONLINGER), SNMP_MIB_ITEM("TCPAbortFailed", LINUX_MIB_TCPABORTFAILED), SNMP_MIB_ITEM("TCPMemoryPressures", LINUX_MIB_TCPMEMORYPRESSURES), + SNMP_MIB_ITEM("TCPSACKDiscard", LINUX_MIB_TCPSACKDISCARD), + SNMP_MIB_ITEM("TCPDSACKIgnoredOld", LINUX_MIB_TCPDSACKIGNOREDOLD), + SNMP_MIB_ITEM("TCPDSACKIgnoredNoUndo", LINUX_MIB_TCPDSACKIGNOREDNOUNDO), SNMP_MIB_SENTINEL }; diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index a2364ebf8585..f9e4d7ad68b7 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c @@ -1240,8 +1240,16 @@ tcp_sacktag_write_queue(struct sock *sk, struct sk_buff *ack_skb, u32 prior_snd_ int fack_count; int dup_sack = (found_dup_sack && (i == first_sack_index)); - if (!tcp_is_sackblock_valid(tp, dup_sack, start_seq, end_seq)) + if (!tcp_is_sackblock_valid(tp, dup_sack, start_seq, end_seq)) { + if (dup_sack) { + if (!tp->undo_marker) + NET_INC_STATS_BH(LINUX_MIB_TCPDSACKIGNOREDNOUNDO); + else + NET_INC_STATS_BH(LINUX_MIB_TCPDSACKIGNOREDOLD); + } else + NET_INC_STATS_BH(LINUX_MIB_TCPSACKDISCARD); continue; + } skb = cached_skb; fack_count = cached_fack_count; -- cgit v1.2.3 From ab5f5e8b144e4c804ef3aa1ce08a9ca9f01187ce Mon Sep 17 00:00:00 2001 From: Joy Latten Date: Mon, 17 Sep 2007 11:51:22 -0700 Subject: [XFRM]: xfrm audit calls This patch modifies the current ipsec audit layer by breaking it up into purpose driven audit calls. So far, the only audit calls made are when add/delete an SA/policy. It had been discussed to give each key manager it's own calls to do this, but I found there to be much redundnacy since they did the exact same things, except for how they got auid and sid, so I combined them. The below audit calls can be made by any key manager. Hopefully, this is ok. Signed-off-by: Joy Latten Signed-off-by: David S. Miller --- include/linux/audit.h | 9 ++- include/net/xfrm.h | 40 +++++++++- net/key/af_key.c | 21 +++-- net/xfrm/xfrm_policy.c | 210 ++++++++++++++++++------------------------------- net/xfrm/xfrm_state.c | 89 ++++++++++++++++++--- net/xfrm/xfrm_user.c | 26 +++--- 6 files changed, 218 insertions(+), 177 deletions(-) (limited to 'include/linux') diff --git a/include/linux/audit.h b/include/linux/audit.h index d6579df8dadf..9ae740936a65 100644 --- a/include/linux/audit.h +++ b/include/linux/audit.h @@ -108,10 +108,11 @@ #define AUDIT_MAC_CIPSOV4_DEL 1408 /* NetLabel: del CIPSOv4 DOI entry */ #define AUDIT_MAC_MAP_ADD 1409 /* NetLabel: add LSM domain mapping */ #define AUDIT_MAC_MAP_DEL 1410 /* NetLabel: del LSM domain mapping */ -#define AUDIT_MAC_IPSEC_ADDSA 1411 /* Add a XFRM state */ -#define AUDIT_MAC_IPSEC_DELSA 1412 /* Delete a XFRM state */ -#define AUDIT_MAC_IPSEC_ADDSPD 1413 /* Add a XFRM policy */ -#define AUDIT_MAC_IPSEC_DELSPD 1414 /* Delete a XFRM policy */ +#define AUDIT_MAC_IPSEC_ADDSA 1411 /* Not used */ +#define AUDIT_MAC_IPSEC_DELSA 1412 /* Not used */ +#define AUDIT_MAC_IPSEC_ADDSPD 1413 /* Not used */ +#define AUDIT_MAC_IPSEC_DELSPD 1414 /* Not used */ +#define AUDIT_MAC_IPSEC_EVENT 1415 /* Audit an IPSec event */ #define AUDIT_FIRST_KERN_ANOM_MSG 1700 #define AUDIT_LAST_KERN_ANOM_MSG 1799 diff --git a/include/net/xfrm.h b/include/net/xfrm.h index a5f80bfbaaa4..760d2432be6b 100644 --- a/include/net/xfrm.h +++ b/include/net/xfrm.h @@ -12,6 +12,7 @@ #include #include #include +#include #include #include @@ -421,15 +422,46 @@ extern unsigned int xfrm_policy_count[XFRM_POLICY_MAX*2]; /* Audit Information */ struct xfrm_audit { - uid_t loginuid; + u32 loginuid; u32 secid; }; #ifdef CONFIG_AUDITSYSCALL -extern void xfrm_audit_log(uid_t auid, u32 secid, int type, int result, - struct xfrm_policy *xp, struct xfrm_state *x); +static inline struct audit_buffer *xfrm_audit_start(u32 auid, u32 sid) +{ + struct audit_buffer *audit_buf = NULL; + char *secctx; + u32 secctx_len; + + audit_buf = audit_log_start(current->audit_context, GFP_ATOMIC, + AUDIT_MAC_IPSEC_EVENT); + if (audit_buf == NULL) + return NULL; + + audit_log_format(audit_buf, "auid=%u", auid); + + if (sid != 0 && + security_secid_to_secctx(sid, &secctx, &secctx_len) == 0) { + audit_log_format(audit_buf, " subj=%s", secctx); + security_release_secctx(secctx, secctx_len); + } else + audit_log_task_context(audit_buf); + return audit_buf; +} + +extern void xfrm_audit_policy_add(struct xfrm_policy *xp, int result, + u32 auid, u32 sid); +extern void xfrm_audit_policy_delete(struct xfrm_policy *xp, int result, + u32 auid, u32 sid); +extern void xfrm_audit_state_add(struct xfrm_state *x, int result, + u32 auid, u32 sid); +extern void xfrm_audit_state_delete(struct xfrm_state *x, int result, + u32 auid, u32 sid); #else -#define xfrm_audit_log(a,s,t,r,p,x) do { ; } while (0) +#define xfrm_audit_policy_add(x, r, a, s) do { ; } while (0) +#define xfrm_audit_policy_delete(x, r, a, s) do { ; } while (0) +#define xfrm_audit_state_add(x, r, a, s) do { ; } while (0) +#define xfrm_audit_state_delete(x, r, a, s) do { ; } while (0) #endif /* CONFIG_AUDITSYSCALL */ static inline void xfrm_pol_hold(struct xfrm_policy *policy) diff --git a/net/key/af_key.c b/net/key/af_key.c index 17b2a6927f01..0241fff95137 100644 --- a/net/key/af_key.c +++ b/net/key/af_key.c @@ -27,7 +27,6 @@ #include #include #include -#include #include @@ -1454,8 +1453,8 @@ static int pfkey_add(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hdr, else err = xfrm_state_update(x); - xfrm_audit_log(audit_get_loginuid(current->audit_context), 0, - AUDIT_MAC_IPSEC_ADDSA, err ? 0 : 1, NULL, x); + xfrm_audit_state_add(x, err ? 0 : 1, + audit_get_loginuid(current->audit_context), 0); if (err < 0) { x->km.state = XFRM_STATE_DEAD; @@ -1508,8 +1507,8 @@ static int pfkey_delete(struct sock *sk, struct sk_buff *skb, struct sadb_msg *h c.event = XFRM_MSG_DELSA; km_state_notify(x, &c); out: - xfrm_audit_log(audit_get_loginuid(current->audit_context), 0, - AUDIT_MAC_IPSEC_DELSA, err ? 0 : 1, NULL, x); + xfrm_audit_state_delete(x, err ? 0 : 1, + audit_get_loginuid(current->audit_context), 0); xfrm_state_put(x); return err; @@ -2261,8 +2260,8 @@ static int pfkey_spdadd(struct sock *sk, struct sk_buff *skb, struct sadb_msg *h err = xfrm_policy_insert(pol->sadb_x_policy_dir-1, xp, hdr->sadb_msg_type != SADB_X_SPDUPDATE); - xfrm_audit_log(audit_get_loginuid(current->audit_context), 0, - AUDIT_MAC_IPSEC_ADDSPD, err ? 0 : 1, xp, NULL); + xfrm_audit_policy_add(xp, err ? 0 : 1, + audit_get_loginuid(current->audit_context), 0); if (err) goto out; @@ -2345,8 +2344,8 @@ static int pfkey_spddelete(struct sock *sk, struct sk_buff *skb, struct sadb_msg if (xp == NULL) return -ENOENT; - xfrm_audit_log(audit_get_loginuid(current->audit_context), 0, - AUDIT_MAC_IPSEC_DELSPD, err ? 0 : 1, xp, NULL); + xfrm_audit_policy_delete(xp, err ? 0 : 1, + audit_get_loginuid(current->audit_context), 0); if (err) goto out; @@ -2606,8 +2605,8 @@ static int pfkey_spdget(struct sock *sk, struct sk_buff *skb, struct sadb_msg *h return -ENOENT; if (delete) { - xfrm_audit_log(audit_get_loginuid(current->audit_context), 0, - AUDIT_MAC_IPSEC_DELSPD, err ? 0 : 1, xp, NULL); + xfrm_audit_policy_delete(xp, err ? 0 : 1, + audit_get_loginuid(current->audit_context), 0); if (err) goto out; diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index 6ab81b1d215e..36dd31c40f4a 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c @@ -23,7 +23,6 @@ #include #include #include -#include #include #include @@ -850,10 +849,9 @@ xfrm_policy_flush_secctx_check(u8 type, struct xfrm_audit *audit_info) continue; err = security_xfrm_policy_delete(pol); if (err) { - xfrm_audit_log(audit_info->loginuid, - audit_info->secid, - AUDIT_MAC_IPSEC_DELSPD, 0, - pol, NULL); + xfrm_audit_policy_delete(pol, 0, + audit_info->loginuid, + audit_info->secid); return err; } } @@ -865,10 +863,9 @@ xfrm_policy_flush_secctx_check(u8 type, struct xfrm_audit *audit_info) continue; err = security_xfrm_policy_delete(pol); if (err) { - xfrm_audit_log(audit_info->loginuid, - audit_info->secid, - AUDIT_MAC_IPSEC_DELSPD, - 0, pol, NULL); + xfrm_audit_policy_delete(pol, 0, + audit_info->loginuid, + audit_info->secid); return err; } } @@ -909,8 +906,8 @@ int xfrm_policy_flush(u8 type, struct xfrm_audit *audit_info) hlist_del(&pol->byidx); write_unlock_bh(&xfrm_policy_lock); - xfrm_audit_log(audit_info->loginuid, audit_info->secid, - AUDIT_MAC_IPSEC_DELSPD, 1, pol, NULL); + xfrm_audit_policy_delete(pol, 1, audit_info->loginuid, + audit_info->secid); xfrm_policy_kill(pol); killed++; @@ -930,11 +927,9 @@ int xfrm_policy_flush(u8 type, struct xfrm_audit *audit_info) hlist_del(&pol->byidx); write_unlock_bh(&xfrm_policy_lock); - xfrm_audit_log(audit_info->loginuid, - audit_info->secid, - AUDIT_MAC_IPSEC_DELSPD, 1, - pol, NULL); - + xfrm_audit_policy_delete(pol, 1, + audit_info->loginuid, + audit_info->secid); xfrm_policy_kill(pol); killed++; @@ -2150,123 +2145,6 @@ int xfrm_bundle_ok(struct xfrm_policy *pol, struct xfrm_dst *first, EXPORT_SYMBOL(xfrm_bundle_ok); -#ifdef CONFIG_AUDITSYSCALL -/* Audit addition and deletion of SAs and ipsec policy */ - -void xfrm_audit_log(uid_t auid, u32 sid, int type, int result, - struct xfrm_policy *xp, struct xfrm_state *x) -{ - - char *secctx; - u32 secctx_len; - struct xfrm_sec_ctx *sctx = NULL; - struct audit_buffer *audit_buf; - int family; - extern int audit_enabled; - - if (audit_enabled == 0) - return; - - BUG_ON((type == AUDIT_MAC_IPSEC_ADDSA || - type == AUDIT_MAC_IPSEC_DELSA) && !x); - BUG_ON((type == AUDIT_MAC_IPSEC_ADDSPD || - type == AUDIT_MAC_IPSEC_DELSPD) && !xp); - - audit_buf = audit_log_start(current->audit_context, GFP_ATOMIC, type); - if (audit_buf == NULL) - return; - - switch(type) { - case AUDIT_MAC_IPSEC_ADDSA: - audit_log_format(audit_buf, "SAD add: auid=%u", auid); - break; - case AUDIT_MAC_IPSEC_DELSA: - audit_log_format(audit_buf, "SAD delete: auid=%u", auid); - break; - case AUDIT_MAC_IPSEC_ADDSPD: - audit_log_format(audit_buf, "SPD add: auid=%u", auid); - break; - case AUDIT_MAC_IPSEC_DELSPD: - audit_log_format(audit_buf, "SPD delete: auid=%u", auid); - break; - default: - return; - } - - if (sid != 0 && - security_secid_to_secctx(sid, &secctx, &secctx_len) == 0) { - audit_log_format(audit_buf, " subj=%s", secctx); - security_release_secctx(secctx, secctx_len); - } else - audit_log_task_context(audit_buf); - - if (xp) { - family = xp->selector.family; - if (xp->security) - sctx = xp->security; - } else { - family = x->props.family; - if (x->security) - sctx = x->security; - } - - if (sctx) - audit_log_format(audit_buf, - " sec_alg=%u sec_doi=%u sec_obj=%s", - sctx->ctx_alg, sctx->ctx_doi, sctx->ctx_str); - - switch(family) { - case AF_INET: - { - struct in_addr saddr, daddr; - if (xp) { - saddr.s_addr = xp->selector.saddr.a4; - daddr.s_addr = xp->selector.daddr.a4; - } else { - saddr.s_addr = x->props.saddr.a4; - daddr.s_addr = x->id.daddr.a4; - } - audit_log_format(audit_buf, - " src=%u.%u.%u.%u dst=%u.%u.%u.%u", - NIPQUAD(saddr), NIPQUAD(daddr)); - } - break; - case AF_INET6: - { - struct in6_addr saddr6, daddr6; - if (xp) { - memcpy(&saddr6, xp->selector.saddr.a6, - sizeof(struct in6_addr)); - memcpy(&daddr6, xp->selector.daddr.a6, - sizeof(struct in6_addr)); - } else { - memcpy(&saddr6, x->props.saddr.a6, - sizeof(struct in6_addr)); - memcpy(&daddr6, x->id.daddr.a6, - sizeof(struct in6_addr)); - } - audit_log_format(audit_buf, - " src=" NIP6_FMT " dst=" NIP6_FMT, - NIP6(saddr6), NIP6(daddr6)); - } - break; - } - - if (x) - audit_log_format(audit_buf, " spi=%lu(0x%lx) protocol=%s", - (unsigned long)ntohl(x->id.spi), - (unsigned long)ntohl(x->id.spi), - x->id.proto == IPPROTO_AH ? "AH" : - (x->id.proto == IPPROTO_ESP ? - "ESP" : "IPCOMP")); - - audit_log_format(audit_buf, " res=%u", result); - audit_log_end(audit_buf); -} - -EXPORT_SYMBOL(xfrm_audit_log); -#endif /* CONFIG_AUDITSYSCALL */ - int xfrm_policy_register_afinfo(struct xfrm_policy_afinfo *afinfo) { int err = 0; @@ -2412,6 +2290,72 @@ void __init xfrm_init(void) xfrm_input_init(); } +#ifdef CONFIG_AUDITSYSCALL +static inline void xfrm_audit_common_policyinfo(struct xfrm_policy *xp, + struct audit_buffer *audit_buf) +{ + if (xp->security) + audit_log_format(audit_buf, " sec_alg=%u sec_doi=%u sec_obj=%s", + xp->security->ctx_alg, xp->security->ctx_doi, + xp->security->ctx_str); + + switch(xp->selector.family) { + case AF_INET: + audit_log_format(audit_buf, " src=%u.%u.%u.%u dst=%u.%u.%u.%u", + NIPQUAD(xp->selector.saddr.a4), + NIPQUAD(xp->selector.daddr.a4)); + break; + case AF_INET6: + { + struct in6_addr saddr6, daddr6; + + memcpy(&saddr6, xp->selector.saddr.a6, + sizeof(struct in6_addr)); + memcpy(&daddr6, xp->selector.daddr.a6, + sizeof(struct in6_addr)); + audit_log_format(audit_buf, + " src=" NIP6_FMT " dst=" NIP6_FMT, + NIP6(saddr6), NIP6(daddr6)); + } + break; + } +} + +void +xfrm_audit_policy_add(struct xfrm_policy *xp, int result, u32 auid, u32 sid) +{ + struct audit_buffer *audit_buf; + extern int audit_enabled; + + if (audit_enabled == 0) + return; + audit_buf = xfrm_audit_start(sid, auid); + if (audit_buf == NULL) + return; + audit_log_format(audit_buf, " op=SPD-add res=%u", result); + xfrm_audit_common_policyinfo(xp, audit_buf); + audit_log_end(audit_buf); +} +EXPORT_SYMBOL_GPL(xfrm_audit_policy_add); + +void +xfrm_audit_policy_delete(struct xfrm_policy *xp, int result, u32 auid, u32 sid) +{ + struct audit_buffer *audit_buf; + extern int audit_enabled; + + if (audit_enabled == 0) + return; + audit_buf = xfrm_audit_start(sid, auid); + if (audit_buf == NULL) + return; + audit_log_format(audit_buf, " op=SPD-delete res=%u", result); + xfrm_audit_common_policyinfo(xp, audit_buf); + audit_log_end(audit_buf); +} +EXPORT_SYMBOL_GPL(xfrm_audit_policy_delete); +#endif + #ifdef CONFIG_XFRM_MIGRATE static int xfrm_migrate_selector_match(struct xfrm_selector *sel_cmp, struct xfrm_selector *sel_tgt) diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c index d4356e6f7f9b..15734adc9367 100644 --- a/net/xfrm/xfrm_state.c +++ b/net/xfrm/xfrm_state.c @@ -19,7 +19,6 @@ #include #include #include -#include #include #include "xfrm_hash.h" @@ -301,8 +300,8 @@ expired: if (!err && x->id.spi) km_state_expired(x, 1, 0); - xfrm_audit_log(audit_get_loginuid(current->audit_context), 0, - AUDIT_MAC_IPSEC_DELSA, err ? 0 : 1, NULL, x); + xfrm_audit_state_delete(x, err ? 0 : 1, + audit_get_loginuid(current->audit_context), 0); out: spin_unlock(&x->lock); @@ -403,11 +402,9 @@ xfrm_state_flush_secctx_check(u8 proto, struct xfrm_audit *audit_info) hlist_for_each_entry(x, entry, xfrm_state_bydst+i, bydst) { if (xfrm_id_proto_match(x->id.proto, proto) && (err = security_xfrm_state_delete(x)) != 0) { - xfrm_audit_log(audit_info->loginuid, - audit_info->secid, - AUDIT_MAC_IPSEC_DELSA, - 0, NULL, x); - + xfrm_audit_state_delete(x, 0, + audit_info->loginuid, + audit_info->secid); return err; } } @@ -443,10 +440,9 @@ restart: spin_unlock_bh(&xfrm_state_lock); err = xfrm_state_delete(x); - xfrm_audit_log(audit_info->loginuid, - audit_info->secid, - AUDIT_MAC_IPSEC_DELSA, - err ? 0 : 1, NULL, x); + xfrm_audit_state_delete(x, err ? 0 : 1, + audit_info->loginuid, + audit_info->secid); xfrm_state_put(x); spin_lock_bh(&xfrm_state_lock); @@ -1821,3 +1817,72 @@ void __init xfrm_state_init(void) INIT_WORK(&xfrm_state_gc_work, xfrm_state_gc_task); } +#ifdef CONFIG_AUDITSYSCALL +static inline void xfrm_audit_common_stateinfo(struct xfrm_state *x, + struct audit_buffer *audit_buf) +{ + if (x->security) + audit_log_format(audit_buf, " sec_alg=%u sec_doi=%u sec_obj=%s", + x->security->ctx_alg, x->security->ctx_doi, + x->security->ctx_str); + + switch(x->props.family) { + case AF_INET: + audit_log_format(audit_buf, " src=%u.%u.%u.%u dst=%u.%u.%u.%u", + NIPQUAD(x->props.saddr.a4), + NIPQUAD(x->id.daddr.a4)); + break; + case AF_INET6: + { + struct in6_addr saddr6, daddr6; + + memcpy(&saddr6, x->props.saddr.a6, + sizeof(struct in6_addr)); + memcpy(&daddr6, x->id.daddr.a6, + sizeof(struct in6_addr)); + audit_log_format(audit_buf, + " src=" NIP6_FMT " dst=" NIP6_FMT, + NIP6(saddr6), NIP6(daddr6)); + } + break; + } +} + +void +xfrm_audit_state_add(struct xfrm_state *x, int result, u32 auid, u32 sid) +{ + struct audit_buffer *audit_buf; + extern int audit_enabled; + + if (audit_enabled == 0) + return; + audit_buf = xfrm_audit_start(sid, auid); + if (audit_buf == NULL) + return; + audit_log_format(audit_buf, " op=SAD-add res=%u",result); + xfrm_audit_common_stateinfo(x, audit_buf); + audit_log_format(audit_buf, " spi=%lu(0x%lx)", + (unsigned long)x->id.spi, (unsigned long)x->id.spi); + audit_log_end(audit_buf); +} +EXPORT_SYMBOL_GPL(xfrm_audit_state_add); + +void +xfrm_audit_state_delete(struct xfrm_state *x, int result, u32 auid, u32 sid) +{ + struct audit_buffer *audit_buf; + extern int audit_enabled; + + if (audit_enabled == 0) + return; + audit_buf = xfrm_audit_start(sid, auid); + if (audit_buf == NULL) + return; + audit_log_format(audit_buf, " op=SAD-delete res=%u",result); + xfrm_audit_common_stateinfo(x, audit_buf); + audit_log_format(audit_buf, " spi=%lu(0x%lx)", + (unsigned long)x->id.spi, (unsigned long)x->id.spi); + audit_log_end(audit_buf); +} +EXPORT_SYMBOL_GPL(xfrm_audit_state_delete); +#endif /* CONFIG_AUDITSYSCALL */ diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c index 9e516f5cbb5e..0d81c0f23919 100644 --- a/net/xfrm/xfrm_user.c +++ b/net/xfrm/xfrm_user.c @@ -30,7 +30,6 @@ #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) #include #endif -#include static inline int alg_len(struct xfrm_algo *alg) { @@ -371,8 +370,8 @@ static int xfrm_add_sa(struct sk_buff *skb, struct nlmsghdr *nlh, else err = xfrm_state_update(x); - xfrm_audit_log(NETLINK_CB(skb).loginuid, NETLINK_CB(skb).sid, - AUDIT_MAC_IPSEC_ADDSA, err ? 0 : 1, NULL, x); + xfrm_audit_state_add(x, err ? 0 : 1, NETLINK_CB(skb).loginuid, + NETLINK_CB(skb).sid); if (err < 0) { x->km.state = XFRM_STATE_DEAD; @@ -451,8 +450,8 @@ static int xfrm_del_sa(struct sk_buff *skb, struct nlmsghdr *nlh, km_state_notify(x, &c); out: - xfrm_audit_log(NETLINK_CB(skb).loginuid, NETLINK_CB(skb).sid, - AUDIT_MAC_IPSEC_DELSA, err ? 0 : 1, NULL, x); + xfrm_audit_state_delete(x, err ? 0 : 1, NETLINK_CB(skb).loginuid, + NETLINK_CB(skb).sid); xfrm_state_put(x); return err; } @@ -1067,8 +1066,8 @@ static int xfrm_add_policy(struct sk_buff *skb, struct nlmsghdr *nlh, * a type XFRM_MSG_UPDPOLICY - JHS */ excl = nlh->nlmsg_type == XFRM_MSG_NEWPOLICY; err = xfrm_policy_insert(p->dir, xp, excl); - xfrm_audit_log(NETLINK_CB(skb).loginuid, NETLINK_CB(skb).sid, - AUDIT_MAC_IPSEC_DELSPD, err ? 0 : 1, xp, NULL); + xfrm_audit_policy_add(xp, err ? 0 : 1, NETLINK_CB(skb).loginuid, + NETLINK_CB(skb).sid); if (err) { security_xfrm_policy_free(xp); @@ -1290,8 +1289,9 @@ static int xfrm_get_policy(struct sk_buff *skb, struct nlmsghdr *nlh, NETLINK_CB(skb).pid); } } else { - xfrm_audit_log(NETLINK_CB(skb).loginuid, NETLINK_CB(skb).sid, - AUDIT_MAC_IPSEC_DELSPD, err ? 0 : 1, xp, NULL); + xfrm_audit_policy_delete(xp, err ? 0 : 1, + NETLINK_CB(skb).loginuid, + NETLINK_CB(skb).sid); if (err != 0) goto out; @@ -1523,8 +1523,8 @@ static int xfrm_add_pol_expire(struct sk_buff *skb, struct nlmsghdr *nlh, err = 0; if (up->hard) { xfrm_policy_delete(xp, p->dir); - xfrm_audit_log(NETLINK_CB(skb).loginuid, NETLINK_CB(skb).sid, - AUDIT_MAC_IPSEC_DELSPD, 1, xp, NULL); + xfrm_audit_policy_delete(xp, 1, NETLINK_CB(skb).loginuid, + NETLINK_CB(skb).sid); } else { // reset the timers here? @@ -1559,8 +1559,8 @@ static int xfrm_add_sa_expire(struct sk_buff *skb, struct nlmsghdr *nlh, if (ue->hard) { __xfrm_state_delete(x); - xfrm_audit_log(NETLINK_CB(skb).loginuid, NETLINK_CB(skb).sid, - AUDIT_MAC_IPSEC_DELSA, 1, NULL, x); + xfrm_audit_state_delete(x, 1, NETLINK_CB(skb).loginuid, + NETLINK_CB(skb).sid); } err = 0; out: -- cgit v1.2.3 From 772698f6362680b65211f7efc68121f1e4c28aa5 Mon Sep 17 00:00:00 2001 From: "Eric W. Biederman" Date: Wed, 12 Sep 2007 11:55:17 +0200 Subject: [NET]: Add a network namespace parameter to tasks This is the network namespace from which all which all sockets and anything else under user control ultimately get their network namespace parameters. Signed-off-by: Eric W. Biederman Signed-off-by: David S. Miller --- include/linux/init_task.h | 2 ++ include/linux/nsproxy.h | 1 + 2 files changed, 3 insertions(+) (limited to 'include/linux') diff --git a/include/linux/init_task.h b/include/linux/init_task.h index f8abfa349ef9..e2c1ffcff62c 100644 --- a/include/linux/init_task.h +++ b/include/linux/init_task.h @@ -9,6 +9,7 @@ #include #include #include +#include #define INIT_FDTABLE \ { \ @@ -78,6 +79,7 @@ extern struct nsproxy init_nsproxy; .nslock = __SPIN_LOCK_UNLOCKED(nsproxy.nslock), \ .uts_ns = &init_uts_ns, \ .mnt_ns = NULL, \ + .net_ns = &init_net, \ INIT_IPC_NS(ipc_ns) \ .user_ns = &init_user_ns, \ } diff --git a/include/linux/nsproxy.h b/include/linux/nsproxy.h index ce06188b7a56..bec4485e3d76 100644 --- a/include/linux/nsproxy.h +++ b/include/linux/nsproxy.h @@ -29,6 +29,7 @@ struct nsproxy { struct mnt_namespace *mnt_ns; struct pid_namespace *pid_ns; struct user_namespace *user_ns; + struct net *net_ns; }; extern struct nsproxy init_nsproxy; -- cgit v1.2.3 From 4a1c537113cdc688aabc3fb9bb6ed18ec821c779 Mon Sep 17 00:00:00 2001 From: "Eric W. Biederman" Date: Wed, 12 Sep 2007 11:56:32 +0200 Subject: [NET]: Add a network namespace tag to struct net_device Please note that network devices do not increase the count count on the network namespace. The are inside the network namespace and so the network namespace tag is in the nature of a back pointer and so getting and putting the network namespace is unnecessary. Signed-off-by: Eric W. Biederman Signed-off-by: David S. Miller --- include/linux/netdevice.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'include/linux') diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 8f00bdf95ef4..dc3c15b726bc 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -41,6 +41,7 @@ #include #include +struct net; struct vlan_group; struct ethtool_ops; struct netpoll_info; @@ -663,6 +664,9 @@ struct net_device void (*poll_controller)(struct net_device *dev); #endif + /* Network namespace this network device is inside */ + struct net *nd_net; + /* bridge stuff */ struct net_bridge_port *br_port; /* macvlan */ -- cgit v1.2.3 From 457c4cbc5a3dde259d2a1f15d5f9785290397267 Mon Sep 17 00:00:00 2001 From: "Eric W. Biederman" Date: Wed, 12 Sep 2007 12:01:34 +0200 Subject: [NET]: Make /proc/net per network namespace This patch makes /proc/net per network namespace. It modifies the global variables proc_net and proc_net_stat to be per network namespace. The proc_net file helpers are modified to take a network namespace argument, and all of their callers are fixed to pass &init_net for that argument. This ensures that all of the /proc/net files are only visible and usable in the initial network namespace until the code behind them has been updated to be handle multiple network namespaces. Making /proc/net per namespace is necessary as at least some files in /proc/net depend upon the set of network devices which is per network namespace, and even more files in /proc/net have contents that are relevant to a single network namespace. Signed-off-by: Eric W. Biederman Signed-off-by: David S. Miller --- drivers/isdn/divert/divert_procfs.c | 7 ++-- drivers/isdn/hardware/eicon/diva_didd.c | 5 ++- drivers/isdn/hysdn/hysdn_procconf.c | 5 ++- drivers/net/bonding/bond_main.c | 7 ++-- drivers/net/hamradio/bpqether.c | 5 ++- drivers/net/hamradio/scc.c | 5 ++- drivers/net/hamradio/yam.c | 5 ++- drivers/net/ibmveth.c | 7 ++-- drivers/net/pppoe.c | 5 ++- drivers/net/pppol2tp.c | 5 ++- drivers/net/tokenring/lanstreamer.c | 5 ++- drivers/net/tokenring/olympic.c | 9 +++-- drivers/net/wireless/hostap/hostap_main.c | 7 ++-- drivers/net/wireless/strip.c | 5 ++- fs/proc/Makefile | 1 + fs/proc/internal.h | 5 +++ fs/proc/root.c | 8 ++-- include/linux/proc_fs.h | 44 ++++++++++------------ include/net/net_namespace.h | 5 +++ net/802/tr.c | 3 +- net/8021q/vlanproc.c | 5 ++- net/appletalk/atalk_proc.c | 7 ++-- net/atm/proc.c | 5 ++- net/ax25/af_ax25.c | 13 ++++--- net/core/dev.c | 19 +++++----- net/core/dev_mcast.c | 3 +- net/core/neighbour.c | 3 +- net/core/pktgen.c | 9 +++-- net/core/sock.c | 3 +- net/dccp/probe.c | 7 ++-- net/decnet/af_decnet.c | 5 ++- net/decnet/dn_dev.c | 5 ++- net/decnet/dn_neigh.c | 5 ++- net/decnet/dn_route.c | 5 ++- net/ieee80211/ieee80211_module.c | 7 ++-- net/ipv4/arp.c | 3 +- net/ipv4/fib_hash.c | 5 ++- net/ipv4/fib_trie.c | 17 +++++---- net/ipv4/igmp.c | 5 ++- net/ipv4/ipconfig.c | 3 +- net/ipv4/ipmr.c | 5 ++- net/ipv4/ipvs/ip_vs_app.c | 5 ++- net/ipv4/ipvs/ip_vs_conn.c | 5 ++- net/ipv4/ipvs/ip_vs_ctl.c | 9 +++-- net/ipv4/ipvs/ip_vs_lblcr.c | 5 ++- net/ipv4/netfilter/ip_queue.c | 8 ++-- net/ipv4/netfilter/ipt_CLUSTERIP.c | 3 +- net/ipv4/netfilter/ipt_recent.c | 5 ++- .../netfilter/nf_conntrack_l3proto_ipv4_compat.c | 17 +++++---- net/ipv4/proc.c | 11 +++--- net/ipv4/raw.c | 5 ++- net/ipv4/route.c | 7 ++-- net/ipv4/tcp_ipv4.c | 5 ++- net/ipv4/tcp_probe.c | 7 ++-- net/ipv4/udp.c | 5 ++- net/ipv6/addrconf.c | 7 ++-- net/ipv6/anycast.c | 5 ++- net/ipv6/ip6_flowlabel.c | 5 ++- net/ipv6/mcast.c | 9 +++-- net/ipv6/netfilter/ip6_queue.c | 7 ++-- net/ipv6/proc.c | 17 +++++---- net/ipv6/raw.c | 5 ++- net/ipv6/route.c | 9 +++-- net/ipx/ipx_proc.c | 7 ++-- net/irda/irproc.c | 5 ++- net/key/af_key.c | 5 ++- net/llc/llc_proc.c | 7 ++-- net/netfilter/core.c | 3 +- net/netfilter/nf_conntrack_expect.c | 5 ++- net/netfilter/nf_conntrack_standalone.c | 13 ++++--- net/netfilter/x_tables.c | 17 +++++---- net/netfilter/xt_hashlimit.c | 11 +++--- net/netlink/af_netlink.c | 3 +- net/netrom/af_netrom.c | 13 ++++--- net/packet/af_packet.c | 5 ++- net/rose/af_rose.c | 17 +++++---- net/rxrpc/af_rxrpc.c | 9 +++-- net/sched/sch_api.c | 3 +- net/sctp/protocol.c | 5 ++- net/sunrpc/stats.c | 5 ++- net/unix/af_unix.c | 5 ++- net/wanrouter/wanproc.c | 7 ++-- net/wireless/wext.c | 3 +- net/x25/x25_proc.c | 7 ++-- 84 files changed, 342 insertions(+), 261 deletions(-) (limited to 'include/linux') diff --git a/drivers/isdn/divert/divert_procfs.c b/drivers/isdn/divert/divert_procfs.c index 559a0d0244cf..4fd4c46892e3 100644 --- a/drivers/isdn/divert/divert_procfs.c +++ b/drivers/isdn/divert/divert_procfs.c @@ -17,6 +17,7 @@ #include #endif #include +#include #include "isdn_divert.h" @@ -284,12 +285,12 @@ divert_dev_init(void) init_waitqueue_head(&rd_queue); #ifdef CONFIG_PROC_FS - isdn_proc_entry = proc_mkdir("net/isdn", NULL); + isdn_proc_entry = proc_mkdir("isdn", init_net.proc_net); if (!isdn_proc_entry) return (-1); isdn_divert_entry = create_proc_entry("divert", S_IFREG | S_IRUGO, isdn_proc_entry); if (!isdn_divert_entry) { - remove_proc_entry("net/isdn", NULL); + remove_proc_entry("isdn", init_net.proc_net); return (-1); } isdn_divert_entry->proc_fops = &isdn_fops; @@ -309,7 +310,7 @@ divert_dev_deinit(void) #ifdef CONFIG_PROC_FS remove_proc_entry("divert", isdn_proc_entry); - remove_proc_entry("net/isdn", NULL); + remove_proc_entry("isdn", init_net.proc_net); #endif /* CONFIG_PROC_FS */ return (0); diff --git a/drivers/isdn/hardware/eicon/diva_didd.c b/drivers/isdn/hardware/eicon/diva_didd.c index d755d904e62c..993b14cf1778 100644 --- a/drivers/isdn/hardware/eicon/diva_didd.c +++ b/drivers/isdn/hardware/eicon/diva_didd.c @@ -15,6 +15,7 @@ #include #include #include +#include #include "platform.h" #include "di_defs.h" @@ -86,7 +87,7 @@ proc_read(char *page, char **start, off_t off, int count, int *eof, static int DIVA_INIT_FUNCTION create_proc(void) { - proc_net_eicon = proc_mkdir("net/eicon", NULL); + proc_net_eicon = proc_mkdir("eicon", init_net.proc_net); if (proc_net_eicon) { if ((proc_didd = @@ -102,7 +103,7 @@ static int DIVA_INIT_FUNCTION create_proc(void) static void remove_proc(void) { remove_proc_entry(DRIVERLNAME, proc_net_eicon); - remove_proc_entry("net/eicon", NULL); + remove_proc_entry("eicon", init_net.proc_net); } static int DIVA_INIT_FUNCTION divadidd_init(void) diff --git a/drivers/isdn/hysdn/hysdn_procconf.c b/drivers/isdn/hysdn/hysdn_procconf.c index dc477e0aab0e..27d890b48f88 100644 --- a/drivers/isdn/hysdn/hysdn_procconf.c +++ b/drivers/isdn/hysdn/hysdn_procconf.c @@ -16,6 +16,7 @@ #include #include #include +#include #include "hysdn_defs.h" @@ -392,7 +393,7 @@ hysdn_procconf_init(void) hysdn_card *card; unsigned char conf_name[20]; - hysdn_proc_entry = proc_mkdir(PROC_SUBDIR_NAME, proc_net); + hysdn_proc_entry = proc_mkdir(PROC_SUBDIR_NAME, init_net.proc_net); if (!hysdn_proc_entry) { printk(KERN_ERR "HYSDN: unable to create hysdn subdir\n"); return (-1); @@ -437,5 +438,5 @@ hysdn_procconf_release(void) card = card->next; /* point to next card */ } - remove_proc_entry(PROC_SUBDIR_NAME, proc_net); + remove_proc_entry(PROC_SUBDIR_NAME, init_net.proc_net); } diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 1afda3230def..5de648f90a45 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -75,6 +75,7 @@ #include #include #include +#include #include "bonding.h" #include "bond_3ad.h" #include "bond_alb.h" @@ -3144,7 +3145,7 @@ static void bond_create_proc_dir(void) { int len = strlen(DRV_NAME); - for (bond_proc_dir = proc_net->subdir; bond_proc_dir; + for (bond_proc_dir = init_net.proc_net->subdir; bond_proc_dir; bond_proc_dir = bond_proc_dir->next) { if ((bond_proc_dir->namelen == len) && !memcmp(bond_proc_dir->name, DRV_NAME, len)) { @@ -3153,7 +3154,7 @@ static void bond_create_proc_dir(void) } if (!bond_proc_dir) { - bond_proc_dir = proc_mkdir(DRV_NAME, proc_net); + bond_proc_dir = proc_mkdir(DRV_NAME, init_net.proc_net); if (bond_proc_dir) { bond_proc_dir->owner = THIS_MODULE; } else { @@ -3188,7 +3189,7 @@ static void bond_destroy_proc_dir(void) bond_proc_dir->owner = NULL; } } else { - remove_proc_entry(DRV_NAME, proc_net); + remove_proc_entry(DRV_NAME, init_net.proc_net); bond_proc_dir = NULL; } } diff --git a/drivers/net/hamradio/bpqether.c b/drivers/net/hamradio/bpqether.c index cc0ee93669ea..1699d42d13ca 100644 --- a/drivers/net/hamradio/bpqether.c +++ b/drivers/net/hamradio/bpqether.c @@ -83,6 +83,7 @@ #include #include +#include #include @@ -594,7 +595,7 @@ static int bpq_device_event(struct notifier_block *this,unsigned long event, voi static int __init bpq_init_driver(void) { #ifdef CONFIG_PROC_FS - if (!proc_net_fops_create("bpqether", S_IRUGO, &bpq_info_fops)) { + if (!proc_net_fops_create(&init_net, "bpqether", S_IRUGO, &bpq_info_fops)) { printk(KERN_ERR "bpq: cannot create /proc/net/bpqether entry.\n"); return -ENOENT; @@ -618,7 +619,7 @@ static void __exit bpq_cleanup_driver(void) unregister_netdevice_notifier(&bpq_dev_notifier); - proc_net_remove("bpqether"); + proc_net_remove(&init_net, "bpqether"); rtnl_lock(); while (!list_empty(&bpq_devices)) { diff --git a/drivers/net/hamradio/scc.c b/drivers/net/hamradio/scc.c index 6fdaad5a4577..39b3b82aa4a4 100644 --- a/drivers/net/hamradio/scc.c +++ b/drivers/net/hamradio/scc.c @@ -174,6 +174,7 @@ #include #include +#include #include #include @@ -2114,7 +2115,7 @@ static int __init scc_init_driver (void) } rtnl_unlock(); - proc_net_fops_create("z8530drv", 0, &scc_net_seq_fops); + proc_net_fops_create(&init_net, "z8530drv", 0, &scc_net_seq_fops); return 0; } @@ -2169,7 +2170,7 @@ static void __exit scc_cleanup_driver(void) if (Vector_Latch) release_region(Vector_Latch, 1); - proc_net_remove("z8530drv"); + proc_net_remove(&init_net, "z8530drv"); } MODULE_AUTHOR("Joerg Reuter "); diff --git a/drivers/net/hamradio/yam.c b/drivers/net/hamradio/yam.c index 467559debfd6..401724ddafcd 100644 --- a/drivers/net/hamradio/yam.c +++ b/drivers/net/hamradio/yam.c @@ -65,6 +65,7 @@ #include #include #include +#include #include #include @@ -1142,7 +1143,7 @@ static int __init yam_init_driver(void) yam_timer.expires = jiffies + HZ / 100; add_timer(&yam_timer); - proc_net_fops_create("yam", S_IRUGO, &yam_info_fops); + proc_net_fops_create(&init_net, "yam", S_IRUGO, &yam_info_fops); return 0; error: while (--i >= 0) { @@ -1174,7 +1175,7 @@ static void __exit yam_cleanup_driver(void) kfree(p); } - proc_net_remove("yam"); + proc_net_remove(&init_net, "yam"); } /* --------------------------------------------------------------------- */ diff --git a/drivers/net/ibmveth.c b/drivers/net/ibmveth.c index 78e28ada1e21..0c35d72f5f8d 100644 --- a/drivers/net/ibmveth.c +++ b/drivers/net/ibmveth.c @@ -47,6 +47,7 @@ #include #include #include +#include #include #include #include @@ -97,7 +98,7 @@ static void ibmveth_rxq_harvest_buffer(struct ibmveth_adapter *adapter); static struct kobj_type ktype_veth_pool; #ifdef CONFIG_PROC_FS -#define IBMVETH_PROC_DIR "net/ibmveth" +#define IBMVETH_PROC_DIR "ibmveth" static struct proc_dir_entry *ibmveth_proc_dir; #endif @@ -1091,7 +1092,7 @@ static int __devexit ibmveth_remove(struct vio_dev *dev) #ifdef CONFIG_PROC_FS static void ibmveth_proc_register_driver(void) { - ibmveth_proc_dir = proc_mkdir(IBMVETH_PROC_DIR, NULL); + ibmveth_proc_dir = proc_mkdir(IBMVETH_PROC_DIR, init_net.proc_net); if (ibmveth_proc_dir) { SET_MODULE_OWNER(ibmveth_proc_dir); } @@ -1099,7 +1100,7 @@ static void ibmveth_proc_register_driver(void) static void ibmveth_proc_unregister_driver(void) { - remove_proc_entry(IBMVETH_PROC_DIR, NULL); + remove_proc_entry(IBMVETH_PROC_DIR, init_net.proc_net); } static void *ibmveth_seq_start(struct seq_file *seq, loff_t *pos) diff --git a/drivers/net/pppoe.c b/drivers/net/pppoe.c index 9b30cd600a64..ee8ce195c538 100644 --- a/drivers/net/pppoe.c +++ b/drivers/net/pppoe.c @@ -78,6 +78,7 @@ #include #include +#include #include #include @@ -1042,7 +1043,7 @@ static int __init pppoe_proc_init(void) { struct proc_dir_entry *p; - p = create_proc_entry("net/pppoe", S_IRUGO, NULL); + p = create_proc_entry("pppoe", S_IRUGO, init_net.proc_net); if (!p) return -ENOMEM; @@ -1113,7 +1114,7 @@ static void __exit pppoe_exit(void) dev_remove_pack(&pppoes_ptype); dev_remove_pack(&pppoed_ptype); unregister_netdevice_notifier(&pppoe_notifier); - remove_proc_entry("net/pppoe", NULL); + remove_proc_entry("pppoe", init_net.proc_net); proto_unregister(&pppoe_sk_proto); } diff --git a/drivers/net/pppol2tp.c b/drivers/net/pppol2tp.c index abe91cb595f4..2eb424ba58e5 100644 --- a/drivers/net/pppol2tp.c +++ b/drivers/net/pppol2tp.c @@ -91,6 +91,7 @@ #include #include #include +#include #include #include #include @@ -2444,7 +2445,7 @@ static int __init pppol2tp_init(void) goto out_unregister_pppol2tp_proto; #ifdef CONFIG_PROC_FS - pppol2tp_proc = create_proc_entry("pppol2tp", 0, proc_net); + pppol2tp_proc = create_proc_entry("pppol2tp", 0, init_net.proc_net); if (!pppol2tp_proc) { err = -ENOMEM; goto out_unregister_pppox_proto; @@ -2469,7 +2470,7 @@ static void __exit pppol2tp_exit(void) unregister_pppox_proto(PX_PROTO_OL2TP); #ifdef CONFIG_PROC_FS - remove_proc_entry("pppol2tp", proc_net); + remove_proc_entry("pppol2tp", init_net.proc_net); #endif proto_unregister(&pppol2tp_sk_proto); } diff --git a/drivers/net/tokenring/lanstreamer.c b/drivers/net/tokenring/lanstreamer.c index 5d849c089a3b..fc4495581f96 100644 --- a/drivers/net/tokenring/lanstreamer.c +++ b/drivers/net/tokenring/lanstreamer.c @@ -123,6 +123,7 @@ #include #include +#include #include #include @@ -250,7 +251,7 @@ static int __devinit streamer_init_one(struct pci_dev *pdev, #if STREAMER_NETWORK_MONITOR #ifdef CONFIG_PROC_FS if (!dev_streamer) - create_proc_read_entry("net/streamer_tr", 0, 0, + create_proc_read_entry("streamer_tr", 0, init_net.proc_net, streamer_proc_info, NULL); streamer_priv->next = dev_streamer; dev_streamer = streamer_priv; @@ -423,7 +424,7 @@ static void __devexit streamer_remove_one(struct pci_dev *pdev) } } if (!dev_streamer) - remove_proc_entry("net/streamer_tr", NULL); + remove_proc_entry("streamer_tr", init_net.proc_net); } #endif #endif diff --git a/drivers/net/tokenring/olympic.c b/drivers/net/tokenring/olympic.c index 09b3cfb8e809..c323101a895b 100644 --- a/drivers/net/tokenring/olympic.c +++ b/drivers/net/tokenring/olympic.c @@ -102,6 +102,7 @@ #include #include +#include #include #include @@ -268,9 +269,9 @@ static int __devinit olympic_probe(struct pci_dev *pdev, const struct pci_device printk("Olympic: %s registered as: %s\n",olympic_priv->olympic_card_name,dev->name); if (olympic_priv->olympic_network_monitor) { /* Must go after register_netdev as we need the device name */ char proc_name[20] ; - strcpy(proc_name,"net/olympic_") ; + strcpy(proc_name,"olympic_") ; strcat(proc_name,dev->name) ; - create_proc_read_entry(proc_name,0,NULL,olympic_proc_info,(void *)dev) ; + create_proc_read_entry(proc_name,0,init_net.proc_net,olympic_proc_info,(void *)dev) ; printk("Olympic: Network Monitor information: /proc/%s\n",proc_name); } return 0 ; @@ -1752,9 +1753,9 @@ static void __devexit olympic_remove_one(struct pci_dev *pdev) if (olympic_priv->olympic_network_monitor) { char proc_name[20] ; - strcpy(proc_name,"net/olympic_") ; + strcpy(proc_name,"olympic_") ; strcat(proc_name,dev->name) ; - remove_proc_entry(proc_name,NULL); + remove_proc_entry(proc_name,init_net.proc_net); } unregister_netdev(dev) ; iounmap(olympic_priv->olympic_mmio) ; diff --git a/drivers/net/wireless/hostap/hostap_main.c b/drivers/net/wireless/hostap/hostap_main.c index 446de51bab74..9a470e80ca24 100644 --- a/drivers/net/wireless/hostap/hostap_main.c +++ b/drivers/net/wireless/hostap/hostap_main.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -1093,8 +1094,8 @@ struct proc_dir_entry *hostap_proc; static int __init hostap_init(void) { - if (proc_net != NULL) { - hostap_proc = proc_mkdir("hostap", proc_net); + if (init_net.proc_net != NULL) { + hostap_proc = proc_mkdir("hostap", init_net.proc_net); if (!hostap_proc) printk(KERN_WARNING "Failed to mkdir " "/proc/net/hostap\n"); @@ -1109,7 +1110,7 @@ static void __exit hostap_exit(void) { if (hostap_proc != NULL) { hostap_proc = NULL; - remove_proc_entry("hostap", proc_net); + remove_proc_entry("hostap", init_net.proc_net); } } diff --git a/drivers/net/wireless/strip.c b/drivers/net/wireless/strip.c index ef32a5c1e818..edb214e8c744 100644 --- a/drivers/net/wireless/strip.c +++ b/drivers/net/wireless/strip.c @@ -107,6 +107,7 @@ static const char StripVersion[] = "1.3A-STUART.CHESHIRE"; #include #include #include +#include #include #include @@ -2787,7 +2788,7 @@ static int __init strip_init_driver(void) /* * Register the status file with /proc */ - proc_net_fops_create("strip", S_IFREG | S_IRUGO, &strip_seq_fops); + proc_net_fops_create(&init_net, "strip", S_IFREG | S_IRUGO, &strip_seq_fops); return status; } @@ -2809,7 +2810,7 @@ static void __exit strip_exit_driver(void) } /* Unregister with the /proc/net file here. */ - proc_net_remove("strip"); + proc_net_remove(&init_net, "strip"); if ((i = tty_unregister_ldisc(N_STRIP))) printk(KERN_ERR "STRIP: can't unregister line discipline (err = %d)\n", i); diff --git a/fs/proc/Makefile b/fs/proc/Makefile index bce38e3f06cb..ebaba0213546 100644 --- a/fs/proc/Makefile +++ b/fs/proc/Makefile @@ -11,6 +11,7 @@ proc-y += inode.o root.o base.o generic.o array.o \ proc_tty.o proc_misc.o proc-$(CONFIG_PROC_SYSCTL) += proc_sysctl.o +proc-$(CONFIG_NET) += proc_net.o proc-$(CONFIG_PROC_KCORE) += kcore.o proc-$(CONFIG_PROC_VMCORE) += vmcore.o proc-$(CONFIG_PROC_DEVICETREE) += proc_devtree.o diff --git a/fs/proc/internal.h b/fs/proc/internal.h index b215c3524fa6..1820eb2ef762 100644 --- a/fs/proc/internal.h +++ b/fs/proc/internal.h @@ -16,6 +16,11 @@ extern int proc_sys_init(void); #else static inline void proc_sys_init(void) { } #endif +#ifdef CONFIG_NET +extern int proc_net_init(void); +#else +static inline int proc_net_init(void) { return 0; } +#endif struct vmalloc_info { unsigned long used; diff --git a/fs/proc/root.c b/fs/proc/root.c index 41f17037f738..cf3046638b09 100644 --- a/fs/proc/root.c +++ b/fs/proc/root.c @@ -21,7 +21,7 @@ #include "internal.h" -struct proc_dir_entry *proc_net, *proc_net_stat, *proc_bus, *proc_root_fs, *proc_root_driver; +struct proc_dir_entry *proc_bus, *proc_root_fs, *proc_root_driver; static int proc_get_sb(struct file_system_type *fs_type, int flags, const char *dev_name, void *data, struct vfsmount *mnt) @@ -61,8 +61,8 @@ void __init proc_root_init(void) return; } proc_misc_init(); - proc_net = proc_mkdir("net", NULL); - proc_net_stat = proc_mkdir("net/stat", NULL); + + proc_net_init(); #ifdef CONFIG_SYSVIPC proc_mkdir("sysvipc", NULL); @@ -159,7 +159,5 @@ EXPORT_SYMBOL(create_proc_entry); EXPORT_SYMBOL(remove_proc_entry); EXPORT_SYMBOL(proc_root); EXPORT_SYMBOL(proc_root_fs); -EXPORT_SYMBOL(proc_net); -EXPORT_SYMBOL(proc_net_stat); EXPORT_SYMBOL(proc_bus); EXPORT_SYMBOL(proc_root_driver); diff --git a/include/linux/proc_fs.h b/include/linux/proc_fs.h index cd13a78c5db8..59646705f151 100644 --- a/include/linux/proc_fs.h +++ b/include/linux/proc_fs.h @@ -7,6 +7,7 @@ #include #include +struct net; struct completion; /* @@ -97,8 +98,6 @@ struct vmcore { extern struct proc_dir_entry proc_root; extern struct proc_dir_entry *proc_root_fs; -extern struct proc_dir_entry *proc_net; -extern struct proc_dir_entry *proc_net_stat; extern struct proc_dir_entry *proc_bus; extern struct proc_dir_entry *proc_root_driver; extern struct proc_dir_entry *proc_root_kcore; @@ -192,36 +191,21 @@ static inline struct proc_dir_entry *create_proc_info_entry(const char *name, if (res) res->get_info=get_info; return res; } - -static inline struct proc_dir_entry *proc_net_create(const char *name, - mode_t mode, get_info_t *get_info) -{ - return create_proc_info_entry(name,mode,proc_net,get_info); -} -static inline struct proc_dir_entry *proc_net_fops_create(const char *name, - mode_t mode, const struct file_operations *fops) -{ - struct proc_dir_entry *res = create_proc_entry(name, mode, proc_net); - if (res) - res->proc_fops = fops; - return res; -} - -static inline void proc_net_remove(const char *name) -{ - remove_proc_entry(name,proc_net); -} +extern struct proc_dir_entry *proc_net_create(struct net *net, + const char *name, mode_t mode, get_info_t *get_info); +extern struct proc_dir_entry *proc_net_fops_create(struct net *net, + const char *name, mode_t mode, const struct file_operations *fops); +extern void proc_net_remove(struct net *net, const char *name); #else #define proc_root_driver NULL -#define proc_net NULL #define proc_bus NULL -#define proc_net_fops_create(name, mode, fops) ({ (void)(mode), NULL; }) -#define proc_net_create(name, mode, info) ({ (void)(mode), NULL; }) -static inline void proc_net_remove(const char *name) {} +#define proc_net_fops_create(net, name, mode, fops) ({ (void)(mode), NULL; }) +#define proc_net_create(net, name, mode, info) ({ (void)(mode), NULL; }) +static inline void proc_net_remove(struct net *net, const char *name) {} static inline void proc_flush_task(struct task_struct *task) { } @@ -281,6 +265,16 @@ static inline struct proc_dir_entry *PDE(const struct inode *inode) return PROC_I(inode)->pde; } +static inline struct net *PDE_NET(struct proc_dir_entry *pde) +{ + return pde->parent->data; +} + +static inline struct net *PROC_NET(const struct inode *inode) +{ + return PDE_NET(PDE(inode)); +} + struct proc_maps_private { struct pid *pid; struct task_struct *task; diff --git a/include/net/net_namespace.h b/include/net/net_namespace.h index 6344b77f81a2..547247681345 100644 --- a/include/net/net_namespace.h +++ b/include/net/net_namespace.h @@ -8,6 +8,7 @@ #include #include +struct proc_dir_entry; struct net { atomic_t count; /* To decided when the network * namespace should be freed. @@ -17,6 +18,10 @@ struct net { */ struct list_head list; /* list of network namespaces */ struct work_struct work; /* work struct for freeing */ + + struct proc_dir_entry *proc_net; + struct proc_dir_entry *proc_net_stat; + struct proc_dir_entry *proc_net_root; }; extern struct net init_net; diff --git a/net/802/tr.c b/net/802/tr.c index e56e61a7f545..032c31e748eb 100644 --- a/net/802/tr.c +++ b/net/802/tr.c @@ -36,6 +36,7 @@ #include #include #include +#include static void tr_add_rif_info(struct trh_hdr *trh, struct net_device *dev); static void rif_check_expire(unsigned long dummy); @@ -639,7 +640,7 @@ static int __init rif_init(void) rif_timer.function = rif_check_expire; add_timer(&rif_timer); - proc_net_fops_create("tr_rif", S_IRUGO, &rif_seq_fops); + proc_net_fops_create(&init_net, "tr_rif", S_IRUGO, &rif_seq_fops); return 0; } diff --git a/net/8021q/vlanproc.c b/net/8021q/vlanproc.c index bd08aa090763..ac80e6b9ef53 100644 --- a/net/8021q/vlanproc.c +++ b/net/8021q/vlanproc.c @@ -33,6 +33,7 @@ #include #include #include +#include #include "vlanproc.h" #include "vlan.h" @@ -143,7 +144,7 @@ void vlan_proc_cleanup(void) remove_proc_entry(name_conf, proc_vlan_dir); if (proc_vlan_dir) - proc_net_remove(name_root); + proc_net_remove(&init_net, name_root); /* Dynamically added entries should be cleaned up as their vlan_device * is removed, so we should not have to take care of it here... @@ -156,7 +157,7 @@ void vlan_proc_cleanup(void) int __init vlan_proc_init(void) { - proc_vlan_dir = proc_mkdir(name_root, proc_net); + proc_vlan_dir = proc_mkdir(name_root, init_net.proc_net); if (proc_vlan_dir) { proc_vlan_conf = create_proc_entry(name_conf, S_IFREG|S_IRUSR|S_IWUSR, diff --git a/net/appletalk/atalk_proc.c b/net/appletalk/atalk_proc.c index 87a582cc8111..05d9652afcb6 100644 --- a/net/appletalk/atalk_proc.c +++ b/net/appletalk/atalk_proc.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include @@ -271,7 +272,7 @@ int __init atalk_proc_init(void) struct proc_dir_entry *p; int rc = -ENOMEM; - atalk_proc_dir = proc_mkdir("atalk", proc_net); + atalk_proc_dir = proc_mkdir("atalk", init_net.proc_net); if (!atalk_proc_dir) goto out; atalk_proc_dir->owner = THIS_MODULE; @@ -306,7 +307,7 @@ out_socket: out_route: remove_proc_entry("interface", atalk_proc_dir); out_interface: - remove_proc_entry("atalk", proc_net); + remove_proc_entry("atalk", init_net.proc_net); goto out; } @@ -316,5 +317,5 @@ void __exit atalk_proc_exit(void) remove_proc_entry("route", atalk_proc_dir); remove_proc_entry("socket", atalk_proc_dir); remove_proc_entry("arp", atalk_proc_dir); - remove_proc_entry("atalk", proc_net); + remove_proc_entry("atalk", init_net.proc_net); } diff --git a/net/atm/proc.c b/net/atm/proc.c index 99fc1fe950ee..3a6be64b0512 100644 --- a/net/atm/proc.c +++ b/net/atm/proc.c @@ -22,6 +22,7 @@ #include #include #include /* for __init */ +#include #include #include #include @@ -475,7 +476,7 @@ static void atm_proc_dirs_remove(void) if (e->dirent) remove_proc_entry(e->name, atm_proc_root); } - remove_proc_entry("net/atm", NULL); + remove_proc_entry("atm", init_net.proc_net); } int __init atm_proc_init(void) @@ -483,7 +484,7 @@ int __init atm_proc_init(void) static struct atm_proc_entry *e; int ret; - atm_proc_root = proc_mkdir("net/atm",NULL); + atm_proc_root = proc_mkdir("atm", init_net.proc_net); if (!atm_proc_root) goto err_out; for (e = atm_proc_ents; e->name; e++) { diff --git a/net/ax25/af_ax25.c b/net/ax25/af_ax25.c index dae2a42d3d86..1d71f85680b8 100644 --- a/net/ax25/af_ax25.c +++ b/net/ax25/af_ax25.c @@ -44,6 +44,7 @@ #include #include #include +#include #include #include #include @@ -1998,9 +1999,9 @@ static int __init ax25_init(void) register_netdevice_notifier(&ax25_dev_notifier); ax25_register_sysctl(); - proc_net_fops_create("ax25_route", S_IRUGO, &ax25_route_fops); - proc_net_fops_create("ax25", S_IRUGO, &ax25_info_fops); - proc_net_fops_create("ax25_calls", S_IRUGO, &ax25_uid_fops); + proc_net_fops_create(&init_net, "ax25_route", S_IRUGO, &ax25_route_fops); + proc_net_fops_create(&init_net, "ax25", S_IRUGO, &ax25_info_fops); + proc_net_fops_create(&init_net, "ax25_calls", S_IRUGO, &ax25_uid_fops); out: return rc; } @@ -2014,9 +2015,9 @@ MODULE_ALIAS_NETPROTO(PF_AX25); static void __exit ax25_exit(void) { - proc_net_remove("ax25_route"); - proc_net_remove("ax25"); - proc_net_remove("ax25_calls"); + proc_net_remove(&init_net, "ax25_route"); + proc_net_remove(&init_net, "ax25"); + proc_net_remove(&init_net, "ax25_calls"); ax25_rt_free(); ax25_uid_free(); ax25_dev_free(); diff --git a/net/core/dev.c b/net/core/dev.c index 29cf00c5d865..618fb1c1dd47 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -92,6 +92,7 @@ #include #include #include +#include #include #include #include @@ -2556,24 +2557,24 @@ static int __init dev_proc_init(void) { int rc = -ENOMEM; - if (!proc_net_fops_create("dev", S_IRUGO, &dev_seq_fops)) + if (!proc_net_fops_create(&init_net, "dev", S_IRUGO, &dev_seq_fops)) goto out; - if (!proc_net_fops_create("softnet_stat", S_IRUGO, &softnet_seq_fops)) + if (!proc_net_fops_create(&init_net, "softnet_stat", S_IRUGO, &softnet_seq_fops)) goto out_dev; - if (!proc_net_fops_create("ptype", S_IRUGO, &ptype_seq_fops)) - goto out_dev2; + if (!proc_net_fops_create(&init_net, "ptype", S_IRUGO, &ptype_seq_fops)) + goto out_softnet; if (wext_proc_init()) - goto out_softnet; + goto out_ptype; rc = 0; out: return rc; +out_ptype: + proc_net_remove(&init_net, "ptype"); out_softnet: - proc_net_remove("ptype"); -out_dev2: - proc_net_remove("softnet_stat"); + proc_net_remove(&init_net, "softnet_stat"); out_dev: - proc_net_remove("dev"); + proc_net_remove(&init_net, "dev"); goto out; } #else diff --git a/net/core/dev_mcast.c b/net/core/dev_mcast.c index 20330c572610..8e069fc207cb 100644 --- a/net/core/dev_mcast.c +++ b/net/core/dev_mcast.c @@ -41,6 +41,7 @@ #include #include #include +#include #include #include #include @@ -254,7 +255,7 @@ static const struct file_operations dev_mc_seq_fops = { void __init dev_mcast_init(void) { - proc_net_fops_create("dev_mcast", 0, &dev_mc_seq_fops); + proc_net_fops_create(&init_net, "dev_mcast", 0, &dev_mc_seq_fops); } EXPORT_SYMBOL(dev_mc_add); diff --git a/net/core/neighbour.c b/net/core/neighbour.c index ecd43c4a2221..5f25f4f79b8c 100644 --- a/net/core/neighbour.c +++ b/net/core/neighbour.c @@ -25,6 +25,7 @@ #include #endif #include +#include #include #include #include @@ -1350,7 +1351,7 @@ void neigh_table_init_no_netlink(struct neigh_table *tbl) panic("cannot create neighbour cache statistics"); #ifdef CONFIG_PROC_FS - tbl->pde = create_proc_entry(tbl->id, 0, proc_net_stat); + tbl->pde = create_proc_entry(tbl->id, 0, init_net.proc_net_stat); if (!tbl->pde) panic("cannot create neighbour proc dir entry"); tbl->pde->proc_fops = &neigh_stat_seq_fops; diff --git a/net/core/pktgen.c b/net/core/pktgen.c index 84c0edeedf6d..33d7247fb19d 100644 --- a/net/core/pktgen.c +++ b/net/core/pktgen.c @@ -152,6 +152,7 @@ #include #include #include +#include #include #include #include @@ -3808,7 +3809,7 @@ static int __init pg_init(void) printk(KERN_INFO "%s", version); - pg_proc_dir = proc_mkdir(PG_PROC_DIR, proc_net); + pg_proc_dir = proc_mkdir(PG_PROC_DIR, init_net.proc_net); if (!pg_proc_dir) return -ENODEV; pg_proc_dir->owner = THIS_MODULE; @@ -3817,7 +3818,7 @@ static int __init pg_init(void) if (pe == NULL) { printk(KERN_ERR "pktgen: ERROR: cannot create %s " "procfs entry.\n", PGCTRL); - proc_net_remove(PG_PROC_DIR); + proc_net_remove(&init_net, PG_PROC_DIR); return -EINVAL; } @@ -3841,7 +3842,7 @@ static int __init pg_init(void) "all threads\n"); unregister_netdevice_notifier(&pktgen_notifier_block); remove_proc_entry(PGCTRL, pg_proc_dir); - proc_net_remove(PG_PROC_DIR); + proc_net_remove(&init_net, PG_PROC_DIR); return -ENODEV; } @@ -3868,7 +3869,7 @@ static void __exit pg_cleanup(void) /* Clean up proc file system */ remove_proc_entry(PGCTRL, pg_proc_dir); - proc_net_remove(PG_PROC_DIR); + proc_net_remove(&init_net, PG_PROC_DIR); } module_init(pg_init); diff --git a/net/core/sock.c b/net/core/sock.c index beb924c248e8..bbc726a49d87 100644 --- a/net/core/sock.c +++ b/net/core/sock.c @@ -119,6 +119,7 @@ #include #include #include +#include #include #include #include @@ -1973,7 +1974,7 @@ static const struct file_operations proto_seq_fops = { static int __init proto_init(void) { /* register /proc/net/protocols */ - return proc_net_fops_create("protocols", S_IRUGO, &proto_seq_fops) == NULL ? -ENOBUFS : 0; + return proc_net_fops_create(&init_net, "protocols", S_IRUGO, &proto_seq_fops) == NULL ? -ENOBUFS : 0; } subsys_initcall(proto_init); diff --git a/net/dccp/probe.c b/net/dccp/probe.c index bae10b0f2fc3..7053bb827bc8 100644 --- a/net/dccp/probe.c +++ b/net/dccp/probe.c @@ -30,6 +30,7 @@ #include #include #include +#include #include "dccp.h" #include "ccid.h" @@ -168,7 +169,7 @@ static __init int dccpprobe_init(void) if (IS_ERR(dccpw.fifo)) return PTR_ERR(dccpw.fifo); - if (!proc_net_fops_create(procname, S_IRUSR, &dccpprobe_fops)) + if (!proc_net_fops_create(&init_net, procname, S_IRUSR, &dccpprobe_fops)) goto err0; ret = register_jprobe(&dccp_send_probe); @@ -178,7 +179,7 @@ static __init int dccpprobe_init(void) pr_info("DCCP watch registered (port=%d)\n", port); return 0; err1: - proc_net_remove(procname); + proc_net_remove(&init_net, procname); err0: kfifo_free(dccpw.fifo); return ret; @@ -188,7 +189,7 @@ module_init(dccpprobe_init); static __exit void dccpprobe_exit(void) { kfifo_free(dccpw.fifo); - proc_net_remove(procname); + proc_net_remove(&init_net, procname); unregister_jprobe(&dccp_send_probe); } diff --git a/net/decnet/af_decnet.c b/net/decnet/af_decnet.c index ed76d4aab4a9..625d5955b8e2 100644 --- a/net/decnet/af_decnet.c +++ b/net/decnet/af_decnet.c @@ -128,6 +128,7 @@ Version 0.0.6 2.1.110 07-aug-98 Eduardo Marcelo Serrat #include #include #include +#include #include #include #include @@ -2399,7 +2400,7 @@ static int __init decnet_init(void) dev_add_pack(&dn_dix_packet_type); register_netdevice_notifier(&dn_dev_notifier); - proc_net_fops_create("decnet", S_IRUGO, &dn_socket_seq_fops); + proc_net_fops_create(&init_net, "decnet", S_IRUGO, &dn_socket_seq_fops); dn_register_sysctl(); out: return rc; @@ -2428,7 +2429,7 @@ static void __exit decnet_exit(void) dn_neigh_cleanup(); dn_fib_cleanup(); - proc_net_remove("decnet"); + proc_net_remove(&init_net, "decnet"); proto_unregister(&dn_proto); } diff --git a/net/decnet/dn_dev.c b/net/decnet/dn_dev.c index 8def68209edd..83cb0761336a 100644 --- a/net/decnet/dn_dev.c +++ b/net/decnet/dn_dev.c @@ -42,6 +42,7 @@ #include #include #include +#include #include #include #include @@ -1462,7 +1463,7 @@ void __init dn_dev_init(void) rtnl_register(PF_DECnet, RTM_DELADDR, dn_nl_deladdr, NULL); rtnl_register(PF_DECnet, RTM_GETADDR, NULL, dn_nl_dump_ifaddr); - proc_net_fops_create("decnet_dev", S_IRUGO, &dn_dev_seq_fops); + proc_net_fops_create(&init_net, "decnet_dev", S_IRUGO, &dn_dev_seq_fops); #ifdef CONFIG_SYSCTL { @@ -1483,7 +1484,7 @@ void __exit dn_dev_cleanup(void) } #endif /* CONFIG_SYSCTL */ - proc_net_remove("decnet_dev"); + proc_net_remove(&init_net, "decnet_dev"); dn_dev_devices_off(); } diff --git a/net/decnet/dn_neigh.c b/net/decnet/dn_neigh.c index 174d8a7a6dac..a424a8ddbaf7 100644 --- a/net/decnet/dn_neigh.c +++ b/net/decnet/dn_neigh.c @@ -38,6 +38,7 @@ #include #include #include +#include #include #include #include @@ -611,11 +612,11 @@ static const struct file_operations dn_neigh_seq_fops = { void __init dn_neigh_init(void) { neigh_table_init(&dn_neigh_table); - proc_net_fops_create("decnet_neigh", S_IRUGO, &dn_neigh_seq_fops); + proc_net_fops_create(&init_net, "decnet_neigh", S_IRUGO, &dn_neigh_seq_fops); } void __exit dn_neigh_cleanup(void) { - proc_net_remove("decnet_neigh"); + proc_net_remove(&init_net, "decnet_neigh"); neigh_table_clear(&dn_neigh_table); } diff --git a/net/decnet/dn_route.c b/net/decnet/dn_route.c index a4a620971ef0..4cfea9563d2a 100644 --- a/net/decnet/dn_route.c +++ b/net/decnet/dn_route.c @@ -77,6 +77,7 @@ #include #include #include +#include #include #include #include @@ -1814,7 +1815,7 @@ void __init dn_route_init(void) dn_dst_ops.gc_thresh = (dn_rt_hash_mask + 1); - proc_net_fops_create("decnet_cache", S_IRUGO, &dn_rt_cache_seq_fops); + proc_net_fops_create(&init_net, "decnet_cache", S_IRUGO, &dn_rt_cache_seq_fops); #ifdef CONFIG_DECNET_ROUTER rtnl_register(PF_DECnet, RTM_GETROUTE, dn_cache_getroute, dn_fib_dump); @@ -1829,6 +1830,6 @@ void __exit dn_route_cleanup(void) del_timer(&dn_route_timer); dn_run_flush(0); - proc_net_remove("decnet_cache"); + proc_net_remove(&init_net, "decnet_cache"); } diff --git a/net/ieee80211/ieee80211_module.c b/net/ieee80211/ieee80211_module.c index 17ad278696ed..69cb6aad25be 100644 --- a/net/ieee80211/ieee80211_module.c +++ b/net/ieee80211/ieee80211_module.c @@ -47,6 +47,7 @@ #include #include #include +#include #include #include @@ -264,7 +265,7 @@ static int __init ieee80211_init(void) struct proc_dir_entry *e; ieee80211_debug_level = debug; - ieee80211_proc = proc_mkdir(DRV_NAME, proc_net); + ieee80211_proc = proc_mkdir(DRV_NAME, init_net.proc_net); if (ieee80211_proc == NULL) { IEEE80211_ERROR("Unable to create " DRV_NAME " proc directory\n"); @@ -273,7 +274,7 @@ static int __init ieee80211_init(void) e = create_proc_entry("debug_level", S_IFREG | S_IRUGO | S_IWUSR, ieee80211_proc); if (!e) { - remove_proc_entry(DRV_NAME, proc_net); + remove_proc_entry(DRV_NAME, init_net.proc_net); ieee80211_proc = NULL; return -EIO; } @@ -293,7 +294,7 @@ static void __exit ieee80211_exit(void) #ifdef CONFIG_IEEE80211_DEBUG if (ieee80211_proc) { remove_proc_entry("debug_level", ieee80211_proc); - remove_proc_entry(DRV_NAME, proc_net); + remove_proc_entry(DRV_NAME, init_net.proc_net); ieee80211_proc = NULL; } #endif /* CONFIG_IEEE80211_DEBUG */ diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c index 9ab9d534fbac..78dd3443016c 100644 --- a/net/ipv4/arp.c +++ b/net/ipv4/arp.c @@ -103,6 +103,7 @@ #include #endif +#include #include #include #include @@ -1400,7 +1401,7 @@ static const struct file_operations arp_seq_fops = { static int __init arp_proc_init(void) { - if (!proc_net_fops_create("arp", S_IRUGO, &arp_seq_fops)) + if (!proc_net_fops_create(&init_net, "arp", S_IRUGO, &arp_seq_fops)) return -ENOMEM; return 0; } diff --git a/net/ipv4/fib_hash.c b/net/ipv4/fib_hash.c index 9ad1d9ff9ce7..9fafbeea8fe6 100644 --- a/net/ipv4/fib_hash.c +++ b/net/ipv4/fib_hash.c @@ -35,6 +35,7 @@ #include #include +#include #include #include #include @@ -1068,13 +1069,13 @@ static const struct file_operations fib_seq_fops = { int __init fib_proc_init(void) { - if (!proc_net_fops_create("route", S_IRUGO, &fib_seq_fops)) + if (!proc_net_fops_create(&init_net, "route", S_IRUGO, &fib_seq_fops)) return -ENOMEM; return 0; } void __init fib_proc_exit(void) { - proc_net_remove("route"); + proc_net_remove(&init_net, "route"); } #endif /* CONFIG_PROC_FS */ diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c index 52b2891c63b7..be34bd556d58 100644 --- a/net/ipv4/fib_trie.c +++ b/net/ipv4/fib_trie.c @@ -73,6 +73,7 @@ #include #include #include +#include #include #include #include @@ -2530,30 +2531,30 @@ static const struct file_operations fib_route_fops = { int __init fib_proc_init(void) { - if (!proc_net_fops_create("fib_trie", S_IRUGO, &fib_trie_fops)) + if (!proc_net_fops_create(&init_net, "fib_trie", S_IRUGO, &fib_trie_fops)) goto out1; - if (!proc_net_fops_create("fib_triestat", S_IRUGO, &fib_triestat_fops)) + if (!proc_net_fops_create(&init_net, "fib_triestat", S_IRUGO, &fib_triestat_fops)) goto out2; - if (!proc_net_fops_create("route", S_IRUGO, &fib_route_fops)) + if (!proc_net_fops_create(&init_net, "route", S_IRUGO, &fib_route_fops)) goto out3; return 0; out3: - proc_net_remove("fib_triestat"); + proc_net_remove(&init_net, "fib_triestat"); out2: - proc_net_remove("fib_trie"); + proc_net_remove(&init_net, "fib_trie"); out1: return -ENOMEM; } void __init fib_proc_exit(void) { - proc_net_remove("fib_trie"); - proc_net_remove("fib_triestat"); - proc_net_remove("route"); + proc_net_remove(&init_net, "fib_trie"); + proc_net_remove(&init_net, "fib_triestat"); + proc_net_remove(&init_net, "route"); } #endif /* CONFIG_PROC_FS */ diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c index a646409c2d06..d78599a9dbd5 100644 --- a/net/ipv4/igmp.c +++ b/net/ipv4/igmp.c @@ -91,6 +91,7 @@ #include #include +#include #include #include #include @@ -2613,8 +2614,8 @@ static const struct file_operations igmp_mcf_seq_fops = { int __init igmp_mc_proc_init(void) { - proc_net_fops_create("igmp", S_IRUGO, &igmp_mc_seq_fops); - proc_net_fops_create("mcfilter", S_IRUGO, &igmp_mcf_seq_fops); + proc_net_fops_create(&init_net, "igmp", S_IRUGO, &igmp_mc_seq_fops); + proc_net_fops_create(&init_net, "mcfilter", S_IRUGO, &igmp_mcf_seq_fops); return 0; } #endif diff --git a/net/ipv4/ipconfig.c b/net/ipv4/ipconfig.c index c5b247077539..5ae4849878a3 100644 --- a/net/ipv4/ipconfig.c +++ b/net/ipv4/ipconfig.c @@ -55,6 +55,7 @@ #include #include #include +#include #include #include #include @@ -1253,7 +1254,7 @@ static int __init ip_auto_config(void) __be32 addr; #ifdef CONFIG_PROC_FS - proc_net_fops_create("pnp", S_IRUGO, &pnp_seq_fops); + proc_net_fops_create(&init_net, "pnp", S_IRUGO, &pnp_seq_fops); #endif /* CONFIG_PROC_FS */ if (!ic_enable) diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c index 7003cc1b7fe2..35683e1a42e8 100644 --- a/net/ipv4/ipmr.c +++ b/net/ipv4/ipmr.c @@ -49,6 +49,7 @@ #include #include #include +#include #include #include #include @@ -1922,7 +1923,7 @@ void __init ip_mr_init(void) ipmr_expire_timer.function=ipmr_expire_process; register_netdevice_notifier(&ip_mr_notifier); #ifdef CONFIG_PROC_FS - proc_net_fops_create("ip_mr_vif", 0, &ipmr_vif_fops); - proc_net_fops_create("ip_mr_cache", 0, &ipmr_mfc_fops); + proc_net_fops_create(&init_net, "ip_mr_vif", 0, &ipmr_vif_fops); + proc_net_fops_create(&init_net, "ip_mr_cache", 0, &ipmr_mfc_fops); #endif } diff --git a/net/ipv4/ipvs/ip_vs_app.c b/net/ipv4/ipvs/ip_vs_app.c index 8d6901d4e94f..341474eefa55 100644 --- a/net/ipv4/ipvs/ip_vs_app.c +++ b/net/ipv4/ipvs/ip_vs_app.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -616,12 +617,12 @@ int ip_vs_skb_replace(struct sk_buff *skb, gfp_t pri, int ip_vs_app_init(void) { /* we will replace it with proc_net_ipvs_create() soon */ - proc_net_fops_create("ip_vs_app", 0, &ip_vs_app_fops); + proc_net_fops_create(&init_net, "ip_vs_app", 0, &ip_vs_app_fops); return 0; } void ip_vs_app_cleanup(void) { - proc_net_remove("ip_vs_app"); + proc_net_remove(&init_net, "ip_vs_app"); } diff --git a/net/ipv4/ipvs/ip_vs_conn.c b/net/ipv4/ipvs/ip_vs_conn.c index d612a6a5d957..4b702f708d30 100644 --- a/net/ipv4/ipvs/ip_vs_conn.c +++ b/net/ipv4/ipvs/ip_vs_conn.c @@ -35,6 +35,7 @@ #include #include +#include #include @@ -922,7 +923,7 @@ int ip_vs_conn_init(void) rwlock_init(&__ip_vs_conntbl_lock_array[idx].l); } - proc_net_fops_create("ip_vs_conn", 0, &ip_vs_conn_fops); + proc_net_fops_create(&init_net, "ip_vs_conn", 0, &ip_vs_conn_fops); /* calculate the random value for connection hash */ get_random_bytes(&ip_vs_conn_rnd, sizeof(ip_vs_conn_rnd)); @@ -938,6 +939,6 @@ void ip_vs_conn_cleanup(void) /* Release the empty cache */ kmem_cache_destroy(ip_vs_conn_cachep); - proc_net_remove("ip_vs_conn"); + proc_net_remove(&init_net, "ip_vs_conn"); vfree(ip_vs_conn_tab); } diff --git a/net/ipv4/ipvs/ip_vs_ctl.c b/net/ipv4/ipvs/ip_vs_ctl.c index f656d41d8d41..61d023d58b5d 100644 --- a/net/ipv4/ipvs/ip_vs_ctl.c +++ b/net/ipv4/ipvs/ip_vs_ctl.c @@ -35,6 +35,7 @@ #include #include +#include #include #include #include @@ -2356,8 +2357,8 @@ int ip_vs_control_init(void) return ret; } - proc_net_fops_create("ip_vs", 0, &ip_vs_info_fops); - proc_net_fops_create("ip_vs_stats",0, &ip_vs_stats_fops); + proc_net_fops_create(&init_net, "ip_vs", 0, &ip_vs_info_fops); + proc_net_fops_create(&init_net, "ip_vs_stats",0, &ip_vs_stats_fops); sysctl_header = register_sysctl_table(vs_root_table); @@ -2390,8 +2391,8 @@ void ip_vs_control_cleanup(void) cancel_work_sync(&defense_work.work); ip_vs_kill_estimator(&ip_vs_stats); unregister_sysctl_table(sysctl_header); - proc_net_remove("ip_vs_stats"); - proc_net_remove("ip_vs"); + proc_net_remove(&init_net, "ip_vs_stats"); + proc_net_remove(&init_net, "ip_vs"); nf_unregister_sockopt(&ip_vs_sockopts); LeaveFunction(2); } diff --git a/net/ipv4/ipvs/ip_vs_lblcr.c b/net/ipv4/ipvs/ip_vs_lblcr.c index 6225acac7a3b..6a1fec416eaf 100644 --- a/net/ipv4/ipvs/ip_vs_lblcr.c +++ b/net/ipv4/ipvs/ip_vs_lblcr.c @@ -50,6 +50,7 @@ #include /* for proc_net_create/proc_net_remove */ #include +#include #include @@ -843,7 +844,7 @@ static int __init ip_vs_lblcr_init(void) INIT_LIST_HEAD(&ip_vs_lblcr_scheduler.n_list); sysctl_header = register_sysctl_table(lblcr_root_table); #ifdef CONFIG_IP_VS_LBLCR_DEBUG - proc_net_create("ip_vs_lblcr", 0, ip_vs_lblcr_getinfo); + proc_net_create(&init_net, "ip_vs_lblcr", 0, ip_vs_lblcr_getinfo); #endif return register_ip_vs_scheduler(&ip_vs_lblcr_scheduler); } @@ -852,7 +853,7 @@ static int __init ip_vs_lblcr_init(void) static void __exit ip_vs_lblcr_cleanup(void) { #ifdef CONFIG_IP_VS_LBLCR_DEBUG - proc_net_remove("ip_vs_lblcr"); + proc_net_remove(&init_net, "ip_vs_lblcr"); #endif unregister_sysctl_table(sysctl_header); unregister_ip_vs_scheduler(&ip_vs_lblcr_scheduler); diff --git a/net/ipv4/netfilter/ip_queue.c b/net/ipv4/netfilter/ip_queue.c index 702d94db19b9..cb5e61a1d7ab 100644 --- a/net/ipv4/netfilter/ip_queue.c +++ b/net/ipv4/netfilter/ip_queue.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include @@ -674,7 +675,7 @@ static int __init ip_queue_init(void) goto cleanup_netlink_notifier; } - proc = proc_net_create(IPQ_PROC_FS_NAME, 0, ipq_get_info); + proc = proc_net_create(&init_net, IPQ_PROC_FS_NAME, 0, ipq_get_info); if (proc) proc->owner = THIS_MODULE; else { @@ -695,8 +696,7 @@ static int __init ip_queue_init(void) cleanup_sysctl: unregister_sysctl_table(ipq_sysctl_header); unregister_netdevice_notifier(&ipq_dev_notifier); - proc_net_remove(IPQ_PROC_FS_NAME); - + proc_net_remove(&init_net, IPQ_PROC_FS_NAME); cleanup_ipqnl: sock_release(ipqnl->sk_socket); mutex_lock(&ipqnl_mutex); @@ -715,7 +715,7 @@ static void __exit ip_queue_fini(void) unregister_sysctl_table(ipq_sysctl_header); unregister_netdevice_notifier(&ipq_dev_notifier); - proc_net_remove(IPQ_PROC_FS_NAME); + proc_net_remove(&init_net, IPQ_PROC_FS_NAME); sock_release(ipqnl->sk_socket); mutex_lock(&ipqnl_mutex); diff --git a/net/ipv4/netfilter/ipt_CLUSTERIP.c b/net/ipv4/netfilter/ipt_CLUSTERIP.c index 69bd362b5fa2..50fc9e009fe4 100644 --- a/net/ipv4/netfilter/ipt_CLUSTERIP.c +++ b/net/ipv4/netfilter/ipt_CLUSTERIP.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #define CLUSTERIP_VERSION "0.8" @@ -726,7 +727,7 @@ static int __init ipt_clusterip_init(void) goto cleanup_target; #ifdef CONFIG_PROC_FS - clusterip_procdir = proc_mkdir("ipt_CLUSTERIP", proc_net); + clusterip_procdir = proc_mkdir("ipt_CLUSTERIP", init_net.proc_net); if (!clusterip_procdir) { printk(KERN_ERR "CLUSTERIP: Unable to proc dir entry\n"); ret = -ENOMEM; diff --git a/net/ipv4/netfilter/ipt_recent.c b/net/ipv4/netfilter/ipt_recent.c index 6d0c0f7364ad..db2a79889f9a 100644 --- a/net/ipv4/netfilter/ipt_recent.c +++ b/net/ipv4/netfilter/ipt_recent.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include @@ -487,7 +488,7 @@ static int __init ipt_recent_init(void) #ifdef CONFIG_PROC_FS if (err) return err; - proc_dir = proc_mkdir("ipt_recent", proc_net); + proc_dir = proc_mkdir("ipt_recent", init_net.proc_net); if (proc_dir == NULL) { xt_unregister_match(&recent_match); err = -ENOMEM; @@ -501,7 +502,7 @@ static void __exit ipt_recent_exit(void) BUG_ON(!list_empty(&tables)); xt_unregister_match(&recent_match); #ifdef CONFIG_PROC_FS - remove_proc_entry("ipt_recent", proc_net); + remove_proc_entry("ipt_recent", init_net.proc_net); #endif } diff --git a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c index b3dd5de9a258..a5ae2eabf0f3 100644 --- a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c +++ b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include @@ -408,16 +409,16 @@ int __init nf_conntrack_ipv4_compat_init(void) { struct proc_dir_entry *proc, *proc_exp, *proc_stat; - proc = proc_net_fops_create("ip_conntrack", 0440, &ct_file_ops); + proc = proc_net_fops_create(&init_net, "ip_conntrack", 0440, &ct_file_ops); if (!proc) goto err1; - proc_exp = proc_net_fops_create("ip_conntrack_expect", 0440, + proc_exp = proc_net_fops_create(&init_net, "ip_conntrack_expect", 0440, &ip_exp_file_ops); if (!proc_exp) goto err2; - proc_stat = create_proc_entry("ip_conntrack", S_IRUGO, proc_net_stat); + proc_stat = create_proc_entry("ip_conntrack", S_IRUGO, init_net.proc_net_stat); if (!proc_stat) goto err3; @@ -427,16 +428,16 @@ int __init nf_conntrack_ipv4_compat_init(void) return 0; err3: - proc_net_remove("ip_conntrack_expect"); + proc_net_remove(&init_net, "ip_conntrack_expect"); err2: - proc_net_remove("ip_conntrack"); + proc_net_remove(&init_net, "ip_conntrack"); err1: return -ENOMEM; } void __exit nf_conntrack_ipv4_compat_fini(void) { - remove_proc_entry("ip_conntrack", proc_net_stat); - proc_net_remove("ip_conntrack_expect"); - proc_net_remove("ip_conntrack"); + remove_proc_entry("ip_conntrack", init_net.proc_net_stat); + proc_net_remove(&init_net, "ip_conntrack_expect"); + proc_net_remove(&init_net, "ip_conntrack"); } diff --git a/net/ipv4/proc.c b/net/ipv4/proc.c index 986d1c83a000..95a8f8f2de71 100644 --- a/net/ipv4/proc.c +++ b/net/ipv4/proc.c @@ -34,6 +34,7 @@ * 2 of the License, or (at your option) any later version. */ #include +#include #include #include #include @@ -383,20 +384,20 @@ int __init ip_misc_proc_init(void) { int rc = 0; - if (!proc_net_fops_create("netstat", S_IRUGO, &netstat_seq_fops)) + if (!proc_net_fops_create(&init_net, "netstat", S_IRUGO, &netstat_seq_fops)) goto out_netstat; - if (!proc_net_fops_create("snmp", S_IRUGO, &snmp_seq_fops)) + if (!proc_net_fops_create(&init_net, "snmp", S_IRUGO, &snmp_seq_fops)) goto out_snmp; - if (!proc_net_fops_create("sockstat", S_IRUGO, &sockstat_seq_fops)) + if (!proc_net_fops_create(&init_net, "sockstat", S_IRUGO, &sockstat_seq_fops)) goto out_sockstat; out: return rc; out_sockstat: - proc_net_remove("snmp"); + proc_net_remove(&init_net, "snmp"); out_snmp: - proc_net_remove("netstat"); + proc_net_remove(&init_net, "netstat"); out_netstat: rc = -ENOMEM; goto out; diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c index c6d71526f625..216e01b0f44a 100644 --- a/net/ipv4/raw.c +++ b/net/ipv4/raw.c @@ -59,6 +59,7 @@ #include #include #include +#include #include #include #include @@ -928,13 +929,13 @@ static const struct file_operations raw_seq_fops = { int __init raw_proc_init(void) { - if (!proc_net_fops_create("raw", S_IRUGO, &raw_seq_fops)) + if (!proc_net_fops_create(&init_net, "raw", S_IRUGO, &raw_seq_fops)) return -ENOMEM; return 0; } void __init raw_proc_exit(void) { - proc_net_remove("raw"); + proc_net_remove(&init_net, "raw"); } #endif /* CONFIG_PROC_FS */ diff --git a/net/ipv4/route.c b/net/ipv4/route.c index c7ca94bd152c..efd2a9202d68 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -91,6 +91,7 @@ #include #include #include +#include #include #include #include @@ -3011,15 +3012,15 @@ int __init ip_rt_init(void) #ifdef CONFIG_PROC_FS { struct proc_dir_entry *rtstat_pde = NULL; /* keep gcc happy */ - if (!proc_net_fops_create("rt_cache", S_IRUGO, &rt_cache_seq_fops) || + if (!proc_net_fops_create(&init_net, "rt_cache", S_IRUGO, &rt_cache_seq_fops) || !(rtstat_pde = create_proc_entry("rt_cache", S_IRUGO, - proc_net_stat))) { + init_net.proc_net_stat))) { return -ENOMEM; } rtstat_pde->proc_fops = &rt_cpu_seq_fops; } #ifdef CONFIG_NET_CLS_ROUTE - create_proc_read_entry("rt_acct", 0, proc_net, ip_rt_acct_read, NULL); + create_proc_read_entry("rt_acct", 0, init_net.proc_net, ip_rt_acct_read, NULL); #endif #endif #ifdef CONFIG_XFRM diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index e089a978e128..8855e640e958 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c @@ -62,6 +62,7 @@ #include #include +#include #include #include #include @@ -2249,7 +2250,7 @@ int tcp_proc_register(struct tcp_seq_afinfo *afinfo) afinfo->seq_fops->llseek = seq_lseek; afinfo->seq_fops->release = seq_release_private; - p = proc_net_fops_create(afinfo->name, S_IRUGO, afinfo->seq_fops); + p = proc_net_fops_create(&init_net, afinfo->name, S_IRUGO, afinfo->seq_fops); if (p) p->data = afinfo; else @@ -2261,7 +2262,7 @@ void tcp_proc_unregister(struct tcp_seq_afinfo *afinfo) { if (!afinfo) return; - proc_net_remove(afinfo->name); + proc_net_remove(&init_net, afinfo->name); memset(afinfo->seq_fops, 0, sizeof(*afinfo->seq_fops)); } diff --git a/net/ipv4/tcp_probe.c b/net/ipv4/tcp_probe.c index b76398d1b454..87dd5bff315f 100644 --- a/net/ipv4/tcp_probe.c +++ b/net/ipv4/tcp_probe.c @@ -26,6 +26,7 @@ #include #include #include +#include #include @@ -228,7 +229,7 @@ static __init int tcpprobe_init(void) if (!tcp_probe.log) goto err0; - if (!proc_net_fops_create(procname, S_IRUSR, &tcpprobe_fops)) + if (!proc_net_fops_create(&init_net, procname, S_IRUSR, &tcpprobe_fops)) goto err0; ret = register_jprobe(&tcp_jprobe); @@ -238,7 +239,7 @@ static __init int tcpprobe_init(void) pr_info("TCP probe registered (port=%d)\n", port); return 0; err1: - proc_net_remove(procname); + proc_net_remove(&init_net, procname); err0: kfree(tcp_probe.log); return ret; @@ -247,7 +248,7 @@ module_init(tcpprobe_init); static __exit void tcpprobe_exit(void) { - proc_net_remove(procname); + proc_net_remove(&init_net, procname); unregister_jprobe(&tcp_jprobe); kfree(tcp_probe.log); } diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index a581b543bff7..ef4d901ee9ad 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c @@ -98,6 +98,7 @@ #include #include #include +#include #include #include #include @@ -1566,7 +1567,7 @@ int udp_proc_register(struct udp_seq_afinfo *afinfo) afinfo->seq_fops->llseek = seq_lseek; afinfo->seq_fops->release = seq_release_private; - p = proc_net_fops_create(afinfo->name, S_IRUGO, afinfo->seq_fops); + p = proc_net_fops_create(&init_net, afinfo->name, S_IRUGO, afinfo->seq_fops); if (p) p->data = afinfo; else @@ -1578,7 +1579,7 @@ void udp_proc_unregister(struct udp_seq_afinfo *afinfo) { if (!afinfo) return; - proc_net_remove(afinfo->name); + proc_net_remove(&init_net, afinfo->name); memset(afinfo->seq_fops, 0, sizeof(*afinfo->seq_fops)); } diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 45b4c82148a0..cd2db728d183 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -62,6 +62,7 @@ #include #include +#include #include #include @@ -2827,14 +2828,14 @@ static const struct file_operations if6_fops = { int __init if6_proc_init(void) { - if (!proc_net_fops_create("if_inet6", S_IRUGO, &if6_fops)) + if (!proc_net_fops_create(&init_net, "if_inet6", S_IRUGO, &if6_fops)) return -ENOMEM; return 0; } void if6_proc_exit(void) { - proc_net_remove("if_inet6"); + proc_net_remove(&init_net, "if_inet6"); } #endif /* CONFIG_PROC_FS */ @@ -4293,6 +4294,6 @@ void __exit addrconf_cleanup(void) rtnl_unlock(); #ifdef CONFIG_PROC_FS - proc_net_remove("if_inet6"); + proc_net_remove(&init_net, "if_inet6"); #endif } diff --git a/net/ipv6/anycast.c b/net/ipv6/anycast.c index b8c533fbdb63..0bd665498d06 100644 --- a/net/ipv6/anycast.c +++ b/net/ipv6/anycast.c @@ -30,6 +30,7 @@ #include #include +#include #include #include @@ -578,7 +579,7 @@ static const struct file_operations ac6_seq_fops = { int __init ac6_proc_init(void) { - if (!proc_net_fops_create("anycast6", S_IRUGO, &ac6_seq_fops)) + if (!proc_net_fops_create(&init_net, "anycast6", S_IRUGO, &ac6_seq_fops)) return -ENOMEM; return 0; @@ -586,7 +587,7 @@ int __init ac6_proc_init(void) void ac6_proc_exit(void) { - proc_net_remove("anycast6"); + proc_net_remove(&init_net, "anycast6"); } #endif diff --git a/net/ipv6/ip6_flowlabel.c b/net/ipv6/ip6_flowlabel.c index 413a4ebb195c..1791399c7f10 100644 --- a/net/ipv6/ip6_flowlabel.c +++ b/net/ipv6/ip6_flowlabel.c @@ -21,6 +21,7 @@ #include #include +#include #include #include @@ -690,7 +691,7 @@ static const struct file_operations ip6fl_seq_fops = { void ip6_flowlabel_init(void) { #ifdef CONFIG_PROC_FS - proc_net_fops_create("ip6_flowlabel", S_IRUGO, &ip6fl_seq_fops); + proc_net_fops_create(&init_net, "ip6_flowlabel", S_IRUGO, &ip6fl_seq_fops); #endif } @@ -698,6 +699,6 @@ void ip6_flowlabel_cleanup(void) { del_timer(&ip6_fl_gc_timer); #ifdef CONFIG_PROC_FS - proc_net_remove("ip6_flowlabel"); + proc_net_remove(&init_net, "ip6_flowlabel"); #endif } diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c index ae9881832a7e..a41d5a0b50cc 100644 --- a/net/ipv6/mcast.c +++ b/net/ipv6/mcast.c @@ -49,6 +49,7 @@ #include #include +#include #include #include @@ -2658,8 +2659,8 @@ int __init igmp6_init(struct net_proto_family *ops) np->hop_limit = 1; #ifdef CONFIG_PROC_FS - proc_net_fops_create("igmp6", S_IRUGO, &igmp6_mc_seq_fops); - proc_net_fops_create("mcfilter6", S_IRUGO, &igmp6_mcf_seq_fops); + proc_net_fops_create(&init_net, "igmp6", S_IRUGO, &igmp6_mc_seq_fops); + proc_net_fops_create(&init_net, "mcfilter6", S_IRUGO, &igmp6_mcf_seq_fops); #endif return 0; @@ -2671,7 +2672,7 @@ void igmp6_cleanup(void) igmp6_socket = NULL; /* for safety */ #ifdef CONFIG_PROC_FS - proc_net_remove("mcfilter6"); - proc_net_remove("igmp6"); + proc_net_remove(&init_net, "mcfilter6"); + proc_net_remove(&init_net, "igmp6"); #endif } diff --git a/net/ipv6/netfilter/ip6_queue.c b/net/ipv6/netfilter/ip6_queue.c index 0004db38af6d..dfc58fbdb68b 100644 --- a/net/ipv6/netfilter/ip6_queue.c +++ b/net/ipv6/netfilter/ip6_queue.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -664,7 +665,7 @@ static int __init ip6_queue_init(void) goto cleanup_netlink_notifier; } - proc = proc_net_create(IPQ_PROC_FS_NAME, 0, ipq_get_info); + proc = proc_net_create(&init_net, IPQ_PROC_FS_NAME, 0, ipq_get_info); if (proc) proc->owner = THIS_MODULE; else { @@ -685,7 +686,7 @@ static int __init ip6_queue_init(void) cleanup_sysctl: unregister_sysctl_table(ipq_sysctl_header); unregister_netdevice_notifier(&ipq_dev_notifier); - proc_net_remove(IPQ_PROC_FS_NAME); + proc_net_remove(&init_net, IPQ_PROC_FS_NAME); cleanup_ipqnl: sock_release(ipqnl->sk_socket); @@ -705,7 +706,7 @@ static void __exit ip6_queue_fini(void) unregister_sysctl_table(ipq_sysctl_header); unregister_netdevice_notifier(&ipq_dev_notifier); - proc_net_remove(IPQ_PROC_FS_NAME); + proc_net_remove(&init_net, IPQ_PROC_FS_NAME); sock_release(ipqnl->sk_socket); mutex_lock(&ipqnl_mutex); diff --git a/net/ipv6/proc.c b/net/ipv6/proc.c index 920dc9cf6a84..a712a2289484 100644 --- a/net/ipv6/proc.c +++ b/net/ipv6/proc.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -231,22 +232,22 @@ int __init ipv6_misc_proc_init(void) { int rc = 0; - if (!proc_net_fops_create("snmp6", S_IRUGO, &snmp6_seq_fops)) + if (!proc_net_fops_create(&init_net, "snmp6", S_IRUGO, &snmp6_seq_fops)) goto proc_snmp6_fail; - proc_net_devsnmp6 = proc_mkdir("dev_snmp6", proc_net); + proc_net_devsnmp6 = proc_mkdir("dev_snmp6", init_net.proc_net); if (!proc_net_devsnmp6) goto proc_dev_snmp6_fail; - if (!proc_net_fops_create("sockstat6", S_IRUGO, &sockstat6_seq_fops)) + if (!proc_net_fops_create(&init_net, "sockstat6", S_IRUGO, &sockstat6_seq_fops)) goto proc_sockstat6_fail; out: return rc; proc_sockstat6_fail: - proc_net_remove("dev_snmp6"); + proc_net_remove(&init_net, "dev_snmp6"); proc_dev_snmp6_fail: - proc_net_remove("snmp6"); + proc_net_remove(&init_net, "snmp6"); proc_snmp6_fail: rc = -ENOMEM; goto out; @@ -254,8 +255,8 @@ proc_snmp6_fail: void ipv6_misc_proc_exit(void) { - proc_net_remove("sockstat6"); - proc_net_remove("dev_snmp6"); - proc_net_remove("snmp6"); + proc_net_remove(&init_net, "sockstat6"); + proc_net_remove(&init_net, "dev_snmp6"); + proc_net_remove(&init_net, "snmp6"); } diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c index 77167afa3455..38a3d21c2585 100644 --- a/net/ipv6/raw.c +++ b/net/ipv6/raw.c @@ -35,6 +35,7 @@ #include #include +#include #include #include #include @@ -1315,13 +1316,13 @@ static const struct file_operations raw6_seq_fops = { int __init raw6_proc_init(void) { - if (!proc_net_fops_create("raw6", S_IRUGO, &raw6_seq_fops)) + if (!proc_net_fops_create(&init_net, "raw6", S_IRUGO, &raw6_seq_fops)) return -ENOMEM; return 0; } void raw6_proc_exit(void) { - proc_net_remove("raw6"); + proc_net_remove(&init_net, "raw6"); } #endif /* CONFIG_PROC_FS */ diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 55ea80fac601..f4f0c341e5c8 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c @@ -44,6 +44,7 @@ #include #endif +#include #include #include #include @@ -2561,11 +2562,11 @@ void __init ip6_route_init(void) fib6_init(); #ifdef CONFIG_PROC_FS - p = proc_net_create("ipv6_route", 0, rt6_proc_info); + p = proc_net_create(&init_net, "ipv6_route", 0, rt6_proc_info); if (p) p->owner = THIS_MODULE; - proc_net_fops_create("rt6_stats", S_IRUGO, &rt6_stats_seq_fops); + proc_net_fops_create(&init_net, "rt6_stats", S_IRUGO, &rt6_stats_seq_fops); #endif #ifdef CONFIG_XFRM xfrm6_init(); @@ -2585,8 +2586,8 @@ void ip6_route_cleanup(void) fib6_rules_cleanup(); #endif #ifdef CONFIG_PROC_FS - proc_net_remove("ipv6_route"); - proc_net_remove("rt6_stats"); + proc_net_remove(&init_net, "ipv6_route"); + proc_net_remove(&init_net, "rt6_stats"); #endif #ifdef CONFIG_XFRM xfrm6_fini(); diff --git a/net/ipx/ipx_proc.c b/net/ipx/ipx_proc.c index 4226e71ae1e3..d483a00dc427 100644 --- a/net/ipx/ipx_proc.c +++ b/net/ipx/ipx_proc.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include @@ -353,7 +354,7 @@ int __init ipx_proc_init(void) struct proc_dir_entry *p; int rc = -ENOMEM; - ipx_proc_dir = proc_mkdir("ipx", proc_net); + ipx_proc_dir = proc_mkdir("ipx", init_net.proc_net); if (!ipx_proc_dir) goto out; @@ -381,7 +382,7 @@ out_socket: out_route: remove_proc_entry("interface", ipx_proc_dir); out_interface: - remove_proc_entry("ipx", proc_net); + remove_proc_entry("ipx", init_net.proc_net); goto out; } @@ -390,7 +391,7 @@ void __exit ipx_proc_exit(void) remove_proc_entry("interface", ipx_proc_dir); remove_proc_entry("route", ipx_proc_dir); remove_proc_entry("socket", ipx_proc_dir); - remove_proc_entry("ipx", proc_net); + remove_proc_entry("ipx", init_net.proc_net); } #else /* CONFIG_PROC_FS */ diff --git a/net/irda/irproc.c b/net/irda/irproc.c index 181cb51b48a8..cae24fbda966 100644 --- a/net/irda/irproc.c +++ b/net/irda/irproc.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include @@ -66,7 +67,7 @@ void __init irda_proc_register(void) int i; struct proc_dir_entry *d; - proc_irda = proc_mkdir("irda", proc_net); + proc_irda = proc_mkdir("irda", init_net.proc_net); if (proc_irda == NULL) return; proc_irda->owner = THIS_MODULE; @@ -92,7 +93,7 @@ void irda_proc_unregister(void) for (i=0; i #include #include +#include #include #include @@ -3776,7 +3777,7 @@ static struct xfrm_mgr pfkeyv2_mgr = static void __exit ipsec_pfkey_exit(void) { xfrm_unregister_km(&pfkeyv2_mgr); - remove_proc_entry("net/pfkey", NULL); + remove_proc_entry("pfkey", init_net.proc_net); sock_unregister(PF_KEY); proto_unregister(&key_proto); } @@ -3793,7 +3794,7 @@ static int __init ipsec_pfkey_init(void) goto out_unregister_key_proto; #ifdef CONFIG_PROC_FS err = -ENOMEM; - if (create_proc_read_entry("net/pfkey", 0, NULL, pfkey_read_proc, NULL) == NULL) + if (create_proc_read_entry("pfkey", 0, init_net.proc_net, pfkey_read_proc, NULL) == NULL) goto out_sock_unregister; #endif err = xfrm_register_km(&pfkeyv2_mgr); diff --git a/net/llc/llc_proc.c b/net/llc/llc_proc.c index 49be6c902c83..4865d82896b1 100644 --- a/net/llc/llc_proc.c +++ b/net/llc/llc_proc.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -231,7 +232,7 @@ int __init llc_proc_init(void) int rc = -ENOMEM; struct proc_dir_entry *p; - llc_proc_dir = proc_mkdir("llc", proc_net); + llc_proc_dir = proc_mkdir("llc", init_net.proc_net); if (!llc_proc_dir) goto out; llc_proc_dir->owner = THIS_MODULE; @@ -254,7 +255,7 @@ out: out_core: remove_proc_entry("socket", llc_proc_dir); out_socket: - remove_proc_entry("llc", proc_net); + remove_proc_entry("llc", init_net.proc_net); goto out; } @@ -262,5 +263,5 @@ void llc_proc_exit(void) { remove_proc_entry("socket", llc_proc_dir); remove_proc_entry("core", llc_proc_dir); - remove_proc_entry("llc", proc_net); + remove_proc_entry("llc", init_net.proc_net); } diff --git a/net/netfilter/core.c b/net/netfilter/core.c index 381a77cf0c9e..a523fa4136ed 100644 --- a/net/netfilter/core.c +++ b/net/netfilter/core.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include "nf_internals.h" @@ -293,7 +294,7 @@ void __init netfilter_init(void) } #ifdef CONFIG_PROC_FS - proc_net_netfilter = proc_mkdir("netfilter", proc_net); + proc_net_netfilter = proc_mkdir("netfilter", init_net.proc_net); if (!proc_net_netfilter) panic("cannot create netfilter proc entry"); #endif diff --git a/net/netfilter/nf_conntrack_expect.c b/net/netfilter/nf_conntrack_expect.c index 3ac64e25f10c..8a3e3af656bf 100644 --- a/net/netfilter/nf_conntrack_expect.c +++ b/net/netfilter/nf_conntrack_expect.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include @@ -505,7 +506,7 @@ static int __init exp_proc_init(void) #ifdef CONFIG_PROC_FS struct proc_dir_entry *proc; - proc = proc_net_fops_create("nf_conntrack_expect", 0440, &exp_file_ops); + proc = proc_net_fops_create(&init_net, "nf_conntrack_expect", 0440, &exp_file_ops); if (!proc) return -ENOMEM; #endif /* CONFIG_PROC_FS */ @@ -515,7 +516,7 @@ static int __init exp_proc_init(void) static void exp_proc_remove(void) { #ifdef CONFIG_PROC_FS - proc_net_remove("nf_conntrack_expect"); + proc_net_remove(&init_net, "nf_conntrack_expect"); #endif /* CONFIG_PROC_FS */ } diff --git a/net/netfilter/nf_conntrack_standalone.c b/net/netfilter/nf_conntrack_standalone.c index a4ce5e887997..2a19c5f1240f 100644 --- a/net/netfilter/nf_conntrack_standalone.c +++ b/net/netfilter/nf_conntrack_standalone.c @@ -14,6 +14,7 @@ #include #include #include +#include #ifdef CONFIG_SYSCTL #include #endif @@ -420,10 +421,10 @@ static int __init nf_conntrack_standalone_init(void) return ret; #ifdef CONFIG_PROC_FS - proc = proc_net_fops_create("nf_conntrack", 0440, &ct_file_ops); + proc = proc_net_fops_create(&init_net, "nf_conntrack", 0440, &ct_file_ops); if (!proc) goto cleanup_init; - proc_stat = create_proc_entry("nf_conntrack", S_IRUGO, proc_net_stat); + proc_stat = create_proc_entry("nf_conntrack", S_IRUGO, init_net.proc_net_stat); if (!proc_stat) goto cleanup_proc; @@ -444,9 +445,9 @@ static int __init nf_conntrack_standalone_init(void) cleanup_proc_stat: #endif #ifdef CONFIG_PROC_FS - remove_proc_entry("nf_conntrack", proc_net_stat); + remove_proc_entry("nf_conntrack", init_net. proc_net_stat); cleanup_proc: - proc_net_remove("nf_conntrack"); + proc_net_remove(&init_net, "nf_conntrack"); cleanup_init: #endif /* CNFIG_PROC_FS */ nf_conntrack_cleanup(); @@ -459,8 +460,8 @@ static void __exit nf_conntrack_standalone_fini(void) unregister_sysctl_table(nf_ct_sysctl_header); #endif #ifdef CONFIG_PROC_FS - remove_proc_entry("nf_conntrack", proc_net_stat); - proc_net_remove("nf_conntrack"); + remove_proc_entry("nf_conntrack", init_net.proc_net_stat); + proc_net_remove(&init_net, "nf_conntrack"); #endif /* CNFIG_PROC_FS */ nf_conntrack_cleanup(); } diff --git a/net/netfilter/x_tables.c b/net/netfilter/x_tables.c index cc2baa6d5a7a..d9a3bded0d00 100644 --- a/net/netfilter/x_tables.c +++ b/net/netfilter/x_tables.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include @@ -795,7 +796,7 @@ int xt_proto_init(int af) #ifdef CONFIG_PROC_FS strlcpy(buf, xt_prefix[af], sizeof(buf)); strlcat(buf, FORMAT_TABLES, sizeof(buf)); - proc = proc_net_fops_create(buf, 0440, &xt_file_ops); + proc = proc_net_fops_create(&init_net, buf, 0440, &xt_file_ops); if (!proc) goto out; proc->data = (void *) ((unsigned long) af | (TABLE << 16)); @@ -803,14 +804,14 @@ int xt_proto_init(int af) strlcpy(buf, xt_prefix[af], sizeof(buf)); strlcat(buf, FORMAT_MATCHES, sizeof(buf)); - proc = proc_net_fops_create(buf, 0440, &xt_file_ops); + proc = proc_net_fops_create(&init_net, buf, 0440, &xt_file_ops); if (!proc) goto out_remove_tables; proc->data = (void *) ((unsigned long) af | (MATCH << 16)); strlcpy(buf, xt_prefix[af], sizeof(buf)); strlcat(buf, FORMAT_TARGETS, sizeof(buf)); - proc = proc_net_fops_create(buf, 0440, &xt_file_ops); + proc = proc_net_fops_create(&init_net, buf, 0440, &xt_file_ops); if (!proc) goto out_remove_matches; proc->data = (void *) ((unsigned long) af | (TARGET << 16)); @@ -822,12 +823,12 @@ int xt_proto_init(int af) out_remove_matches: strlcpy(buf, xt_prefix[af], sizeof(buf)); strlcat(buf, FORMAT_MATCHES, sizeof(buf)); - proc_net_remove(buf); + proc_net_remove(&init_net, buf); out_remove_tables: strlcpy(buf, xt_prefix[af], sizeof(buf)); strlcat(buf, FORMAT_TABLES, sizeof(buf)); - proc_net_remove(buf); + proc_net_remove(&init_net, buf); out: return -1; #endif @@ -841,15 +842,15 @@ void xt_proto_fini(int af) strlcpy(buf, xt_prefix[af], sizeof(buf)); strlcat(buf, FORMAT_TABLES, sizeof(buf)); - proc_net_remove(buf); + proc_net_remove(&init_net, buf); strlcpy(buf, xt_prefix[af], sizeof(buf)); strlcat(buf, FORMAT_TARGETS, sizeof(buf)); - proc_net_remove(buf); + proc_net_remove(&init_net, buf); strlcpy(buf, xt_prefix[af], sizeof(buf)); strlcat(buf, FORMAT_MATCHES, sizeof(buf)); - proc_net_remove(buf); + proc_net_remove(&init_net, buf); #endif /*CONFIG_PROC_FS*/ } EXPORT_SYMBOL_GPL(xt_proto_fini); diff --git a/net/netfilter/xt_hashlimit.c b/net/netfilter/xt_hashlimit.c index bd45f9d3f7d0..19103678bf20 100644 --- a/net/netfilter/xt_hashlimit.c +++ b/net/netfilter/xt_hashlimit.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include @@ -743,13 +744,13 @@ static int __init xt_hashlimit_init(void) printk(KERN_ERR "xt_hashlimit: unable to create slab cache\n"); goto err2; } - hashlimit_procdir4 = proc_mkdir("ipt_hashlimit", proc_net); + hashlimit_procdir4 = proc_mkdir("ipt_hashlimit", init_net.proc_net); if (!hashlimit_procdir4) { printk(KERN_ERR "xt_hashlimit: unable to create proc dir " "entry\n"); goto err3; } - hashlimit_procdir6 = proc_mkdir("ip6t_hashlimit", proc_net); + hashlimit_procdir6 = proc_mkdir("ip6t_hashlimit", init_net.proc_net); if (!hashlimit_procdir6) { printk(KERN_ERR "xt_hashlimit: unable to create proc dir " "entry\n"); @@ -757,7 +758,7 @@ static int __init xt_hashlimit_init(void) } return 0; err4: - remove_proc_entry("ipt_hashlimit", proc_net); + remove_proc_entry("ipt_hashlimit", init_net.proc_net); err3: kmem_cache_destroy(hashlimit_cachep); err2: @@ -769,8 +770,8 @@ err1: static void __exit xt_hashlimit_fini(void) { - remove_proc_entry("ipt_hashlimit", proc_net); - remove_proc_entry("ip6t_hashlimit", proc_net); + remove_proc_entry("ipt_hashlimit", init_net.proc_net); + remove_proc_entry("ip6t_hashlimit", init_net.proc_net); kmem_cache_destroy(hashlimit_cachep); xt_unregister_matches(xt_hashlimit, ARRAY_SIZE(xt_hashlimit)); } diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c index a78d962e2c70..3982f13dab17 100644 --- a/net/netlink/af_netlink.c +++ b/net/netlink/af_netlink.c @@ -57,6 +57,7 @@ #include #include +#include #include #include #include @@ -1927,7 +1928,7 @@ static int __init netlink_proto_init(void) sock_register(&netlink_family_ops); #ifdef CONFIG_PROC_FS - proc_net_fops_create("netlink", 0, &netlink_seq_fops); + proc_net_fops_create(&init_net, "netlink", 0, &netlink_seq_fops); #endif /* The netlink device handler may be needed early. */ rtnetlink_init(); diff --git a/net/netrom/af_netrom.c b/net/netrom/af_netrom.c index dc9273295a38..15c8a92bd719 100644 --- a/net/netrom/af_netrom.c +++ b/net/netrom/af_netrom.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include @@ -1447,9 +1448,9 @@ static int __init nr_proto_init(void) nr_loopback_init(); - proc_net_fops_create("nr", S_IRUGO, &nr_info_fops); - proc_net_fops_create("nr_neigh", S_IRUGO, &nr_neigh_fops); - proc_net_fops_create("nr_nodes", S_IRUGO, &nr_nodes_fops); + proc_net_fops_create(&init_net, "nr", S_IRUGO, &nr_info_fops); + proc_net_fops_create(&init_net, "nr_neigh", S_IRUGO, &nr_neigh_fops); + proc_net_fops_create(&init_net, "nr_nodes", S_IRUGO, &nr_nodes_fops); out: return rc; fail: @@ -1477,9 +1478,9 @@ static void __exit nr_exit(void) { int i; - proc_net_remove("nr"); - proc_net_remove("nr_neigh"); - proc_net_remove("nr_nodes"); + proc_net_remove(&init_net, "nr"); + proc_net_remove(&init_net, "nr_neigh"); + proc_net_remove(&init_net, "nr_nodes"); nr_loopback_clear(); nr_rt_free(); diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c index 9c26dd9ee649..56502292f24c 100644 --- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c @@ -61,6 +61,7 @@ #include #include #include +#include #include #include #include @@ -1951,7 +1952,7 @@ static const struct file_operations packet_seq_fops = { static void __exit packet_exit(void) { - proc_net_remove("packet"); + proc_net_remove(&init_net, "packet"); unregister_netdevice_notifier(&packet_netdev_notifier); sock_unregister(PF_PACKET); proto_unregister(&packet_proto); @@ -1966,7 +1967,7 @@ static int __init packet_init(void) sock_register(&packet_family_ops); register_netdevice_notifier(&packet_netdev_notifier); - proc_net_fops_create("packet", 0, &packet_seq_fops); + proc_net_fops_create(&init_net, "packet", 0, &packet_seq_fops); out: return rc; } diff --git a/net/rose/af_rose.c b/net/rose/af_rose.c index 976c3cc86a29..48319f7991ac 100644 --- a/net/rose/af_rose.c +++ b/net/rose/af_rose.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -1576,10 +1577,10 @@ static int __init rose_proto_init(void) rose_add_loopback_neigh(); - proc_net_fops_create("rose", S_IRUGO, &rose_info_fops); - proc_net_fops_create("rose_neigh", S_IRUGO, &rose_neigh_fops); - proc_net_fops_create("rose_nodes", S_IRUGO, &rose_nodes_fops); - proc_net_fops_create("rose_routes", S_IRUGO, &rose_routes_fops); + proc_net_fops_create(&init_net, "rose", S_IRUGO, &rose_info_fops); + proc_net_fops_create(&init_net, "rose_neigh", S_IRUGO, &rose_neigh_fops); + proc_net_fops_create(&init_net, "rose_nodes", S_IRUGO, &rose_nodes_fops); + proc_net_fops_create(&init_net, "rose_routes", S_IRUGO, &rose_routes_fops); out: return rc; fail: @@ -1606,10 +1607,10 @@ static void __exit rose_exit(void) { int i; - proc_net_remove("rose"); - proc_net_remove("rose_neigh"); - proc_net_remove("rose_nodes"); - proc_net_remove("rose_routes"); + proc_net_remove(&init_net, "rose"); + proc_net_remove(&init_net, "rose_neigh"); + proc_net_remove(&init_net, "rose_nodes"); + proc_net_remove(&init_net, "rose_routes"); rose_loopback_clear(); rose_rt_free(); diff --git a/net/rxrpc/af_rxrpc.c b/net/rxrpc/af_rxrpc.c index c58fa0d1be26..122d55d992e1 100644 --- a/net/rxrpc/af_rxrpc.c +++ b/net/rxrpc/af_rxrpc.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include "ar-internal.h" @@ -829,8 +830,8 @@ static int __init af_rxrpc_init(void) } #ifdef CONFIG_PROC_FS - proc_net_fops_create("rxrpc_calls", 0, &rxrpc_call_seq_fops); - proc_net_fops_create("rxrpc_conns", 0, &rxrpc_connection_seq_fops); + proc_net_fops_create(&init_net, "rxrpc_calls", 0, &rxrpc_call_seq_fops); + proc_net_fops_create(&init_net, "rxrpc_conns", 0, &rxrpc_connection_seq_fops); #endif return 0; @@ -868,8 +869,8 @@ static void __exit af_rxrpc_exit(void) _debug("flush scheduled work"); flush_workqueue(rxrpc_workqueue); - proc_net_remove("rxrpc_conns"); - proc_net_remove("rxrpc_calls"); + proc_net_remove(&init_net, "rxrpc_conns"); + proc_net_remove(&init_net, "rxrpc_calls"); destroy_workqueue(rxrpc_workqueue); kmem_cache_destroy(rxrpc_call_jar); _leave(""); diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c index dee0d5fb39c5..efc383c58f1e 100644 --- a/net/sched/sch_api.c +++ b/net/sched/sch_api.c @@ -28,6 +28,7 @@ #include #include +#include #include #include @@ -1251,7 +1252,7 @@ static int __init pktsched_init(void) { register_qdisc(&pfifo_qdisc_ops); register_qdisc(&bfifo_qdisc_ops); - proc_net_fops_create("psched", 0, &psched_fops); + proc_net_fops_create(&init_net, "psched", 0, &psched_fops); rtnl_register(PF_UNSPEC, RTM_NEWQDISC, tc_modify_qdisc, NULL); rtnl_register(PF_UNSPEC, RTM_DELQDISC, tc_get_qdisc, NULL); diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c index 957c118a6068..30929e3ca05a 100644 --- a/net/sctp/protocol.c +++ b/net/sctp/protocol.c @@ -52,6 +52,7 @@ #include #include #include +#include #include #include #include @@ -98,7 +99,7 @@ static __init int sctp_proc_init(void) { if (!proc_net_sctp) { struct proc_dir_entry *ent; - ent = proc_mkdir("net/sctp", NULL); + ent = proc_mkdir("sctp", init_net.proc_net); if (ent) { ent->owner = THIS_MODULE; proc_net_sctp = ent; @@ -131,7 +132,7 @@ static void sctp_proc_exit(void) if (proc_net_sctp) { proc_net_sctp = NULL; - remove_proc_entry("net/sctp", NULL); + remove_proc_entry("sctp", init_net.proc_net); } } diff --git a/net/sunrpc/stats.c b/net/sunrpc/stats.c index 74ba7d443dfc..4d4f3738b688 100644 --- a/net/sunrpc/stats.c +++ b/net/sunrpc/stats.c @@ -21,6 +21,7 @@ #include #include #include +#include #define RPCDBG_FACILITY RPCDBG_MISC @@ -265,7 +266,7 @@ rpc_proc_init(void) dprintk("RPC: registering /proc/net/rpc\n"); if (!proc_net_rpc) { struct proc_dir_entry *ent; - ent = proc_mkdir("rpc", proc_net); + ent = proc_mkdir("rpc", init_net.proc_net); if (ent) { ent->owner = THIS_MODULE; proc_net_rpc = ent; @@ -279,7 +280,7 @@ rpc_proc_exit(void) dprintk("RPC: unregistering /proc/net/rpc\n"); if (proc_net_rpc) { proc_net_rpc = NULL; - remove_proc_entry("net/rpc", NULL); + remove_proc_entry("rpc", init_net.proc_net); } } diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index a05c34260e70..2386090c3a16 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c @@ -103,6 +103,7 @@ #include #include #include +#include #include #include #include @@ -2135,7 +2136,7 @@ static int __init af_unix_init(void) sock_register(&unix_family_ops); #ifdef CONFIG_PROC_FS - proc_net_fops_create("unix", 0, &unix_seq_fops); + proc_net_fops_create(&init_net, "unix", 0, &unix_seq_fops); #endif unix_sysctl_register(); out: @@ -2146,7 +2147,7 @@ static void __exit af_unix_exit(void) { sock_unregister(PF_UNIX); unix_sysctl_unregister(); - proc_net_remove("unix"); + proc_net_remove(&init_net, "unix"); proto_unregister(&unix_proto); } diff --git a/net/wanrouter/wanproc.c b/net/wanrouter/wanproc.c index 236e7eaf1b7f..f2e54c3f064e 100644 --- a/net/wanrouter/wanproc.c +++ b/net/wanrouter/wanproc.c @@ -29,6 +29,7 @@ #include #include +#include #include #define PROC_STATS_FORMAT "%30s: %12lu\n" @@ -287,7 +288,7 @@ static const struct file_operations wandev_fops = { int __init wanrouter_proc_init(void) { struct proc_dir_entry *p; - proc_router = proc_mkdir(ROUTER_NAME, proc_net); + proc_router = proc_mkdir(ROUTER_NAME, init_net.proc_net); if (!proc_router) goto fail; @@ -303,7 +304,7 @@ int __init wanrouter_proc_init(void) fail_stat: remove_proc_entry("config", proc_router); fail_config: - remove_proc_entry(ROUTER_NAME, proc_net); + remove_proc_entry(ROUTER_NAME, init_net.proc_net); fail: return -ENOMEM; } @@ -316,7 +317,7 @@ void wanrouter_proc_cleanup(void) { remove_proc_entry("config", proc_router); remove_proc_entry("status", proc_router); - remove_proc_entry(ROUTER_NAME, proc_net); + remove_proc_entry(ROUTER_NAME, init_net.proc_net); } /* diff --git a/net/wireless/wext.c b/net/wireless/wext.c index debf5191a128..b8069afe0410 100644 --- a/net/wireless/wext.c +++ b/net/wireless/wext.c @@ -93,6 +93,7 @@ #include /* ARPHRD_ETHER */ #include /* compare_ether_addr */ #include +#include #include /* Pretty obvious */ #include /* New driver API */ @@ -686,7 +687,7 @@ static const struct file_operations wireless_seq_fops = { int __init wext_proc_init(void) { /* Create /proc/net/wireless entry */ - if (!proc_net_fops_create("wireless", S_IRUGO, &wireless_seq_fops)) + if (!proc_net_fops_create(&init_net, "wireless", S_IRUGO, &wireless_seq_fops)) return -ENOMEM; return 0; diff --git a/net/x25/x25_proc.c b/net/x25/x25_proc.c index 7405b9c5b7f2..7d55e50c936f 100644 --- a/net/x25/x25_proc.c +++ b/net/x25/x25_proc.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include @@ -301,7 +302,7 @@ int __init x25_proc_init(void) struct proc_dir_entry *p; int rc = -ENOMEM; - x25_proc_dir = proc_mkdir("x25", proc_net); + x25_proc_dir = proc_mkdir("x25", init_net.proc_net); if (!x25_proc_dir) goto out; @@ -328,7 +329,7 @@ out_forward: out_socket: remove_proc_entry("route", x25_proc_dir); out_route: - remove_proc_entry("x25", proc_net); + remove_proc_entry("x25", init_net.proc_net); goto out; } @@ -337,7 +338,7 @@ void __exit x25_proc_exit(void) remove_proc_entry("forward", x25_proc_dir); remove_proc_entry("route", x25_proc_dir); remove_proc_entry("socket", x25_proc_dir); - remove_proc_entry("x25", proc_net); + remove_proc_entry("x25", init_net.proc_net); } #else /* CONFIG_PROC_FS */ -- cgit v1.2.3 From 1b8d7ae42d02e483ad94035cca851e4f7fbecb40 Mon Sep 17 00:00:00 2001 From: "Eric W. Biederman" Date: Mon, 8 Oct 2007 23:24:22 -0700 Subject: [NET]: Make socket creation namespace safe. This patch passes in the namespace a new socket should be created in and has the socket code do the appropriate reference counting. By virtue of this all socket create methods are touched. In addition the socket create methods are modified so that they will fail if you attempt to create a socket in a non-default network namespace. Failing if we attempt to create a socket outside of the default network namespace ensures that as we incrementally make the network stack network namespace aware we will not export functionality that someone has not audited and made certain is network namespace safe. Allowing us to partially enable network namespaces before all of the exotic protocols are supported. Any protocol layers I have missed will fail to compile because I now pass an extra parameter into the socket creation code. [ Integrated AF_IUCV build fixes from Andrew Morton... -DaveM ] Signed-off-by: Eric W. Biederman Signed-off-by: David S. Miller --- drivers/net/pppoe.c | 4 ++-- drivers/net/pppol2tp.c | 4 ++-- drivers/net/pppox.c | 7 +++++-- include/linux/if_pppox.h | 2 +- include/linux/net.h | 3 ++- include/net/iucv/af_iucv.h | 1 - include/net/llc_conn.h | 2 +- include/net/sock.h | 4 +++- net/appletalk/ddp.c | 7 +++++-- net/atm/common.c | 4 ++-- net/atm/common.h | 2 +- net/atm/pvc.c | 7 +++++-- net/atm/svc.c | 11 +++++++---- net/ax25/af_ax25.c | 9 ++++++--- net/bluetooth/af_bluetooth.c | 7 +++++-- net/bluetooth/bnep/sock.c | 4 ++-- net/bluetooth/cmtp/sock.c | 4 ++-- net/bluetooth/hci_sock.c | 4 ++-- net/bluetooth/hidp/sock.c | 4 ++-- net/bluetooth/l2cap.c | 10 +++++----- net/bluetooth/rfcomm/sock.c | 10 +++++----- net/bluetooth/sco.c | 10 +++++----- net/core/sock.c | 6 ++++-- net/decnet/af_decnet.c | 13 ++++++++----- net/econet/af_econet.c | 7 +++++-- net/ipv4/af_inet.c | 7 +++++-- net/ipv6/af_inet6.c | 7 +++++-- net/ipx/af_ipx.c | 7 +++++-- net/irda/af_irda.c | 11 +++++++---- net/iucv/af_iucv.c | 4 ++-- net/key/af_key.c | 7 +++++-- net/llc/af_llc.c | 7 +++++-- net/llc/llc_conn.c | 6 +++--- net/netlink/af_netlink.c | 15 +++++++++------ net/netrom/af_netrom.c | 9 ++++++--- net/packet/af_packet.c | 7 +++++-- net/rose/af_rose.c | 9 ++++++--- net/rxrpc/af_rxrpc.c | 7 +++++-- net/sctp/ipv6.c | 2 +- net/sctp/protocol.c | 2 +- net/socket.c | 9 +++++---- net/tipc/socket.c | 9 ++++++--- net/unix/af_unix.c | 13 ++++++++----- net/x25/af_x25.c | 13 ++++++++----- 44 files changed, 184 insertions(+), 113 deletions(-) (limited to 'include/linux') diff --git a/drivers/net/pppoe.c b/drivers/net/pppoe.c index ee8ce195c538..53fcee26d6ae 100644 --- a/drivers/net/pppoe.c +++ b/drivers/net/pppoe.c @@ -477,12 +477,12 @@ static struct proto pppoe_sk_proto = { * Initialize a new struct sock. * **********************************************************************/ -static int pppoe_create(struct socket *sock) +static int pppoe_create(struct net *net, struct socket *sock) { int error = -ENOMEM; struct sock *sk; - sk = sk_alloc(PF_PPPOX, GFP_KERNEL, &pppoe_sk_proto, 1); + sk = sk_alloc(net, PF_PPPOX, GFP_KERNEL, &pppoe_sk_proto, 1); if (!sk) goto out; diff --git a/drivers/net/pppol2tp.c b/drivers/net/pppol2tp.c index 2eb424ba58e5..921d4ef6d14b 100644 --- a/drivers/net/pppol2tp.c +++ b/drivers/net/pppol2tp.c @@ -1411,12 +1411,12 @@ static struct proto pppol2tp_sk_proto = { /* socket() handler. Initialize a new struct sock. */ -static int pppol2tp_create(struct socket *sock) +static int pppol2tp_create(struct net *net, struct socket *sock) { int error = -ENOMEM; struct sock *sk; - sk = sk_alloc(PF_PPPOX, GFP_KERNEL, &pppol2tp_sk_proto, 1); + sk = sk_alloc(net, PF_PPPOX, GFP_KERNEL, &pppol2tp_sk_proto, 1); if (!sk) goto out; diff --git a/drivers/net/pppox.c b/drivers/net/pppox.c index 25c52b55c38f..c6898c1fc54d 100644 --- a/drivers/net/pppox.c +++ b/drivers/net/pppox.c @@ -104,10 +104,13 @@ int pppox_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) EXPORT_SYMBOL(pppox_ioctl); -static int pppox_create(struct socket *sock, int protocol) +static int pppox_create(struct net *net, struct socket *sock, int protocol) { int rc = -EPROTOTYPE; + if (net != &init_net) + return -EAFNOSUPPORT; + if (protocol < 0 || protocol > PX_MAX_PROTO) goto out; @@ -123,7 +126,7 @@ static int pppox_create(struct socket *sock, int protocol) !try_module_get(pppox_protos[protocol]->owner)) goto out; - rc = pppox_protos[protocol]->create(sock); + rc = pppox_protos[protocol]->create(net, sock); module_put(pppox_protos[protocol]->owner); out: diff --git a/include/linux/if_pppox.h b/include/linux/if_pppox.h index 25652545ba6e..43cfc9f0c078 100644 --- a/include/linux/if_pppox.h +++ b/include/linux/if_pppox.h @@ -172,7 +172,7 @@ static inline struct sock *sk_pppox(struct pppox_sock *po) struct module; struct pppox_proto { - int (*create)(struct socket *sock); + int (*create)(struct net *net, struct socket *sock); int (*ioctl)(struct socket *sock, unsigned int cmd, unsigned long arg); struct module *owner; diff --git a/include/linux/net.h b/include/linux/net.h index efc45177b503..c136abce7ef6 100644 --- a/include/linux/net.h +++ b/include/linux/net.h @@ -23,6 +23,7 @@ struct poll_table_struct; struct inode; +struct net; #define NPROTO 34 /* should be enough for now.. */ @@ -169,7 +170,7 @@ struct proto_ops { struct net_proto_family { int family; - int (*create)(struct socket *sock, int protocol); + int (*create)(struct net *net, struct socket *sock, int protocol); struct module *owner; }; diff --git a/include/net/iucv/af_iucv.h b/include/net/iucv/af_iucv.h index b6c468cd7f5b..c661c6fd6fd5 100644 --- a/include/net/iucv/af_iucv.h +++ b/include/net/iucv/af_iucv.h @@ -78,7 +78,6 @@ static void iucv_sock_destruct(struct sock *sk); static void iucv_sock_cleanup_listen(struct sock *parent); static void iucv_sock_kill(struct sock *sk); static void iucv_sock_close(struct sock *sk); -static int iucv_sock_create(struct socket *sock, int proto); static int iucv_sock_bind(struct socket *sock, struct sockaddr *addr, int addr_len); static int iucv_sock_connect(struct socket *sock, struct sockaddr *addr, diff --git a/include/net/llc_conn.h b/include/net/llc_conn.h index 00730d21b522..e2374e34989f 100644 --- a/include/net/llc_conn.h +++ b/include/net/llc_conn.h @@ -93,7 +93,7 @@ static __inline__ char llc_backlog_type(struct sk_buff *skb) return skb->cb[sizeof(skb->cb) - 1]; } -extern struct sock *llc_sk_alloc(int family, gfp_t priority, +extern struct sock *llc_sk_alloc(struct net *net, int family, gfp_t priority, struct proto *prot); extern void llc_sk_free(struct sock *sk); diff --git a/include/net/sock.h b/include/net/sock.h index 9ef8b5fb7936..74e1f7d90d73 100644 --- a/include/net/sock.h +++ b/include/net/sock.h @@ -56,6 +56,7 @@ #include #include #include +#include /* * This structure really needs to be cleaned up. @@ -776,7 +777,7 @@ extern void FASTCALL(release_sock(struct sock *sk)); SINGLE_DEPTH_NESTING) #define bh_unlock_sock(__sk) spin_unlock(&((__sk)->sk_lock.slock)) -extern struct sock *sk_alloc(int family, +extern struct sock *sk_alloc(struct net *net, int family, gfp_t priority, struct proto *prot, int zero_it); extern void sk_free(struct sock *sk); @@ -1005,6 +1006,7 @@ static inline void sock_copy(struct sock *nsk, const struct sock *osk) #endif memcpy(nsk, osk, osk->sk_prot->obj_size); + get_net(nsk->sk_net); #ifdef CONFIG_SECURITY_NETWORK nsk->sk_security = sptr; security_sk_clone(osk, nsk); diff --git a/net/appletalk/ddp.c b/net/appletalk/ddp.c index 594b59739546..fd1d52f09707 100644 --- a/net/appletalk/ddp.c +++ b/net/appletalk/ddp.c @@ -1026,11 +1026,14 @@ static struct proto ddp_proto = { * Create a socket. Initialise the socket, blank the addresses * set the state. */ -static int atalk_create(struct socket *sock, int protocol) +static int atalk_create(struct net *net, struct socket *sock, int protocol) { struct sock *sk; int rc = -ESOCKTNOSUPPORT; + if (net != &init_net) + return -EAFNOSUPPORT; + /* * We permit SOCK_DGRAM and RAW is an extension. It is trivial to do * and gives you the full ELAP frame. Should be handy for CAP 8) @@ -1038,7 +1041,7 @@ static int atalk_create(struct socket *sock, int protocol) if (sock->type != SOCK_RAW && sock->type != SOCK_DGRAM) goto out; rc = -ENOMEM; - sk = sk_alloc(PF_APPLETALK, GFP_KERNEL, &ddp_proto, 1); + sk = sk_alloc(net, PF_APPLETALK, GFP_KERNEL, &ddp_proto, 1); if (!sk) goto out; rc = 0; diff --git a/net/atm/common.c b/net/atm/common.c index 299ec1eb872a..e166d9e0ffd9 100644 --- a/net/atm/common.c +++ b/net/atm/common.c @@ -125,7 +125,7 @@ static struct proto vcc_proto = { .obj_size = sizeof(struct atm_vcc), }; -int vcc_create(struct socket *sock, int protocol, int family) +int vcc_create(struct net *net, struct socket *sock, int protocol, int family) { struct sock *sk; struct atm_vcc *vcc; @@ -133,7 +133,7 @@ int vcc_create(struct socket *sock, int protocol, int family) sock->sk = NULL; if (sock->type == SOCK_STREAM) return -EINVAL; - sk = sk_alloc(family, GFP_KERNEL, &vcc_proto, 1); + sk = sk_alloc(net, family, GFP_KERNEL, &vcc_proto, 1); if (!sk) return -ENOMEM; sock_init_data(sock, sk); diff --git a/net/atm/common.h b/net/atm/common.h index ad78c9e1117d..16f32c1fa1c9 100644 --- a/net/atm/common.h +++ b/net/atm/common.h @@ -10,7 +10,7 @@ #include /* for poll_table */ -int vcc_create(struct socket *sock, int protocol, int family); +int vcc_create(struct net *net, struct socket *sock, int protocol, int family); int vcc_release(struct socket *sock); int vcc_connect(struct socket *sock, int itf, short vpi, int vci); int vcc_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, diff --git a/net/atm/pvc.c b/net/atm/pvc.c index 848e6e191cc7..43e8bf5ed001 100644 --- a/net/atm/pvc.c +++ b/net/atm/pvc.c @@ -124,10 +124,13 @@ static const struct proto_ops pvc_proto_ops = { }; -static int pvc_create(struct socket *sock,int protocol) +static int pvc_create(struct net *net, struct socket *sock,int protocol) { + if (net != &init_net) + return -EAFNOSUPPORT; + sock->ops = &pvc_proto_ops; - return vcc_create(sock, protocol, PF_ATMPVC); + return vcc_create(net, sock, protocol, PF_ATMPVC); } diff --git a/net/atm/svc.c b/net/atm/svc.c index 53d04c7992cf..daf9a48a7db0 100644 --- a/net/atm/svc.c +++ b/net/atm/svc.c @@ -25,7 +25,7 @@ #include "signaling.h" #include "addr.h" -static int svc_create(struct socket *sock,int protocol); +static int svc_create(struct net *net, struct socket *sock,int protocol); /* * Note: since all this is still nicely synchronized with the signaling demon, @@ -326,7 +326,7 @@ static int svc_accept(struct socket *sock,struct socket *newsock,int flags) lock_sock(sk); - error = svc_create(newsock,0); + error = svc_create(sk->sk_net, newsock,0); if (error) goto out; @@ -627,12 +627,15 @@ static const struct proto_ops svc_proto_ops = { }; -static int svc_create(struct socket *sock,int protocol) +static int svc_create(struct net *net, struct socket *sock,int protocol) { int error; + if (net != &init_net) + return -EAFNOSUPPORT; + sock->ops = &svc_proto_ops; - error = vcc_create(sock, protocol, AF_ATMSVC); + error = vcc_create(net, sock, protocol, AF_ATMSVC); if (error) return error; ATM_SD(sock)->local.sas_family = AF_ATMSVC; ATM_SD(sock)->remote.sas_family = AF_ATMSVC; diff --git a/net/ax25/af_ax25.c b/net/ax25/af_ax25.c index 1d71f85680b8..def6c42ad165 100644 --- a/net/ax25/af_ax25.c +++ b/net/ax25/af_ax25.c @@ -780,11 +780,14 @@ static struct proto ax25_proto = { .obj_size = sizeof(struct sock), }; -static int ax25_create(struct socket *sock, int protocol) +static int ax25_create(struct net *net, struct socket *sock, int protocol) { struct sock *sk; ax25_cb *ax25; + if (net != &init_net) + return -EAFNOSUPPORT; + switch (sock->type) { case SOCK_DGRAM: if (protocol == 0 || protocol == PF_AX25) @@ -830,7 +833,7 @@ static int ax25_create(struct socket *sock, int protocol) return -ESOCKTNOSUPPORT; } - if ((sk = sk_alloc(PF_AX25, GFP_ATOMIC, &ax25_proto, 1)) == NULL) + if ((sk = sk_alloc(net, PF_AX25, GFP_ATOMIC, &ax25_proto, 1)) == NULL) return -ENOMEM; ax25 = sk->sk_protinfo = ax25_create_cb(); @@ -855,7 +858,7 @@ struct sock *ax25_make_new(struct sock *osk, struct ax25_dev *ax25_dev) struct sock *sk; ax25_cb *ax25, *oax25; - if ((sk = sk_alloc(PF_AX25, GFP_ATOMIC, osk->sk_prot, 1)) == NULL) + if ((sk = sk_alloc(osk->sk_net, PF_AX25, GFP_ATOMIC, osk->sk_prot, 1)) == NULL) return NULL; if ((ax25 = ax25_create_cb()) == NULL) { diff --git a/net/bluetooth/af_bluetooth.c b/net/bluetooth/af_bluetooth.c index d942b946ba07..1220d8a41eb5 100644 --- a/net/bluetooth/af_bluetooth.c +++ b/net/bluetooth/af_bluetooth.c @@ -95,10 +95,13 @@ int bt_sock_unregister(int proto) } EXPORT_SYMBOL(bt_sock_unregister); -static int bt_sock_create(struct socket *sock, int proto) +static int bt_sock_create(struct net *net, struct socket *sock, int proto) { int err; + if (net != &init_net) + return -EAFNOSUPPORT; + if (proto < 0 || proto >= BT_MAX_PROTO) return -EINVAL; @@ -113,7 +116,7 @@ static int bt_sock_create(struct socket *sock, int proto) read_lock(&bt_proto_lock); if (bt_proto[proto] && try_module_get(bt_proto[proto]->owner)) { - err = bt_proto[proto]->create(sock, proto); + err = bt_proto[proto]->create(net, sock, proto); module_put(bt_proto[proto]->owner); } diff --git a/net/bluetooth/bnep/sock.c b/net/bluetooth/bnep/sock.c index 10292e776046..f718965f296c 100644 --- a/net/bluetooth/bnep/sock.c +++ b/net/bluetooth/bnep/sock.c @@ -204,7 +204,7 @@ static struct proto bnep_proto = { .obj_size = sizeof(struct bt_sock) }; -static int bnep_sock_create(struct socket *sock, int protocol) +static int bnep_sock_create(struct net *net, struct socket *sock, int protocol) { struct sock *sk; @@ -213,7 +213,7 @@ static int bnep_sock_create(struct socket *sock, int protocol) if (sock->type != SOCK_RAW) return -ESOCKTNOSUPPORT; - sk = sk_alloc(PF_BLUETOOTH, GFP_ATOMIC, &bnep_proto, 1); + sk = sk_alloc(net, PF_BLUETOOTH, GFP_ATOMIC, &bnep_proto, 1); if (!sk) return -ENOMEM; diff --git a/net/bluetooth/cmtp/sock.c b/net/bluetooth/cmtp/sock.c index 19be7861e51e..cf700c20d11e 100644 --- a/net/bluetooth/cmtp/sock.c +++ b/net/bluetooth/cmtp/sock.c @@ -195,7 +195,7 @@ static struct proto cmtp_proto = { .obj_size = sizeof(struct bt_sock) }; -static int cmtp_sock_create(struct socket *sock, int protocol) +static int cmtp_sock_create(struct net *net, struct socket *sock, int protocol) { struct sock *sk; @@ -204,7 +204,7 @@ static int cmtp_sock_create(struct socket *sock, int protocol) if (sock->type != SOCK_RAW) return -ESOCKTNOSUPPORT; - sk = sk_alloc(PF_BLUETOOTH, GFP_ATOMIC, &cmtp_proto, 1); + sk = sk_alloc(net, PF_BLUETOOTH, GFP_ATOMIC, &cmtp_proto, 1); if (!sk) return -ENOMEM; diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c index 5ccea5fbd236..43dd6373bff9 100644 --- a/net/bluetooth/hci_sock.c +++ b/net/bluetooth/hci_sock.c @@ -634,7 +634,7 @@ static struct proto hci_sk_proto = { .obj_size = sizeof(struct hci_pinfo) }; -static int hci_sock_create(struct socket *sock, int protocol) +static int hci_sock_create(struct net *net, struct socket *sock, int protocol) { struct sock *sk; @@ -645,7 +645,7 @@ static int hci_sock_create(struct socket *sock, int protocol) sock->ops = &hci_sock_ops; - sk = sk_alloc(PF_BLUETOOTH, GFP_ATOMIC, &hci_sk_proto, 1); + sk = sk_alloc(net, PF_BLUETOOTH, GFP_ATOMIC, &hci_sk_proto, 1); if (!sk) return -ENOMEM; diff --git a/net/bluetooth/hidp/sock.c b/net/bluetooth/hidp/sock.c index 0c185257e55b..1de2b6fbcac0 100644 --- a/net/bluetooth/hidp/sock.c +++ b/net/bluetooth/hidp/sock.c @@ -246,7 +246,7 @@ static struct proto hidp_proto = { .obj_size = sizeof(struct bt_sock) }; -static int hidp_sock_create(struct socket *sock, int protocol) +static int hidp_sock_create(struct net *net, struct socket *sock, int protocol) { struct sock *sk; @@ -255,7 +255,7 @@ static int hidp_sock_create(struct socket *sock, int protocol) if (sock->type != SOCK_RAW) return -ESOCKTNOSUPPORT; - sk = sk_alloc(PF_BLUETOOTH, GFP_ATOMIC, &hidp_proto, 1); + sk = sk_alloc(net, PF_BLUETOOTH, GFP_ATOMIC, &hidp_proto, 1); if (!sk) return -ENOMEM; diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c index c4e4ce4ebb2b..36ef27b625db 100644 --- a/net/bluetooth/l2cap.c +++ b/net/bluetooth/l2cap.c @@ -518,11 +518,11 @@ static struct proto l2cap_proto = { .obj_size = sizeof(struct l2cap_pinfo) }; -static struct sock *l2cap_sock_alloc(struct socket *sock, int proto, gfp_t prio) +static struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock, int proto, gfp_t prio) { struct sock *sk; - sk = sk_alloc(PF_BLUETOOTH, prio, &l2cap_proto, 1); + sk = sk_alloc(net, PF_BLUETOOTH, prio, &l2cap_proto, 1); if (!sk) return NULL; @@ -543,7 +543,7 @@ static struct sock *l2cap_sock_alloc(struct socket *sock, int proto, gfp_t prio) return sk; } -static int l2cap_sock_create(struct socket *sock, int protocol) +static int l2cap_sock_create(struct net *net, struct socket *sock, int protocol) { struct sock *sk; @@ -560,7 +560,7 @@ static int l2cap_sock_create(struct socket *sock, int protocol) sock->ops = &l2cap_sock_ops; - sk = l2cap_sock_alloc(sock, protocol, GFP_ATOMIC); + sk = l2cap_sock_alloc(net, sock, protocol, GFP_ATOMIC); if (!sk) return -ENOMEM; @@ -1425,7 +1425,7 @@ static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hd goto response; } - sk = l2cap_sock_alloc(NULL, BTPROTO_L2CAP, GFP_ATOMIC); + sk = l2cap_sock_alloc(parent->sk_net, NULL, BTPROTO_L2CAP, GFP_ATOMIC); if (!sk) goto response; diff --git a/net/bluetooth/rfcomm/sock.c b/net/bluetooth/rfcomm/sock.c index 30586ab9e878..266b6972667d 100644 --- a/net/bluetooth/rfcomm/sock.c +++ b/net/bluetooth/rfcomm/sock.c @@ -282,12 +282,12 @@ static struct proto rfcomm_proto = { .obj_size = sizeof(struct rfcomm_pinfo) }; -static struct sock *rfcomm_sock_alloc(struct socket *sock, int proto, gfp_t prio) +static struct sock *rfcomm_sock_alloc(struct net *net, struct socket *sock, int proto, gfp_t prio) { struct rfcomm_dlc *d; struct sock *sk; - sk = sk_alloc(PF_BLUETOOTH, prio, &rfcomm_proto, 1); + sk = sk_alloc(net, PF_BLUETOOTH, prio, &rfcomm_proto, 1); if (!sk) return NULL; @@ -323,7 +323,7 @@ static struct sock *rfcomm_sock_alloc(struct socket *sock, int proto, gfp_t prio return sk; } -static int rfcomm_sock_create(struct socket *sock, int protocol) +static int rfcomm_sock_create(struct net *net, struct socket *sock, int protocol) { struct sock *sk; @@ -336,7 +336,7 @@ static int rfcomm_sock_create(struct socket *sock, int protocol) sock->ops = &rfcomm_sock_ops; - sk = rfcomm_sock_alloc(sock, protocol, GFP_ATOMIC); + sk = rfcomm_sock_alloc(net, sock, protocol, GFP_ATOMIC); if (!sk) return -ENOMEM; @@ -868,7 +868,7 @@ int rfcomm_connect_ind(struct rfcomm_session *s, u8 channel, struct rfcomm_dlc * goto done; } - sk = rfcomm_sock_alloc(NULL, BTPROTO_RFCOMM, GFP_ATOMIC); + sk = rfcomm_sock_alloc(parent->sk_net, NULL, BTPROTO_RFCOMM, GFP_ATOMIC); if (!sk) goto done; diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c index 3f5163e725ed..65b6fb1c4154 100644 --- a/net/bluetooth/sco.c +++ b/net/bluetooth/sco.c @@ -414,11 +414,11 @@ static struct proto sco_proto = { .obj_size = sizeof(struct sco_pinfo) }; -static struct sock *sco_sock_alloc(struct socket *sock, int proto, gfp_t prio) +static struct sock *sco_sock_alloc(struct net *net, struct socket *sock, int proto, gfp_t prio) { struct sock *sk; - sk = sk_alloc(PF_BLUETOOTH, prio, &sco_proto, 1); + sk = sk_alloc(net, PF_BLUETOOTH, prio, &sco_proto, 1); if (!sk) return NULL; @@ -439,7 +439,7 @@ static struct sock *sco_sock_alloc(struct socket *sock, int proto, gfp_t prio) return sk; } -static int sco_sock_create(struct socket *sock, int protocol) +static int sco_sock_create(struct net *net, struct socket *sock, int protocol) { struct sock *sk; @@ -452,7 +452,7 @@ static int sco_sock_create(struct socket *sock, int protocol) sock->ops = &sco_sock_ops; - sk = sco_sock_alloc(sock, protocol, GFP_ATOMIC); + sk = sco_sock_alloc(net, sock, protocol, GFP_ATOMIC); if (!sk) return -ENOMEM; @@ -807,7 +807,7 @@ static void sco_conn_ready(struct sco_conn *conn) bh_lock_sock(parent); - sk = sco_sock_alloc(NULL, BTPROTO_SCO, GFP_ATOMIC); + sk = sco_sock_alloc(parent->sk_net, NULL, BTPROTO_SCO, GFP_ATOMIC); if (!sk) { bh_unlock_sock(parent); goto done; diff --git a/net/core/sock.c b/net/core/sock.c index bbc726a49d87..a31455dc7024 100644 --- a/net/core/sock.c +++ b/net/core/sock.c @@ -873,7 +873,7 @@ static inline void sock_lock_init(struct sock *sk) * @prot: struct proto associated with this new sock instance * @zero_it: if we should zero the newly allocated sock */ -struct sock *sk_alloc(int family, gfp_t priority, +struct sock *sk_alloc(struct net *net, int family, gfp_t priority, struct proto *prot, int zero_it) { struct sock *sk = NULL; @@ -894,6 +894,7 @@ struct sock *sk_alloc(int family, gfp_t priority, */ sk->sk_prot = sk->sk_prot_creator = prot; sock_lock_init(sk); + sk->sk_net = get_net(net); } if (security_sk_alloc(sk, family, priority)) @@ -933,6 +934,7 @@ void sk_free(struct sock *sk) __FUNCTION__, atomic_read(&sk->sk_omem_alloc)); security_sk_free(sk); + put_net(sk->sk_net); if (sk->sk_prot_creator->slab != NULL) kmem_cache_free(sk->sk_prot_creator->slab, sk); else @@ -942,7 +944,7 @@ void sk_free(struct sock *sk) struct sock *sk_clone(const struct sock *sk, const gfp_t priority) { - struct sock *newsk = sk_alloc(sk->sk_family, priority, sk->sk_prot, 0); + struct sock *newsk = sk_alloc(sk->sk_net, sk->sk_family, priority, sk->sk_prot, 0); if (newsk != NULL) { struct sk_filter *filter; diff --git a/net/decnet/af_decnet.c b/net/decnet/af_decnet.c index 625d5955b8e2..aca4c4930eb6 100644 --- a/net/decnet/af_decnet.c +++ b/net/decnet/af_decnet.c @@ -471,10 +471,10 @@ static struct proto dn_proto = { .obj_size = sizeof(struct dn_sock), }; -static struct sock *dn_alloc_sock(struct socket *sock, gfp_t gfp) +static struct sock *dn_alloc_sock(struct net *net, struct socket *sock, gfp_t gfp) { struct dn_scp *scp; - struct sock *sk = sk_alloc(PF_DECnet, gfp, &dn_proto, 1); + struct sock *sk = sk_alloc(net, PF_DECnet, gfp, &dn_proto, 1); if (!sk) goto out; @@ -675,10 +675,13 @@ char *dn_addr2asc(__u16 addr, char *buf) -static int dn_create(struct socket *sock, int protocol) +static int dn_create(struct net *net, struct socket *sock, int protocol) { struct sock *sk; + if (net != &init_net) + return -EAFNOSUPPORT; + switch(sock->type) { case SOCK_SEQPACKET: if (protocol != DNPROTO_NSP) @@ -691,7 +694,7 @@ static int dn_create(struct socket *sock, int protocol) } - if ((sk = dn_alloc_sock(sock, GFP_KERNEL)) == NULL) + if ((sk = dn_alloc_sock(net, sock, GFP_KERNEL)) == NULL) return -ENOBUFS; sk->sk_protocol = protocol; @@ -1091,7 +1094,7 @@ static int dn_accept(struct socket *sock, struct socket *newsock, int flags) cb = DN_SKB_CB(skb); sk->sk_ack_backlog--; - newsk = dn_alloc_sock(newsock, sk->sk_allocation); + newsk = dn_alloc_sock(sk->sk_net, newsock, sk->sk_allocation); if (newsk == NULL) { release_sock(sk); kfree_skb(skb); diff --git a/net/econet/af_econet.c b/net/econet/af_econet.c index 35c96bcc0f32..a2429dbcb86e 100644 --- a/net/econet/af_econet.c +++ b/net/econet/af_econet.c @@ -608,12 +608,15 @@ static struct proto econet_proto = { * Create an Econet socket */ -static int econet_create(struct socket *sock, int protocol) +static int econet_create(struct net *net, struct socket *sock, int protocol) { struct sock *sk; struct econet_sock *eo; int err; + if (net != &init_net) + return -EAFNOSUPPORT; + /* Econet only provides datagram services. */ if (sock->type != SOCK_DGRAM) return -ESOCKTNOSUPPORT; @@ -621,7 +624,7 @@ static int econet_create(struct socket *sock, int protocol) sock->state = SS_UNCONNECTED; err = -ENOBUFS; - sk = sk_alloc(PF_ECONET, GFP_KERNEL, &econet_proto, 1); + sk = sk_alloc(net, PF_ECONET, GFP_KERNEL, &econet_proto, 1); if (sk == NULL) goto out; diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c index e68103475cca..110a19edacc8 100644 --- a/net/ipv4/af_inet.c +++ b/net/ipv4/af_inet.c @@ -241,7 +241,7 @@ EXPORT_SYMBOL(build_ehash_secret); * Create an inet socket. */ -static int inet_create(struct socket *sock, int protocol) +static int inet_create(struct net *net, struct socket *sock, int protocol) { struct sock *sk; struct list_head *p; @@ -253,6 +253,9 @@ static int inet_create(struct socket *sock, int protocol) int try_loading_module = 0; int err; + if (net != &init_net) + return -EAFNOSUPPORT; + if (sock->type != SOCK_RAW && sock->type != SOCK_DGRAM && !inet_ehash_secret) @@ -320,7 +323,7 @@ lookup_protocol: BUG_TRAP(answer_prot->slab != NULL); err = -ENOBUFS; - sk = sk_alloc(PF_INET, GFP_KERNEL, answer_prot, 1); + sk = sk_alloc(net, PF_INET, GFP_KERNEL, answer_prot, 1); if (sk == NULL) goto out; diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c index b5f96372ad73..21931c86e95b 100644 --- a/net/ipv6/af_inet6.c +++ b/net/ipv6/af_inet6.c @@ -81,7 +81,7 @@ static __inline__ struct ipv6_pinfo *inet6_sk_generic(struct sock *sk) return (struct ipv6_pinfo *)(((u8 *)sk) + offset); } -static int inet6_create(struct socket *sock, int protocol) +static int inet6_create(struct net *net, struct socket *sock, int protocol) { struct inet_sock *inet; struct ipv6_pinfo *np; @@ -94,6 +94,9 @@ static int inet6_create(struct socket *sock, int protocol) int try_loading_module = 0; int err; + if (net != &init_net) + return -EAFNOSUPPORT; + if (sock->type != SOCK_RAW && sock->type != SOCK_DGRAM && !inet_ehash_secret) @@ -159,7 +162,7 @@ lookup_protocol: BUG_TRAP(answer_prot->slab != NULL); err = -ENOBUFS; - sk = sk_alloc(PF_INET6, GFP_KERNEL, answer_prot, 1); + sk = sk_alloc(net, PF_INET6, GFP_KERNEL, answer_prot, 1); if (sk == NULL) goto out; diff --git a/net/ipx/af_ipx.c b/net/ipx/af_ipx.c index 8400525177ab..ee28babad227 100644 --- a/net/ipx/af_ipx.c +++ b/net/ipx/af_ipx.c @@ -1360,11 +1360,14 @@ static struct proto ipx_proto = { .obj_size = sizeof(struct ipx_sock), }; -static int ipx_create(struct socket *sock, int protocol) +static int ipx_create(struct net *net, struct socket *sock, int protocol) { int rc = -ESOCKTNOSUPPORT; struct sock *sk; + if (net != &init_net) + return -EAFNOSUPPORT; + /* * SPX support is not anymore in the kernel sources. If you want to * ressurrect it, completing it and making it understand shared skbs, @@ -1375,7 +1378,7 @@ static int ipx_create(struct socket *sock, int protocol) goto out; rc = -ENOMEM; - sk = sk_alloc(PF_IPX, GFP_KERNEL, &ipx_proto, 1); + sk = sk_alloc(net, PF_IPX, GFP_KERNEL, &ipx_proto, 1); if (!sk) goto out; #ifdef IPX_REFCNT_DEBUG diff --git a/net/irda/af_irda.c b/net/irda/af_irda.c index c80949a71923..0328ae2654f4 100644 --- a/net/irda/af_irda.c +++ b/net/irda/af_irda.c @@ -60,7 +60,7 @@ #include -static int irda_create(struct socket *sock, int protocol); +static int irda_create(struct net *net, struct socket *sock, int protocol); static const struct proto_ops irda_stream_ops; static const struct proto_ops irda_seqpacket_ops; @@ -831,7 +831,7 @@ static int irda_accept(struct socket *sock, struct socket *newsock, int flags) IRDA_DEBUG(2, "%s()\n", __FUNCTION__); - err = irda_create(newsock, sk->sk_protocol); + err = irda_create(sk->sk_net, newsock, sk->sk_protocol); if (err) return err; @@ -1057,13 +1057,16 @@ static struct proto irda_proto = { * Create IrDA socket * */ -static int irda_create(struct socket *sock, int protocol) +static int irda_create(struct net *net, struct socket *sock, int protocol) { struct sock *sk; struct irda_sock *self; IRDA_DEBUG(2, "%s()\n", __FUNCTION__); + if (net != &init_net) + return -EAFNOSUPPORT; + /* Check for valid socket type */ switch (sock->type) { case SOCK_STREAM: /* For TTP connections with SAR disabled */ @@ -1075,7 +1078,7 @@ static int irda_create(struct socket *sock, int protocol) } /* Allocate networking socket */ - sk = sk_alloc(PF_IRDA, GFP_ATOMIC, &irda_proto, 1); + sk = sk_alloc(net, PF_IRDA, GFP_ATOMIC, &irda_proto, 1); if (sk == NULL) return -ENOMEM; diff --git a/net/iucv/af_iucv.c b/net/iucv/af_iucv.c index 53ae14c35f70..53668585e947 100644 --- a/net/iucv/af_iucv.c +++ b/net/iucv/af_iucv.c @@ -213,7 +213,7 @@ static struct sock *iucv_sock_alloc(struct socket *sock, int proto, gfp_t prio) { struct sock *sk; - sk = sk_alloc(PF_IUCV, prio, &iucv_proto, 1); + sk = sk_alloc(&init_net, PF_IUCV, prio, &iucv_proto, 1); if (!sk) return NULL; @@ -240,7 +240,7 @@ static struct sock *iucv_sock_alloc(struct socket *sock, int proto, gfp_t prio) } /* Create an IUCV socket */ -static int iucv_sock_create(struct socket *sock, int protocol) +static int iucv_sock_create(struct net *net, struct socket *sock, int protocol) { struct sock *sk; diff --git a/net/key/af_key.c b/net/key/af_key.c index 5b802bbb856e..ff5c3d03005e 100644 --- a/net/key/af_key.c +++ b/net/key/af_key.c @@ -136,11 +136,14 @@ static struct proto key_proto = { .obj_size = sizeof(struct pfkey_sock), }; -static int pfkey_create(struct socket *sock, int protocol) +static int pfkey_create(struct net *net, struct socket *sock, int protocol) { struct sock *sk; int err; + if (net != &init_net) + return -EAFNOSUPPORT; + if (!capable(CAP_NET_ADMIN)) return -EPERM; if (sock->type != SOCK_RAW) @@ -149,7 +152,7 @@ static int pfkey_create(struct socket *sock, int protocol) return -EPROTONOSUPPORT; err = -ENOMEM; - sk = sk_alloc(PF_KEY, GFP_KERNEL, &key_proto, 1); + sk = sk_alloc(net, PF_KEY, GFP_KERNEL, &key_proto, 1); if (sk == NULL) goto out; diff --git a/net/llc/af_llc.c b/net/llc/af_llc.c index 6b8a103cf9e6..b48244156e75 100644 --- a/net/llc/af_llc.c +++ b/net/llc/af_llc.c @@ -150,14 +150,17 @@ static struct proto llc_proto = { * socket type we have available. * Returns 0 upon success, negative upon failure. */ -static int llc_ui_create(struct socket *sock, int protocol) +static int llc_ui_create(struct net *net, struct socket *sock, int protocol) { struct sock *sk; int rc = -ESOCKTNOSUPPORT; + if (net != &init_net) + return -EAFNOSUPPORT; + if (likely(sock->type == SOCK_DGRAM || sock->type == SOCK_STREAM)) { rc = -ENOMEM; - sk = llc_sk_alloc(PF_LLC, GFP_KERNEL, &llc_proto); + sk = llc_sk_alloc(net, PF_LLC, GFP_KERNEL, &llc_proto); if (sk) { rc = 0; llc_ui_sk_init(sock, sk); diff --git a/net/llc/llc_conn.c b/net/llc/llc_conn.c index 3b8cfbe029a7..8ebc2769dfda 100644 --- a/net/llc/llc_conn.c +++ b/net/llc/llc_conn.c @@ -700,7 +700,7 @@ static struct sock *llc_create_incoming_sock(struct sock *sk, struct llc_addr *saddr, struct llc_addr *daddr) { - struct sock *newsk = llc_sk_alloc(sk->sk_family, GFP_ATOMIC, + struct sock *newsk = llc_sk_alloc(sk->sk_net, sk->sk_family, GFP_ATOMIC, sk->sk_prot); struct llc_sock *newllc, *llc = llc_sk(sk); @@ -867,9 +867,9 @@ static void llc_sk_init(struct sock* sk) * Allocates a LLC sock and initializes it. Returns the new LLC sock * or %NULL if there's no memory available for one */ -struct sock *llc_sk_alloc(int family, gfp_t priority, struct proto *prot) +struct sock *llc_sk_alloc(struct net *net, int family, gfp_t priority, struct proto *prot) { - struct sock *sk = sk_alloc(family, priority, prot, 1); + struct sock *sk = sk_alloc(net, family, priority, prot, 1); if (!sk) goto out; diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c index 3982f13dab17..406a493300d8 100644 --- a/net/netlink/af_netlink.c +++ b/net/netlink/af_netlink.c @@ -384,15 +384,15 @@ static struct proto netlink_proto = { .obj_size = sizeof(struct netlink_sock), }; -static int __netlink_create(struct socket *sock, struct mutex *cb_mutex, - int protocol) +static int __netlink_create(struct net *net, struct socket *sock, + struct mutex *cb_mutex, int protocol) { struct sock *sk; struct netlink_sock *nlk; sock->ops = &netlink_ops; - sk = sk_alloc(PF_NETLINK, GFP_KERNEL, &netlink_proto, 1); + sk = sk_alloc(net, PF_NETLINK, GFP_KERNEL, &netlink_proto, 1); if (!sk) return -ENOMEM; @@ -412,13 +412,16 @@ static int __netlink_create(struct socket *sock, struct mutex *cb_mutex, return 0; } -static int netlink_create(struct socket *sock, int protocol) +static int netlink_create(struct net *net, struct socket *sock, int protocol) { struct module *module = NULL; struct mutex *cb_mutex; struct netlink_sock *nlk; int err = 0; + if (net != &init_net) + return -EAFNOSUPPORT; + sock->state = SS_UNCONNECTED; if (sock->type != SOCK_RAW && sock->type != SOCK_DGRAM) @@ -441,7 +444,7 @@ static int netlink_create(struct socket *sock, int protocol) cb_mutex = nl_table[protocol].cb_mutex; netlink_unlock_table(); - if ((err = __netlink_create(sock, cb_mutex, protocol)) < 0) + if ((err = __netlink_create(net, sock, cb_mutex, protocol)) < 0) goto out_module; nlk = nlk_sk(sock->sk); @@ -1318,7 +1321,7 @@ netlink_kernel_create(int unit, unsigned int groups, if (sock_create_lite(PF_NETLINK, SOCK_DGRAM, unit, &sock)) return NULL; - if (__netlink_create(sock, cb_mutex, unit) < 0) + if (__netlink_create(&init_net, sock, cb_mutex, unit) < 0) goto out_sock_release; if (groups < 32) diff --git a/net/netrom/af_netrom.c b/net/netrom/af_netrom.c index 15c8a92bd719..e969d1bc765c 100644 --- a/net/netrom/af_netrom.c +++ b/net/netrom/af_netrom.c @@ -409,15 +409,18 @@ static struct proto nr_proto = { .obj_size = sizeof(struct nr_sock), }; -static int nr_create(struct socket *sock, int protocol) +static int nr_create(struct net *net, struct socket *sock, int protocol) { struct sock *sk; struct nr_sock *nr; + if (net != &init_net) + return -EAFNOSUPPORT; + if (sock->type != SOCK_SEQPACKET || protocol != 0) return -ESOCKTNOSUPPORT; - if ((sk = sk_alloc(PF_NETROM, GFP_ATOMIC, &nr_proto, 1)) == NULL) + if ((sk = sk_alloc(net, PF_NETROM, GFP_ATOMIC, &nr_proto, 1)) == NULL) return -ENOMEM; nr = nr_sk(sk); @@ -459,7 +462,7 @@ static struct sock *nr_make_new(struct sock *osk) if (osk->sk_type != SOCK_SEQPACKET) return NULL; - if ((sk = sk_alloc(PF_NETROM, GFP_ATOMIC, osk->sk_prot, 1)) == NULL) + if ((sk = sk_alloc(osk->sk_net, PF_NETROM, GFP_ATOMIC, osk->sk_prot, 1)) == NULL) return NULL; nr = nr_sk(sk); diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c index 56502292f24c..766b5faaed21 100644 --- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c @@ -977,13 +977,16 @@ static struct proto packet_proto = { * Create a packet of type SOCK_PACKET. */ -static int packet_create(struct socket *sock, int protocol) +static int packet_create(struct net *net, struct socket *sock, int protocol) { struct sock *sk; struct packet_sock *po; __be16 proto = (__force __be16)protocol; /* weird, but documented */ int err; + if (net != &init_net) + return -EAFNOSUPPORT; + if (!capable(CAP_NET_RAW)) return -EPERM; if (sock->type != SOCK_DGRAM && sock->type != SOCK_RAW && @@ -993,7 +996,7 @@ static int packet_create(struct socket *sock, int protocol) sock->state = SS_UNCONNECTED; err = -ENOBUFS; - sk = sk_alloc(PF_PACKET, GFP_KERNEL, &packet_proto, 1); + sk = sk_alloc(net, PF_PACKET, GFP_KERNEL, &packet_proto, 1); if (sk == NULL) goto out; diff --git a/net/rose/af_rose.c b/net/rose/af_rose.c index 48319f7991ac..67e06ab7f854 100644 --- a/net/rose/af_rose.c +++ b/net/rose/af_rose.c @@ -499,15 +499,18 @@ static struct proto rose_proto = { .obj_size = sizeof(struct rose_sock), }; -static int rose_create(struct socket *sock, int protocol) +static int rose_create(struct net *net, struct socket *sock, int protocol) { struct sock *sk; struct rose_sock *rose; + if (net != &init_net) + return -EAFNOSUPPORT; + if (sock->type != SOCK_SEQPACKET || protocol != 0) return -ESOCKTNOSUPPORT; - if ((sk = sk_alloc(PF_ROSE, GFP_ATOMIC, &rose_proto, 1)) == NULL) + if ((sk = sk_alloc(net, PF_ROSE, GFP_ATOMIC, &rose_proto, 1)) == NULL) return -ENOMEM; rose = rose_sk(sk); @@ -545,7 +548,7 @@ static struct sock *rose_make_new(struct sock *osk) if (osk->sk_type != SOCK_SEQPACKET) return NULL; - if ((sk = sk_alloc(PF_ROSE, GFP_ATOMIC, &rose_proto, 1)) == NULL) + if ((sk = sk_alloc(osk->sk_net, PF_ROSE, GFP_ATOMIC, &rose_proto, 1)) == NULL) return NULL; rose = rose_sk(sk); diff --git a/net/rxrpc/af_rxrpc.c b/net/rxrpc/af_rxrpc.c index 122d55d992e1..0803f305ed08 100644 --- a/net/rxrpc/af_rxrpc.c +++ b/net/rxrpc/af_rxrpc.c @@ -606,13 +606,16 @@ static unsigned int rxrpc_poll(struct file *file, struct socket *sock, /* * create an RxRPC socket */ -static int rxrpc_create(struct socket *sock, int protocol) +static int rxrpc_create(struct net *net, struct socket *sock, int protocol) { struct rxrpc_sock *rx; struct sock *sk; _enter("%p,%d", sock, protocol); + if (net != &init_net) + return -EAFNOSUPPORT; + /* we support transport protocol UDP only */ if (protocol != PF_INET) return -EPROTONOSUPPORT; @@ -623,7 +626,7 @@ static int rxrpc_create(struct socket *sock, int protocol) sock->ops = &rxrpc_rpc_ops; sock->state = SS_UNCONNECTED; - sk = sk_alloc(PF_RXRPC, GFP_KERNEL, &rxrpc_proto, 1); + sk = sk_alloc(net, PF_RXRPC, GFP_KERNEL, &rxrpc_proto, 1); if (!sk) return -ENOMEM; diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c index ec29b97dbab9..ddeb4882ec75 100644 --- a/net/sctp/ipv6.c +++ b/net/sctp/ipv6.c @@ -631,7 +631,7 @@ static struct sock *sctp_v6_create_accept_sk(struct sock *sk, struct ipv6_pinfo *newnp, *np = inet6_sk(sk); struct sctp6_sock *newsctp6sk; - newsk = sk_alloc(PF_INET6, GFP_KERNEL, sk->sk_prot, 1); + newsk = sk_alloc(sk->sk_net, PF_INET6, GFP_KERNEL, sk->sk_prot, 1); if (!newsk) goto out; diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c index 30929e3ca05a..af67c839ef98 100644 --- a/net/sctp/protocol.c +++ b/net/sctp/protocol.c @@ -552,7 +552,7 @@ static struct sock *sctp_v4_create_accept_sk(struct sock *sk, { struct inet_sock *inet = inet_sk(sk); struct inet_sock *newinet; - struct sock *newsk = sk_alloc(PF_INET, GFP_KERNEL, sk->sk_prot, 1); + struct sock *newsk = sk_alloc(sk->sk_net, PF_INET, GFP_KERNEL, sk->sk_prot, 1); if (!newsk) goto out; diff --git a/net/socket.c b/net/socket.c index b09eb9036a17..a714c6d4e4a1 100644 --- a/net/socket.c +++ b/net/socket.c @@ -84,6 +84,7 @@ #include #include #include +#include #include #include @@ -1071,7 +1072,7 @@ call_kill: return 0; } -static int __sock_create(int family, int type, int protocol, +static int __sock_create(struct net *net, int family, int type, int protocol, struct socket **res, int kern) { int err; @@ -1147,7 +1148,7 @@ static int __sock_create(int family, int type, int protocol, /* Now protected by module ref count */ rcu_read_unlock(); - err = pf->create(sock, protocol); + err = pf->create(net, sock, protocol); if (err < 0) goto out_module_put; @@ -1186,12 +1187,12 @@ out_release: int sock_create(int family, int type, int protocol, struct socket **res) { - return __sock_create(family, type, protocol, res, 0); + return __sock_create(current->nsproxy->net_ns, family, type, protocol, res, 0); } int sock_create_kern(int family, int type, int protocol, struct socket **res) { - return __sock_create(family, type, protocol, res, 1); + return __sock_create(&init_net, family, type, protocol, res, 1); } asmlinkage long sys_socket(int family, int type, int protocol) diff --git a/net/tipc/socket.c b/net/tipc/socket.c index 84110172031e..e36b4b5a5222 100644 --- a/net/tipc/socket.c +++ b/net/tipc/socket.c @@ -162,13 +162,16 @@ static void advance_queue(struct tipc_sock *tsock) * * Returns 0 on success, errno otherwise */ -static int tipc_create(struct socket *sock, int protocol) +static int tipc_create(struct net *net, struct socket *sock, int protocol) { struct tipc_sock *tsock; struct tipc_port *port; struct sock *sk; u32 ref; + if (net != &init_net) + return -EAFNOSUPPORT; + if (unlikely(protocol != 0)) return -EPROTONOSUPPORT; @@ -198,7 +201,7 @@ static int tipc_create(struct socket *sock, int protocol) return -EPROTOTYPE; } - sk = sk_alloc(AF_TIPC, GFP_KERNEL, &tipc_proto, 1); + sk = sk_alloc(net, AF_TIPC, GFP_KERNEL, &tipc_proto, 1); if (!sk) { tipc_deleteport(ref); return -ENOMEM; @@ -1372,7 +1375,7 @@ static int accept(struct socket *sock, struct socket *newsock, int flags) } buf = skb_peek(&sock->sk->sk_receive_queue); - res = tipc_create(newsock, 0); + res = tipc_create(sock->sk->sk_net, newsock, 0); if (!res) { struct tipc_sock *new_tsock = tipc_sk(newsock->sk); struct tipc_portid id; diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index 2386090c3a16..10e73122c34c 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c @@ -594,7 +594,7 @@ static struct proto unix_proto = { */ static struct lock_class_key af_unix_sk_receive_queue_lock_key; -static struct sock * unix_create1(struct socket *sock) +static struct sock * unix_create1(struct net *net, struct socket *sock) { struct sock *sk = NULL; struct unix_sock *u; @@ -602,7 +602,7 @@ static struct sock * unix_create1(struct socket *sock) if (atomic_read(&unix_nr_socks) >= 2*get_max_files()) goto out; - sk = sk_alloc(PF_UNIX, GFP_KERNEL, &unix_proto, 1); + sk = sk_alloc(net, PF_UNIX, GFP_KERNEL, &unix_proto, 1); if (!sk) goto out; @@ -628,8 +628,11 @@ out: return sk; } -static int unix_create(struct socket *sock, int protocol) +static int unix_create(struct net *net, struct socket *sock, int protocol) { + if (net != &init_net) + return -EAFNOSUPPORT; + if (protocol && protocol != PF_UNIX) return -EPROTONOSUPPORT; @@ -655,7 +658,7 @@ static int unix_create(struct socket *sock, int protocol) return -ESOCKTNOSUPPORT; } - return unix_create1(sock) ? 0 : -ENOMEM; + return unix_create1(net, sock) ? 0 : -ENOMEM; } static int unix_release(struct socket *sock) @@ -1039,7 +1042,7 @@ static int unix_stream_connect(struct socket *sock, struct sockaddr *uaddr, err = -ENOMEM; /* create new sock for complete connection */ - newsk = unix_create1(NULL); + newsk = unix_create1(sk->sk_net, NULL); if (newsk == NULL) goto out; diff --git a/net/x25/af_x25.c b/net/x25/af_x25.c index 479927cb45ca..2e9931571a4d 100644 --- a/net/x25/af_x25.c +++ b/net/x25/af_x25.c @@ -466,10 +466,10 @@ static struct proto x25_proto = { .obj_size = sizeof(struct x25_sock), }; -static struct sock *x25_alloc_socket(void) +static struct sock *x25_alloc_socket(struct net *net) { struct x25_sock *x25; - struct sock *sk = sk_alloc(AF_X25, GFP_ATOMIC, &x25_proto, 1); + struct sock *sk = sk_alloc(net, AF_X25, GFP_ATOMIC, &x25_proto, 1); if (!sk) goto out; @@ -485,17 +485,20 @@ out: return sk; } -static int x25_create(struct socket *sock, int protocol) +static int x25_create(struct net *net, struct socket *sock, int protocol) { struct sock *sk; struct x25_sock *x25; int rc = -ESOCKTNOSUPPORT; + if (net != &init_net) + return -EAFNOSUPPORT; + if (sock->type != SOCK_SEQPACKET || protocol) goto out; rc = -ENOMEM; - if ((sk = x25_alloc_socket()) == NULL) + if ((sk = x25_alloc_socket(net)) == NULL) goto out; x25 = x25_sk(sk); @@ -543,7 +546,7 @@ static struct sock *x25_make_new(struct sock *osk) if (osk->sk_type != SOCK_SEQPACKET) goto out; - if ((sk = x25_alloc_socket()) == NULL) + if ((sk = x25_alloc_socket(osk->sk_net)) == NULL) goto out; x25 = x25_sk(sk); -- cgit v1.2.3 From b4b510290b056b86611757ce1175a230f1080f53 Mon Sep 17 00:00:00 2001 From: "Eric W. Biederman" Date: Wed, 12 Sep 2007 13:05:38 +0200 Subject: [NET]: Support multiple network namespaces with netlink Each netlink socket will live in exactly one network namespace, this includes the controlling kernel sockets. This patch updates all of the existing netlink protocols to only support the initial network namespace. Request by clients in other namespaces will get -ECONREFUSED. As they would if the kernel did not have the support for that netlink protocol compiled in. As each netlink protocol is updated to be multiple network namespace safe it can register multiple kernel sockets to acquire a presence in the rest of the network namespaces. The implementation in af_netlink is a simple filter implementation at hash table insertion and hash table look up time. Signed-off-by: Eric W. Biederman Signed-off-by: David S. Miller --- drivers/connector/connector.c | 2 +- drivers/scsi/scsi_netlink.c | 2 +- drivers/scsi/scsi_transport_iscsi.c | 2 +- fs/ecryptfs/netlink.c | 2 +- include/linux/netlink.h | 6 ++- kernel/audit.c | 4 +- lib/kobject_uevent.c | 5 +- net/bridge/netfilter/ebt_ulog.c | 5 +- net/core/rtnetlink.c | 4 +- net/decnet/netfilter/dn_rtmsg.c | 3 +- net/ipv4/fib_frontend.c | 4 +- net/ipv4/inet_diag.c | 4 +- net/ipv4/netfilter/ip_queue.c | 6 +-- net/ipv4/netfilter/ipt_ULOG.c | 3 +- net/ipv6/netfilter/ip6_queue.c | 6 +-- net/netfilter/nfnetlink.c | 2 +- net/netfilter/nfnetlink_log.c | 3 +- net/netfilter/nfnetlink_queue.c | 3 +- net/netlink/af_netlink.c | 104 +++++++++++++++++++++++++++--------- net/netlink/genetlink.c | 4 +- net/xfrm/xfrm_user.c | 2 +- security/selinux/netlink.c | 5 +- 22 files changed, 121 insertions(+), 60 deletions(-) (limited to 'include/linux') diff --git a/drivers/connector/connector.c b/drivers/connector/connector.c index a7b9e9bb3e8d..569070997cc1 100644 --- a/drivers/connector/connector.c +++ b/drivers/connector/connector.c @@ -446,7 +446,7 @@ static int __devinit cn_init(void) dev->id.idx = cn_idx; dev->id.val = cn_val; - dev->nls = netlink_kernel_create(NETLINK_CONNECTOR, + dev->nls = netlink_kernel_create(&init_net, NETLINK_CONNECTOR, CN_NETLINK_USERS + 0xf, dev->input, NULL, THIS_MODULE); if (!dev->nls) diff --git a/drivers/scsi/scsi_netlink.c b/drivers/scsi/scsi_netlink.c index 4bf9aa547c78..163acf6ad2d3 100644 --- a/drivers/scsi/scsi_netlink.c +++ b/drivers/scsi/scsi_netlink.c @@ -167,7 +167,7 @@ scsi_netlink_init(void) return; } - scsi_nl_sock = netlink_kernel_create(NETLINK_SCSITRANSPORT, + scsi_nl_sock = netlink_kernel_create(&init_net, NETLINK_SCSITRANSPORT, SCSI_NL_GRP_CNT, scsi_nl_rcv, NULL, THIS_MODULE); if (!scsi_nl_sock) { diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c index 34c1860a259d..4916f01230dc 100644 --- a/drivers/scsi/scsi_transport_iscsi.c +++ b/drivers/scsi/scsi_transport_iscsi.c @@ -1523,7 +1523,7 @@ static __init int iscsi_transport_init(void) if (err) goto unregister_conn_class; - nls = netlink_kernel_create(NETLINK_ISCSI, 1, iscsi_if_rx, NULL, + nls = netlink_kernel_create(&init_net, NETLINK_ISCSI, 1, iscsi_if_rx, NULL, THIS_MODULE); if (!nls) { err = -ENOBUFS; diff --git a/fs/ecryptfs/netlink.c b/fs/ecryptfs/netlink.c index fe9186312d7c..056519cd92bc 100644 --- a/fs/ecryptfs/netlink.c +++ b/fs/ecryptfs/netlink.c @@ -227,7 +227,7 @@ int ecryptfs_init_netlink(void) { int rc; - ecryptfs_nl_sock = netlink_kernel_create(NETLINK_ECRYPTFS, 0, + ecryptfs_nl_sock = netlink_kernel_create(&init_net, NETLINK_ECRYPTFS, 0, ecryptfs_receive_nl_message, NULL, THIS_MODULE); if (!ecryptfs_nl_sock) { diff --git a/include/linux/netlink.h b/include/linux/netlink.h index 83d8239f0cce..d2843ae4a83a 100644 --- a/include/linux/netlink.h +++ b/include/linux/netlink.h @@ -27,6 +27,8 @@ #define MAX_LINKS 32 +struct net; + struct sockaddr_nl { sa_family_t nl_family; /* AF_NETLINK */ @@ -157,7 +159,8 @@ struct netlink_skb_parms #define NETLINK_CREDS(skb) (&NETLINK_CB((skb)).creds) -extern struct sock *netlink_kernel_create(int unit, unsigned int groups, +extern struct sock *netlink_kernel_create(struct net *net, + int unit,unsigned int groups, void (*input)(struct sock *sk, int len), struct mutex *cb_mutex, struct module *module); @@ -206,6 +209,7 @@ struct netlink_callback struct netlink_notify { + struct net *net; int pid; int protocol; }; diff --git a/kernel/audit.c b/kernel/audit.c index eb0f9165b401..f3c390f6c0b4 100644 --- a/kernel/audit.c +++ b/kernel/audit.c @@ -876,8 +876,8 @@ static int __init audit_init(void) printk(KERN_INFO "audit: initializing netlink socket (%s)\n", audit_default ? "enabled" : "disabled"); - audit_sock = netlink_kernel_create(NETLINK_AUDIT, 0, audit_receive, - NULL, THIS_MODULE); + audit_sock = netlink_kernel_create(&init_net, NETLINK_AUDIT, 0, + audit_receive, NULL, THIS_MODULE); if (!audit_sock) audit_panic("cannot initialize netlink socket"); else diff --git a/lib/kobject_uevent.c b/lib/kobject_uevent.c index df02814699d7..e06a8dcec0f0 100644 --- a/lib/kobject_uevent.c +++ b/lib/kobject_uevent.c @@ -280,9 +280,8 @@ EXPORT_SYMBOL_GPL(add_uevent_var); #if defined(CONFIG_NET) static int __init kobject_uevent_init(void) { - uevent_sock = netlink_kernel_create(NETLINK_KOBJECT_UEVENT, 1, NULL, - NULL, THIS_MODULE); - + uevent_sock = netlink_kernel_create(&init_net, NETLINK_KOBJECT_UEVENT, + 1, NULL, NULL, THIS_MODULE); if (!uevent_sock) { printk(KERN_ERR "kobject_uevent: unable to create netlink socket!\n"); diff --git a/net/bridge/netfilter/ebt_ulog.c b/net/bridge/netfilter/ebt_ulog.c index 204c968fa86d..e7cfd30bac75 100644 --- a/net/bridge/netfilter/ebt_ulog.c +++ b/net/bridge/netfilter/ebt_ulog.c @@ -300,8 +300,9 @@ static int __init ebt_ulog_init(void) spin_lock_init(&ulog_buffers[i].lock); } - ebtulognl = netlink_kernel_create(NETLINK_NFLOG, EBT_ULOG_MAXNLGROUPS, - NULL, NULL, THIS_MODULE); + ebtulognl = netlink_kernel_create(&init_net, NETLINK_NFLOG, + EBT_ULOG_MAXNLGROUPS, NULL, NULL, + THIS_MODULE); if (!ebtulognl) ret = -ENOMEM; else if ((ret = ebt_register_watcher(&ulog))) diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index 41859508bedd..416768d1e0cd 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c @@ -1327,8 +1327,8 @@ void __init rtnetlink_init(void) if (!rta_buf) panic("rtnetlink_init: cannot allocate rta_buf\n"); - rtnl = netlink_kernel_create(NETLINK_ROUTE, RTNLGRP_MAX, rtnetlink_rcv, - &rtnl_mutex, THIS_MODULE); + rtnl = netlink_kernel_create(&init_net, NETLINK_ROUTE, RTNLGRP_MAX, + rtnetlink_rcv, &rtnl_mutex, THIS_MODULE); if (rtnl == NULL) panic("rtnetlink_init: cannot initialize rtnetlink\n"); netlink_set_nonroot(NETLINK_ROUTE, NL_NONROOT_RECV); diff --git a/net/decnet/netfilter/dn_rtmsg.c b/net/decnet/netfilter/dn_rtmsg.c index 696234688cf6..ebb38feb4df3 100644 --- a/net/decnet/netfilter/dn_rtmsg.c +++ b/net/decnet/netfilter/dn_rtmsg.c @@ -137,7 +137,8 @@ static int __init dn_rtmsg_init(void) { int rv = 0; - dnrmg = netlink_kernel_create(NETLINK_DNRTMSG, DNRNG_NLGRP_MAX, + dnrmg = netlink_kernel_create(&init_net, + NETLINK_DNRTMSG, DNRNG_NLGRP_MAX, dnrmg_receive_user_sk, NULL, THIS_MODULE); if (dnrmg == NULL) { printk(KERN_ERR "dn_rtmsg: Cannot create netlink socket"); diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c index cefb55ec3d62..140bf7a8d877 100644 --- a/net/ipv4/fib_frontend.c +++ b/net/ipv4/fib_frontend.c @@ -816,8 +816,8 @@ static void nl_fib_input(struct sock *sk, int len) static void nl_fib_lookup_init(void) { - netlink_kernel_create(NETLINK_FIB_LOOKUP, 0, nl_fib_input, NULL, - THIS_MODULE); + netlink_kernel_create(&init_net, NETLINK_FIB_LOOKUP, 0, nl_fib_input, + NULL, THIS_MODULE); } static void fib_disable_ip(struct net_device *dev, int force) diff --git a/net/ipv4/inet_diag.c b/net/ipv4/inet_diag.c index 686ddd62f71a..031cc4856b49 100644 --- a/net/ipv4/inet_diag.c +++ b/net/ipv4/inet_diag.c @@ -897,8 +897,8 @@ static int __init inet_diag_init(void) if (!inet_diag_table) goto out; - idiagnl = netlink_kernel_create(NETLINK_INET_DIAG, 0, inet_diag_rcv, - NULL, THIS_MODULE); + idiagnl = netlink_kernel_create(&init_net, NETLINK_INET_DIAG, 0, + inet_diag_rcv, NULL, THIS_MODULE); if (idiagnl == NULL) goto out_free_table; err = 0; diff --git a/net/ipv4/netfilter/ip_queue.c b/net/ipv4/netfilter/ip_queue.c index d91856097f25..82fda92e6b97 100644 --- a/net/ipv4/netfilter/ip_queue.c +++ b/net/ipv4/netfilter/ip_queue.c @@ -579,7 +579,7 @@ ipq_rcv_nl_event(struct notifier_block *this, if (event == NETLINK_URELEASE && n->protocol == NETLINK_FIREWALL && n->pid) { write_lock_bh(&queue_lock); - if (n->pid == peer_pid) + if ((n->net == &init_net) && (n->pid == peer_pid)) __ipq_reset(); write_unlock_bh(&queue_lock); } @@ -671,8 +671,8 @@ static int __init ip_queue_init(void) struct proc_dir_entry *proc; netlink_register_notifier(&ipq_nl_notifier); - ipqnl = netlink_kernel_create(NETLINK_FIREWALL, 0, ipq_rcv_sk, - NULL, THIS_MODULE); + ipqnl = netlink_kernel_create(&init_net, NETLINK_FIREWALL, 0, + ipq_rcv_sk, NULL, THIS_MODULE); if (ipqnl == NULL) { printk(KERN_ERR "ip_queue: failed to create netlink socket\n"); goto cleanup_netlink_notifier; diff --git a/net/ipv4/netfilter/ipt_ULOG.c b/net/ipv4/netfilter/ipt_ULOG.c index 6ca43e4ca7e3..c636d6d63574 100644 --- a/net/ipv4/netfilter/ipt_ULOG.c +++ b/net/ipv4/netfilter/ipt_ULOG.c @@ -409,7 +409,8 @@ static int __init ipt_ulog_init(void) for (i = 0; i < ULOG_MAXNLGROUPS; i++) setup_timer(&ulog_buffers[i].timer, ulog_timer, i); - nflognl = netlink_kernel_create(NETLINK_NFLOG, ULOG_MAXNLGROUPS, NULL, + nflognl = netlink_kernel_create(&init_net, + NETLINK_NFLOG, ULOG_MAXNLGROUPS, NULL, NULL, THIS_MODULE); if (!nflognl) return -ENOMEM; diff --git a/net/ipv6/netfilter/ip6_queue.c b/net/ipv6/netfilter/ip6_queue.c index 64536a3ef2f6..2f5a52453834 100644 --- a/net/ipv6/netfilter/ip6_queue.c +++ b/net/ipv6/netfilter/ip6_queue.c @@ -569,7 +569,7 @@ ipq_rcv_nl_event(struct notifier_block *this, if (event == NETLINK_URELEASE && n->protocol == NETLINK_IP6_FW && n->pid) { write_lock_bh(&queue_lock); - if (n->pid == peer_pid) + if ((n->net == &init_net) && (n->pid == peer_pid)) __ipq_reset(); write_unlock_bh(&queue_lock); } @@ -661,8 +661,8 @@ static int __init ip6_queue_init(void) struct proc_dir_entry *proc; netlink_register_notifier(&ipq_nl_notifier); - ipqnl = netlink_kernel_create(NETLINK_IP6_FW, 0, ipq_rcv_sk, NULL, - THIS_MODULE); + ipqnl = netlink_kernel_create(&init_net, NETLINK_IP6_FW, 0, ipq_rcv_sk, + NULL, THIS_MODULE); if (ipqnl == NULL) { printk(KERN_ERR "ip6_queue: failed to create netlink socket\n"); goto cleanup_netlink_notifier; diff --git a/net/netfilter/nfnetlink.c b/net/netfilter/nfnetlink.c index 8797e6953ef2..fa974e8e0ce6 100644 --- a/net/netfilter/nfnetlink.c +++ b/net/netfilter/nfnetlink.c @@ -264,7 +264,7 @@ static int __init nfnetlink_init(void) { printk("Netfilter messages via NETLINK v%s.\n", nfversion); - nfnl = netlink_kernel_create(NETLINK_NETFILTER, NFNLGRP_MAX, + nfnl = netlink_kernel_create(&init_net, NETLINK_NETFILTER, NFNLGRP_MAX, nfnetlink_rcv, NULL, THIS_MODULE); if (!nfnl) { printk(KERN_ERR "cannot initialize nfnetlink!\n"); diff --git a/net/netfilter/nfnetlink_log.c b/net/netfilter/nfnetlink_log.c index 2351533a8507..8e4001b8f764 100644 --- a/net/netfilter/nfnetlink_log.c +++ b/net/netfilter/nfnetlink_log.c @@ -706,7 +706,8 @@ nfulnl_rcv_nl_event(struct notifier_block *this, hlist_for_each_entry_safe(inst, tmp, t2, head, hlist) { UDEBUG("node = %p\n", inst); - if (n->pid == inst->peer_pid) + if ((n->net == &init_net) && + (n->pid == inst->peer_pid)) __instance_destroy(inst); } } diff --git a/net/netfilter/nfnetlink_queue.c b/net/netfilter/nfnetlink_queue.c index 5a8e8ff76641..c97369f48db7 100644 --- a/net/netfilter/nfnetlink_queue.c +++ b/net/netfilter/nfnetlink_queue.c @@ -765,7 +765,8 @@ nfqnl_rcv_nl_event(struct notifier_block *this, struct hlist_head *head = &instance_table[i]; hlist_for_each_entry_safe(inst, tmp, t2, head, hlist) { - if (n->pid == inst->peer_pid) + if ((n->net == &init_net) && + (n->pid == inst->peer_pid)) __instance_destroy(inst); } } diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c index 406a493300d8..3029f865cd61 100644 --- a/net/netlink/af_netlink.c +++ b/net/netlink/af_netlink.c @@ -211,7 +211,7 @@ netlink_unlock_table(void) wake_up(&nl_table_wait); } -static __inline__ struct sock *netlink_lookup(int protocol, u32 pid) +static __inline__ struct sock *netlink_lookup(struct net *net, int protocol, u32 pid) { struct nl_pid_hash *hash = &nl_table[protocol].hash; struct hlist_head *head; @@ -221,7 +221,7 @@ static __inline__ struct sock *netlink_lookup(int protocol, u32 pid) read_lock(&nl_table_lock); head = nl_pid_hashfn(hash, pid); sk_for_each(sk, node, head) { - if (nlk_sk(sk)->pid == pid) { + if ((sk->sk_net == net) && (nlk_sk(sk)->pid == pid)) { sock_hold(sk); goto found; } @@ -328,7 +328,7 @@ netlink_update_listeners(struct sock *sk) * makes sure updates are visible before bind or setsockopt return. */ } -static int netlink_insert(struct sock *sk, u32 pid) +static int netlink_insert(struct sock *sk, struct net *net, u32 pid) { struct nl_pid_hash *hash = &nl_table[sk->sk_protocol].hash; struct hlist_head *head; @@ -341,7 +341,7 @@ static int netlink_insert(struct sock *sk, u32 pid) head = nl_pid_hashfn(hash, pid); len = 0; sk_for_each(osk, node, head) { - if (nlk_sk(osk)->pid == pid) + if ((osk->sk_net == net) && (nlk_sk(osk)->pid == pid)) break; len++; } @@ -419,9 +419,6 @@ static int netlink_create(struct net *net, struct socket *sock, int protocol) struct netlink_sock *nlk; int err = 0; - if (net != &init_net) - return -EAFNOSUPPORT; - sock->state = SS_UNCONNECTED; if (sock->type != SOCK_RAW && sock->type != SOCK_DGRAM) @@ -481,6 +478,7 @@ static int netlink_release(struct socket *sock) if (nlk->pid && !nlk->subscriptions) { struct netlink_notify n = { + .net = sk->sk_net, .protocol = sk->sk_protocol, .pid = nlk->pid, }; @@ -509,6 +507,7 @@ static int netlink_release(struct socket *sock) static int netlink_autobind(struct socket *sock) { struct sock *sk = sock->sk; + struct net *net = sk->sk_net; struct nl_pid_hash *hash = &nl_table[sk->sk_protocol].hash; struct hlist_head *head; struct sock *osk; @@ -522,6 +521,8 @@ retry: netlink_table_grab(); head = nl_pid_hashfn(hash, pid); sk_for_each(osk, node, head) { + if ((osk->sk_net != net)) + continue; if (nlk_sk(osk)->pid == pid) { /* Bind collision, search negative pid values. */ pid = rover--; @@ -533,7 +534,7 @@ retry: } netlink_table_ungrab(); - err = netlink_insert(sk, pid); + err = netlink_insert(sk, net, pid); if (err == -EADDRINUSE) goto retry; @@ -598,6 +599,7 @@ static int netlink_realloc_groups(struct sock *sk) static int netlink_bind(struct socket *sock, struct sockaddr *addr, int addr_len) { struct sock *sk = sock->sk; + struct net *net = sk->sk_net; struct netlink_sock *nlk = nlk_sk(sk); struct sockaddr_nl *nladdr = (struct sockaddr_nl *)addr; int err; @@ -619,7 +621,7 @@ static int netlink_bind(struct socket *sock, struct sockaddr *addr, int addr_len return -EINVAL; } else { err = nladdr->nl_pid ? - netlink_insert(sk, nladdr->nl_pid) : + netlink_insert(sk, net, nladdr->nl_pid) : netlink_autobind(sock); if (err) return err; @@ -703,10 +705,12 @@ static void netlink_overrun(struct sock *sk) static struct sock *netlink_getsockbypid(struct sock *ssk, u32 pid) { int protocol = ssk->sk_protocol; + struct net *net; struct sock *sock; struct netlink_sock *nlk; - sock = netlink_lookup(protocol, pid); + net = ssk->sk_net; + sock = netlink_lookup(net, protocol, pid); if (!sock) return ERR_PTR(-ECONNREFUSED); @@ -887,6 +891,7 @@ static __inline__ int netlink_broadcast_deliver(struct sock *sk, struct sk_buff struct netlink_broadcast_data { struct sock *exclude_sk; + struct net *net; u32 pid; u32 group; int failure; @@ -909,6 +914,9 @@ static inline int do_one_broadcast(struct sock *sk, !test_bit(p->group - 1, nlk->groups)) goto out; + if ((sk->sk_net != p->net)) + goto out; + if (p->failure) { netlink_overrun(sk); goto out; @@ -947,6 +955,7 @@ out: int netlink_broadcast(struct sock *ssk, struct sk_buff *skb, u32 pid, u32 group, gfp_t allocation) { + struct net *net = ssk->sk_net; struct netlink_broadcast_data info; struct hlist_node *node; struct sock *sk; @@ -954,6 +963,7 @@ int netlink_broadcast(struct sock *ssk, struct sk_buff *skb, u32 pid, skb = netlink_trim(skb, allocation); info.exclude_sk = ssk; + info.net = net; info.pid = pid; info.group = group; info.failure = 0; @@ -1002,6 +1012,9 @@ static inline int do_one_set_err(struct sock *sk, if (sk == p->exclude_sk) goto out; + if (sk->sk_net != p->exclude_sk->sk_net) + goto out; + if (nlk->pid == p->pid || p->group - 1 >= nlk->ngroups || !test_bit(p->group - 1, nlk->groups)) goto out; @@ -1304,7 +1317,7 @@ static void netlink_data_ready(struct sock *sk, int len) */ struct sock * -netlink_kernel_create(int unit, unsigned int groups, +netlink_kernel_create(struct net *net, int unit, unsigned int groups, void (*input)(struct sock *sk, int len), struct mutex *cb_mutex, struct module *module) { @@ -1321,7 +1334,7 @@ netlink_kernel_create(int unit, unsigned int groups, if (sock_create_lite(PF_NETLINK, SOCK_DGRAM, unit, &sock)) return NULL; - if (__netlink_create(&init_net, sock, cb_mutex, unit) < 0) + if (__netlink_create(net, sock, cb_mutex, unit) < 0) goto out_sock_release; if (groups < 32) @@ -1336,18 +1349,20 @@ netlink_kernel_create(int unit, unsigned int groups, if (input) nlk_sk(sk)->data_ready = input; - if (netlink_insert(sk, 0)) + if (netlink_insert(sk, net, 0)) goto out_sock_release; nlk = nlk_sk(sk); nlk->flags |= NETLINK_KERNEL_SOCKET; netlink_table_grab(); - nl_table[unit].groups = groups; - nl_table[unit].listeners = listeners; - nl_table[unit].cb_mutex = cb_mutex; - nl_table[unit].module = module; - nl_table[unit].registered = 1; + if (!nl_table[unit].registered) { + nl_table[unit].groups = groups; + nl_table[unit].listeners = listeners; + nl_table[unit].cb_mutex = cb_mutex; + nl_table[unit].module = module; + nl_table[unit].registered = 1; + } netlink_table_ungrab(); return sk; @@ -1513,7 +1528,7 @@ int netlink_dump_start(struct sock *ssk, struct sk_buff *skb, atomic_inc(&skb->users); cb->skb = skb; - sk = netlink_lookup(ssk->sk_protocol, NETLINK_CB(skb).pid); + sk = netlink_lookup(ssk->sk_net, ssk->sk_protocol, NETLINK_CB(skb).pid); if (sk == NULL) { netlink_destroy_callback(cb); return -ECONNREFUSED; @@ -1555,7 +1570,8 @@ void netlink_ack(struct sk_buff *in_skb, struct nlmsghdr *nlh, int err) if (!skb) { struct sock *sk; - sk = netlink_lookup(in_skb->sk->sk_protocol, + sk = netlink_lookup(in_skb->sk->sk_net, + in_skb->sk->sk_protocol, NETLINK_CB(in_skb).pid); if (sk) { sk->sk_err = ENOBUFS; @@ -1706,6 +1722,7 @@ int nlmsg_notify(struct sock *sk, struct sk_buff *skb, u32 pid, #ifdef CONFIG_PROC_FS struct nl_seq_iter { + struct net *net; int link; int hash_idx; }; @@ -1723,6 +1740,8 @@ static struct sock *netlink_seq_socket_idx(struct seq_file *seq, loff_t pos) for (j = 0; j <= hash->mask; j++) { sk_for_each(s, node, &hash->table[j]) { + if (iter->net != s->sk_net) + continue; if (off == pos) { iter->link = i; iter->hash_idx = j; @@ -1752,11 +1771,14 @@ static void *netlink_seq_next(struct seq_file *seq, void *v, loff_t *pos) if (v == SEQ_START_TOKEN) return netlink_seq_socket_idx(seq, 0); - s = sk_next(v); + iter = seq->private; + s = v; + do { + s = sk_next(s); + } while (s && (iter->net != s->sk_net)); if (s) return s; - iter = seq->private; i = iter->link; j = iter->hash_idx + 1; @@ -1765,6 +1787,8 @@ static void *netlink_seq_next(struct seq_file *seq, void *v, loff_t *pos) for (; j <= hash->mask; j++) { s = sk_head(&hash->table[j]); + while (s && (iter->net != s->sk_net)) + s = sk_next(s); if (s) { iter->link = i; iter->hash_idx = j; @@ -1835,15 +1859,24 @@ static int netlink_seq_open(struct inode *inode, struct file *file) seq = file->private_data; seq->private = iter; + iter->net = get_net(PROC_NET(inode)); return 0; } +static int netlink_seq_release(struct inode *inode, struct file *file) +{ + struct seq_file *seq = file->private_data; + struct nl_seq_iter *iter = seq->private; + put_net(iter->net); + return seq_release_private(inode, file); +} + static const struct file_operations netlink_seq_fops = { .owner = THIS_MODULE, .open = netlink_seq_open, .read = seq_read, .llseek = seq_lseek, - .release = seq_release_private, + .release = netlink_seq_release, }; #endif @@ -1885,6 +1918,27 @@ static struct net_proto_family netlink_family_ops = { .owner = THIS_MODULE, /* for consistency 8) */ }; +static int netlink_net_init(struct net *net) +{ +#ifdef CONFIG_PROC_FS + if (!proc_net_fops_create(net, "netlink", 0, &netlink_seq_fops)) + return -ENOMEM; +#endif + return 0; +} + +static void netlink_net_exit(struct net *net) +{ +#ifdef CONFIG_PROC_FS + proc_net_remove(net, "netlink"); +#endif +} + +static struct pernet_operations netlink_net_ops = { + .init = netlink_net_init, + .exit = netlink_net_exit, +}; + static int __init netlink_proto_init(void) { struct sk_buff *dummy_skb; @@ -1930,9 +1984,7 @@ static int __init netlink_proto_init(void) } sock_register(&netlink_family_ops); -#ifdef CONFIG_PROC_FS - proc_net_fops_create(&init_net, "netlink", 0, &netlink_seq_fops); -#endif + register_pernet_subsys(&netlink_net_ops); /* The netlink device handler may be needed early. */ rtnetlink_init(); out: diff --git a/net/netlink/genetlink.c b/net/netlink/genetlink.c index 8c11ca4a2121..af8fe26815fa 100644 --- a/net/netlink/genetlink.c +++ b/net/netlink/genetlink.c @@ -782,8 +782,8 @@ static int __init genl_init(void) netlink_set_nonroot(NETLINK_GENERIC, NL_NONROOT_RECV); /* we'll bump the group number right afterwards */ - genl_sock = netlink_kernel_create(NETLINK_GENERIC, 0, genl_rcv, - NULL, THIS_MODULE); + genl_sock = netlink_kernel_create(&init_net, NETLINK_GENERIC, 0, + genl_rcv, NULL, THIS_MODULE); if (genl_sock == NULL) panic("GENL: Cannot initialize generic netlink\n"); diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c index 0d81c0f23919..1f8e7c22ddbd 100644 --- a/net/xfrm/xfrm_user.c +++ b/net/xfrm/xfrm_user.c @@ -2399,7 +2399,7 @@ static int __init xfrm_user_init(void) printk(KERN_INFO "Initializing XFRM netlink socket\n"); - nlsk = netlink_kernel_create(NETLINK_XFRM, XFRMNLGRP_MAX, + nlsk = netlink_kernel_create(&init_net, NETLINK_XFRM, XFRMNLGRP_MAX, xfrm_netlink_rcv, NULL, THIS_MODULE); if (nlsk == NULL) return -ENOMEM; diff --git a/security/selinux/netlink.c b/security/selinux/netlink.c index f49046de63a2..b59871d74dad 100644 --- a/security/selinux/netlink.c +++ b/security/selinux/netlink.c @@ -17,6 +17,7 @@ #include #include #include +#include static struct sock *selnl; @@ -104,8 +105,8 @@ void selnl_notify_policyload(u32 seqno) static int __init selnl_init(void) { - selnl = netlink_kernel_create(NETLINK_SELINUX, SELNLGRP_MAX, NULL, NULL, - THIS_MODULE); + selnl = netlink_kernel_create(&init_net, NETLINK_SELINUX, + SELNLGRP_MAX, NULL, NULL, THIS_MODULE); if (selnl == NULL) panic("SELinux: Cannot create netlink socket."); netlink_set_nonroot(NETLINK_SELINUX, NL_NONROOT_RECV); -- cgit v1.2.3 From 881d966b48b035ab3f3aeaae0f3d3f9b584f45b2 Mon Sep 17 00:00:00 2001 From: "Eric W. Biederman" Date: Mon, 17 Sep 2007 11:56:21 -0700 Subject: [NET]: Make the device list and device lookups per namespace. This patch makes most of the generic device layer network namespace safe. This patch makes dev_base_head a network namespace variable, and then it picks up a few associated variables. The functions: dev_getbyhwaddr dev_getfirsthwbytype dev_get_by_flags dev_get_by_name __dev_get_by_name dev_get_by_index __dev_get_by_index dev_ioctl dev_ethtool dev_load wireless_process_ioctl were modified to take a network namespace argument, and deal with it. vlan_ioctl_set and brioctl_set were modified so their hooks will receive a network namespace argument. So basically anthing in the core of the network stack that was affected to by the change of dev_base was modified to handle multiple network namespaces. The rest of the network stack was simply modified to explicitly use &init_net the initial network namespace. This can be fixed when those components of the network stack are modified to handle multiple network namespaces. For now the ifindex generator is left global. Fundametally ifindex numbers are per namespace, or else we will have corner case problems with migration when we get that far. At the same time there are assumptions in the network stack that the ifindex of a network device won't change. Making the ifindex number global seems a good compromise until the network stack can cope with ifindex changes when you change namespaces, and the like. Signed-off-by: Eric W. Biederman Signed-off-by: David S. Miller --- arch/s390/appldata/appldata_net_sum.c | 3 +- arch/sparc64/solaris/ioctl.c | 3 +- drivers/atm/idt77252.c | 2 +- drivers/block/aoe/aoecmd.c | 3 +- drivers/infiniband/hw/cxgb3/cxio_hal.c | 3 +- drivers/net/bonding/bond_main.c | 2 +- drivers/net/bonding/bond_sysfs.c | 3 +- drivers/net/eql.c | 9 +- drivers/net/ifb.c | 3 +- drivers/net/macvlan.c | 2 +- drivers/net/pppoe.c | 4 +- drivers/net/shaper.c | 3 +- drivers/net/tun.c | 3 +- drivers/net/veth.c | 2 +- drivers/net/wan/dlci.c | 4 +- drivers/net/wan/sbni.c | 3 +- drivers/net/wireless/strip.c | 2 +- drivers/parisc/led.c | 2 +- fs/afs/netdevices.c | 5 +- include/linux/if_bridge.h | 2 +- include/linux/if_vlan.h | 2 +- include/linux/netdevice.h | 66 ++++---- include/net/net_namespace.h | 4 + include/net/pkt_cls.h | 3 +- include/net/rtnetlink.h | 2 +- include/net/wext.h | 15 +- net/802/tr.c | 2 +- net/8021q/vlan.c | 6 +- net/8021q/vlan_netlink.c | 3 +- net/8021q/vlanproc.c | 6 +- net/appletalk/ddp.c | 6 +- net/atm/mpc.c | 2 +- net/ax25/af_ax25.c | 2 +- net/bridge/br_if.c | 4 +- net/bridge/br_ioctl.c | 7 +- net/bridge/br_netlink.c | 5 +- net/bridge/br_private.h | 2 +- net/core/dev.c | 271 ++++++++++++++++++++++----------- net/core/dev_mcast.c | 41 ++++- net/core/ethtool.c | 4 +- net/core/fib_rules.c | 4 +- net/core/neighbour.c | 6 +- net/core/netpoll.c | 2 +- net/core/pktgen.c | 2 +- net/core/rtnetlink.c | 35 +++-- net/core/sock.c | 3 +- net/decnet/af_decnet.c | 2 +- net/decnet/dn_dev.c | 20 +-- net/decnet/dn_fib.c | 8 +- net/decnet/dn_route.c | 6 +- net/decnet/sysctl_net_decnet.c | 4 +- net/econet/af_econet.c | 2 +- net/ipv4/arp.c | 4 +- net/ipv4/devinet.c | 18 +-- net/ipv4/fib_frontend.c | 2 +- net/ipv4/fib_semantics.c | 4 +- net/ipv4/icmp.c | 2 +- net/ipv4/igmp.c | 4 +- net/ipv4/ip_fragment.c | 2 +- net/ipv4/ip_gre.c | 4 +- net/ipv4/ip_sockglue.c | 2 +- net/ipv4/ipconfig.c | 2 +- net/ipv4/ipip.c | 4 +- net/ipv4/ipmr.c | 4 +- net/ipv4/ipvs/ip_vs_sync.c | 10 +- net/ipv4/netfilter/ipt_CLUSTERIP.c | 2 +- net/ipv4/route.c | 4 +- net/ipv6/addrconf.c | 28 ++-- net/ipv6/af_inet6.c | 2 +- net/ipv6/anycast.c | 12 +- net/ipv6/datagram.c | 2 +- net/ipv6/ip6_tunnel.c | 6 +- net/ipv6/ipv6_sockglue.c | 2 +- net/ipv6/mcast.c | 12 +- net/ipv6/raw.c | 2 +- net/ipv6/reassembly.c | 2 +- net/ipv6/route.c | 4 +- net/ipv6/sit.c | 4 +- net/ipx/af_ipx.c | 6 +- net/irda/irnetlink.c | 9 +- net/llc/af_llc.c | 4 +- net/llc/llc_core.c | 3 +- net/mac80211/ieee80211.c | 1 + net/mac80211/ieee80211_cfg.c | 3 +- net/mac80211/tx.c | 9 +- net/mac80211/util.c | 7 +- net/netrom/nr_route.c | 6 +- net/packet/af_packet.c | 18 +-- net/rose/rose_route.c | 8 +- net/sched/act_mirred.c | 3 +- net/sched/cls_api.c | 4 +- net/sched/em_meta.c | 2 +- net/sched/sch_api.c | 10 +- net/sctp/ipv6.c | 4 +- net/sctp/protocol.c | 2 +- net/socket.c | 22 +-- net/tipc/eth_media.c | 2 +- net/wireless/wext.c | 38 +++-- net/x25/x25_route.c | 2 +- 99 files changed, 555 insertions(+), 362 deletions(-) (limited to 'include/linux') diff --git a/arch/s390/appldata/appldata_net_sum.c b/arch/s390/appldata/appldata_net_sum.c index 2180ac105b05..6c1815a47714 100644 --- a/arch/s390/appldata/appldata_net_sum.c +++ b/arch/s390/appldata/appldata_net_sum.c @@ -16,6 +16,7 @@ #include #include #include +#include #include "appldata.h" @@ -107,7 +108,7 @@ static void appldata_get_net_sum_data(void *data) tx_dropped = 0; collisions = 0; read_lock(&dev_base_lock); - for_each_netdev(dev) { + for_each_netdev(&init_net, dev) { stats = dev->get_stats(dev); rx_packets += stats->rx_packets; tx_packets += stats->tx_packets; diff --git a/arch/sparc64/solaris/ioctl.c b/arch/sparc64/solaris/ioctl.c index 18352a498628..8ad10a6d993b 100644 --- a/arch/sparc64/solaris/ioctl.c +++ b/arch/sparc64/solaris/ioctl.c @@ -28,6 +28,7 @@ #include #include +#include #include #include @@ -686,7 +687,7 @@ static inline int solaris_i(unsigned int fd, unsigned int cmd, u32 arg) int i = 0; read_lock_bh(&dev_base_lock); - for_each_netdev(d) + for_each_netdev(&init_net, d) i++; read_unlock_bh(&dev_base_lock); diff --git a/drivers/atm/idt77252.c b/drivers/atm/idt77252.c index f8b1700f4c16..eee54c0cde68 100644 --- a/drivers/atm/idt77252.c +++ b/drivers/atm/idt77252.c @@ -3576,7 +3576,7 @@ init_card(struct atm_dev *dev) * XXX: */ sprintf(tname, "eth%d", card->index); - tmp = dev_get_by_name(tname); /* jhs: was "tmp = dev_get(tname);" */ + tmp = dev_get_by_name(&init_net, tname); /* jhs: was "tmp = dev_get(tname);" */ if (tmp) { memcpy(card->atmdev->esi, tmp->dev_addr, 6); diff --git a/drivers/block/aoe/aoecmd.c b/drivers/block/aoe/aoecmd.c index 01fbdd38e3be..30394f78cac2 100644 --- a/drivers/block/aoe/aoecmd.c +++ b/drivers/block/aoe/aoecmd.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include "aoe.h" @@ -194,7 +195,7 @@ aoecmd_cfg_pkts(ushort aoemajor, unsigned char aoeminor, struct sk_buff **tail) sl = sl_tail = NULL; read_lock(&dev_base_lock); - for_each_netdev(ifp) { + for_each_netdev(&init_net, ifp) { dev_hold(ifp); if (!is_aoe_netif(ifp)) goto cont; diff --git a/drivers/infiniband/hw/cxgb3/cxio_hal.c b/drivers/infiniband/hw/cxgb3/cxio_hal.c index beb2a381467f..eec6a30840ca 100644 --- a/drivers/infiniband/hw/cxgb3/cxio_hal.c +++ b/drivers/infiniband/hw/cxgb3/cxio_hal.c @@ -37,6 +37,7 @@ #include #include #include +#include #include "cxio_resource.h" #include "cxio_hal.h" @@ -894,7 +895,7 @@ int cxio_rdev_open(struct cxio_rdev *rdev_p) if (cxio_hal_find_rdev_by_name(rdev_p->dev_name)) { return -EBUSY; } - netdev_p = dev_get_by_name(rdev_p->dev_name); + netdev_p = dev_get_by_name(&init_net, rdev_p->dev_name); if (!netdev_p) { return -EINVAL; } diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index cf97d8a6326e..559fe9437e0b 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -3719,7 +3719,7 @@ static int bond_do_ioctl(struct net_device *bond_dev, struct ifreq *ifr, int cmd } down_write(&(bonding_rwsem)); - slave_dev = dev_get_by_name(ifr->ifr_slave); + slave_dev = dev_get_by_name(&init_net, ifr->ifr_slave); dprintk("slave_dev=%p: \n", slave_dev); diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c index 60cccf2aa959..8289e27a360a 100644 --- a/drivers/net/bonding/bond_sysfs.c +++ b/drivers/net/bonding/bond_sysfs.c @@ -35,6 +35,7 @@ #include #include #include +#include /* #define BONDING_DEBUG 1 */ #include "bonding.h" @@ -299,7 +300,7 @@ static ssize_t bonding_store_slaves(struct device *d, read_unlock_bh(&bond->lock); printk(KERN_INFO DRV_NAME ": %s: Adding slave %s.\n", bond->dev->name, ifname); - dev = dev_get_by_name(ifname); + dev = dev_get_by_name(&init_net, ifname); if (!dev) { printk(KERN_INFO DRV_NAME ": %s: Interface %s does not exist!\n", diff --git a/drivers/net/eql.c b/drivers/net/eql.c index 102218c4a907..f1cc66dcbdfd 100644 --- a/drivers/net/eql.c +++ b/drivers/net/eql.c @@ -116,6 +116,7 @@ #include #include #include +#include #include #include @@ -412,7 +413,7 @@ static int eql_enslave(struct net_device *master_dev, slaving_request_t __user * if (copy_from_user(&srq, srqp, sizeof (slaving_request_t))) return -EFAULT; - slave_dev = dev_get_by_name(srq.slave_name); + slave_dev = dev_get_by_name(&init_net, srq.slave_name); if (slave_dev) { if ((master_dev->flags & IFF_UP) == IFF_UP) { /* slave is not a master & not already a slave: */ @@ -460,7 +461,7 @@ static int eql_emancipate(struct net_device *master_dev, slaving_request_t __use if (copy_from_user(&srq, srqp, sizeof (slaving_request_t))) return -EFAULT; - slave_dev = dev_get_by_name(srq.slave_name); + slave_dev = dev_get_by_name(&init_net, srq.slave_name); ret = -EINVAL; if (slave_dev) { spin_lock_bh(&eql->queue.lock); @@ -493,7 +494,7 @@ static int eql_g_slave_cfg(struct net_device *dev, slave_config_t __user *scp) if (copy_from_user(&sc, scp, sizeof (slave_config_t))) return -EFAULT; - slave_dev = dev_get_by_name(sc.slave_name); + slave_dev = dev_get_by_name(&init_net, sc.slave_name); if (!slave_dev) return -ENODEV; @@ -528,7 +529,7 @@ static int eql_s_slave_cfg(struct net_device *dev, slave_config_t __user *scp) if (copy_from_user(&sc, scp, sizeof (slave_config_t))) return -EFAULT; - slave_dev = dev_get_by_name(sc.slave_name); + slave_dev = dev_get_by_name(&init_net, sc.slave_name); if (!slave_dev) return -ENODEV; diff --git a/drivers/net/ifb.c b/drivers/net/ifb.c index f5c3598e59af..b06c6db4383a 100644 --- a/drivers/net/ifb.c +++ b/drivers/net/ifb.c @@ -34,6 +34,7 @@ #include #include #include +#include #define TX_TIMEOUT (2*HZ) @@ -97,7 +98,7 @@ static void ri_tasklet(unsigned long dev) stats->tx_packets++; stats->tx_bytes +=skb->len; - skb->dev = __dev_get_by_index(skb->iif); + skb->dev = __dev_get_by_index(&init_net, skb->iif); if (!skb->dev) { dev_kfree_skb(skb); stats->tx_dropped++; diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c index dc74d006e01f..2de073da182c 100644 --- a/drivers/net/macvlan.c +++ b/drivers/net/macvlan.c @@ -376,7 +376,7 @@ static int macvlan_newlink(struct net_device *dev, if (!tb[IFLA_LINK]) return -EINVAL; - lowerdev = __dev_get_by_index(nla_get_u32(tb[IFLA_LINK])); + lowerdev = __dev_get_by_index(dev->nd_net, nla_get_u32(tb[IFLA_LINK])); if (lowerdev == NULL) return -ENODEV; diff --git a/drivers/net/pppoe.c b/drivers/net/pppoe.c index c5c70e4b1d36..2f130e06b6dc 100644 --- a/drivers/net/pppoe.c +++ b/drivers/net/pppoe.c @@ -216,7 +216,7 @@ static inline struct pppox_sock *get_item_by_addr(struct sockaddr_pppox *sp) struct net_device *dev; int ifindex; - dev = dev_get_by_name(sp->sa_addr.pppoe.dev); + dev = dev_get_by_name(&init_net, sp->sa_addr.pppoe.dev); if(!dev) return NULL; ifindex = dev->ifindex; @@ -603,7 +603,7 @@ static int pppoe_connect(struct socket *sock, struct sockaddr *uservaddr, /* Don't re-bind if sid==0 */ if (sp->sa_addr.pppoe.sid != 0) { - dev = dev_get_by_name(sp->sa_addr.pppoe.dev); + dev = dev_get_by_name(&init_net, sp->sa_addr.pppoe.dev); error = -ENODEV; if (!dev) diff --git a/drivers/net/shaper.c b/drivers/net/shaper.c index 4c3d98ff4cd4..3773b3858bd4 100644 --- a/drivers/net/shaper.c +++ b/drivers/net/shaper.c @@ -86,6 +86,7 @@ #include #include +#include struct shaper_cb { unsigned long shapeclock; /* Time it should go out */ @@ -488,7 +489,7 @@ static int shaper_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) { case SHAPER_SET_DEV: { - struct net_device *them=__dev_get_by_name(ss->ss_name); + struct net_device *them=__dev_get_by_name(&init_net, ss->ss_name); if(them==NULL) return -ENODEV; if(sh->dev) diff --git a/drivers/net/tun.c b/drivers/net/tun.c index 62b2b3005019..691d264fbb6f 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c @@ -62,6 +62,7 @@ #include #include #include +#include #include #include @@ -475,7 +476,7 @@ static int tun_set_iff(struct file *file, struct ifreq *ifr) !capable(CAP_NET_ADMIN)) return -EPERM; } - else if (__dev_get_by_name(ifr->ifr_name)) + else if (__dev_get_by_name(&init_net, ifr->ifr_name)) return -EINVAL; else { char *name; diff --git a/drivers/net/veth.c b/drivers/net/veth.c index ca1c6893b809..2c86a4459d8a 100644 --- a/drivers/net/veth.c +++ b/drivers/net/veth.c @@ -345,7 +345,7 @@ static int veth_newlink(struct net_device *dev, else snprintf(ifname, IFNAMSIZ, DRV_NAME "%%d"); - peer = rtnl_create_link(ifname, &veth_link_ops, tbp); + peer = rtnl_create_link(dev->nd_net, ifname, &veth_link_ops, tbp); if (IS_ERR(peer)) return PTR_ERR(peer); diff --git a/drivers/net/wan/dlci.c b/drivers/net/wan/dlci.c index 61041d5186ac..bc12810157e0 100644 --- a/drivers/net/wan/dlci.c +++ b/drivers/net/wan/dlci.c @@ -361,7 +361,7 @@ static int dlci_add(struct dlci_add *dlci) /* validate slave device */ - slave = dev_get_by_name(dlci->devname); + slave = dev_get_by_name(&init_net, dlci->devname); if (!slave) return -ENODEV; @@ -427,7 +427,7 @@ static int dlci_del(struct dlci_add *dlci) int err; /* validate slave device */ - master = __dev_get_by_name(dlci->devname); + master = __dev_get_by_name(&init_net, dlci->devname); if (!master) return(-ENODEV); diff --git a/drivers/net/wan/sbni.c b/drivers/net/wan/sbni.c index 1cc18e787a65..8d7e01e8f56f 100644 --- a/drivers/net/wan/sbni.c +++ b/drivers/net/wan/sbni.c @@ -54,6 +54,7 @@ #include #include +#include #include #include @@ -1361,7 +1362,7 @@ sbni_ioctl( struct net_device *dev, struct ifreq *ifr, int cmd ) if (copy_from_user( slave_name, ifr->ifr_data, sizeof slave_name )) return -EFAULT; - slave_dev = dev_get_by_name( slave_name ); + slave_dev = dev_get_by_name(&init_net, slave_name ); if( !slave_dev || !(slave_dev->flags & IFF_UP) ) { printk( KERN_ERR "%s: trying to enslave non-active " "device %s\n", dev->name, slave_name ); diff --git a/drivers/net/wireless/strip.c b/drivers/net/wireless/strip.c index edb214e8c744..904e548e6795 100644 --- a/drivers/net/wireless/strip.c +++ b/drivers/net/wireless/strip.c @@ -1972,7 +1972,7 @@ static struct net_device *get_strip_dev(struct strip *strip_info) sizeof(zero_address))) { struct net_device *dev; read_lock_bh(&dev_base_lock); - for_each_netdev(dev) { + for_each_netdev(&init_net, dev) { if (dev->type == strip_info->dev->type && !memcmp(dev->dev_addr, &strip_info->true_dev_addr, diff --git a/drivers/parisc/led.c b/drivers/parisc/led.c index e5d7ed92d6f7..a6d6b2488ffc 100644 --- a/drivers/parisc/led.c +++ b/drivers/parisc/led.c @@ -359,7 +359,7 @@ static __inline__ int led_get_net_activity(void) * for reading should be OK */ read_lock(&dev_base_lock); rcu_read_lock(); - for_each_netdev(dev) { + for_each_netdev(&init_net, dev) { struct net_device_stats *stats; struct in_device *in_dev = __in_dev_get_rcu(dev); if (!in_dev || !in_dev->ifa_list) diff --git a/fs/afs/netdevices.c b/fs/afs/netdevices.c index fc27d4b52e5f..49f189423063 100644 --- a/fs/afs/netdevices.c +++ b/fs/afs/netdevices.c @@ -8,6 +8,7 @@ #include #include #include +#include #include "internal.h" /* @@ -23,7 +24,7 @@ int afs_get_MAC_address(u8 *mac, size_t maclen) BUG(); rtnl_lock(); - dev = __dev_getfirstbyhwtype(ARPHRD_ETHER); + dev = __dev_getfirstbyhwtype(&init_net, ARPHRD_ETHER); if (dev) { memcpy(mac, dev->dev_addr, maclen); ret = 0; @@ -47,7 +48,7 @@ int afs_get_ipv4_interfaces(struct afs_interface *bufs, size_t maxbufs, ASSERT(maxbufs > 0); rtnl_lock(); - for_each_netdev(dev) { + for_each_netdev(&init_net, dev) { if (dev->type == ARPHRD_LOOPBACK && !wantloopback) continue; idev = __in_dev_get_rtnl(dev); diff --git a/include/linux/if_bridge.h b/include/linux/if_bridge.h index 4ff211d98769..99e3a1a00099 100644 --- a/include/linux/if_bridge.h +++ b/include/linux/if_bridge.h @@ -104,7 +104,7 @@ struct __fdb_entry #include -extern void brioctl_set(int (*ioctl_hook)(unsigned int, void __user *)); +extern void brioctl_set(int (*ioctl_hook)(struct net *, unsigned int, void __user *)); extern struct sk_buff *(*br_handle_frame_hook)(struct net_bridge_port *p, struct sk_buff *skb); extern int (*br_should_route_hook)(struct sk_buff **pskb); diff --git a/include/linux/if_vlan.h b/include/linux/if_vlan.h index f8443fdb124a..976d4b1067d1 100644 --- a/include/linux/if_vlan.h +++ b/include/linux/if_vlan.h @@ -62,7 +62,7 @@ struct vlan_hdr { #define VLAN_VID_MASK 0xfff /* found in socket.c */ -extern void vlan_ioctl_set(int (*hook)(void __user *)); +extern void vlan_ioctl_set(int (*hook)(struct net *, void __user *)); #define VLAN_NAME "vlan" diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index dc3c15b726bc..7353b3e1f4fc 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -741,44 +741,48 @@ struct packet_type { #include extern struct net_device loopback_dev; /* The loopback */ -extern struct list_head dev_base_head; /* All devices */ extern rwlock_t dev_base_lock; /* Device list lock */ -#define for_each_netdev(d) \ - list_for_each_entry(d, &dev_base_head, dev_list) -#define for_each_netdev_safe(d, n) \ - list_for_each_entry_safe(d, n, &dev_base_head, dev_list) -#define for_each_netdev_continue(d) \ - list_for_each_entry_continue(d, &dev_base_head, dev_list) -#define net_device_entry(lh) list_entry(lh, struct net_device, dev_list) - -static inline struct net_device *next_net_device(struct net_device *dev) -{ - struct list_head *lh; - lh = dev->dev_list.next; - return lh == &dev_base_head ? NULL : net_device_entry(lh); -} +#define for_each_netdev(net, d) \ + list_for_each_entry(d, &(net)->dev_base_head, dev_list) +#define for_each_netdev_safe(net, d, n) \ + list_for_each_entry_safe(d, n, &(net)->dev_base_head, dev_list) +#define for_each_netdev_continue(net, d) \ + list_for_each_entry_continue(d, &(net)->dev_base_head, dev_list) +#define net_device_entry(lh) list_entry(lh, struct net_device, dev_list) -static inline struct net_device *first_net_device(void) -{ - return list_empty(&dev_base_head) ? NULL : - net_device_entry(dev_base_head.next); -} +#define next_net_device(d) \ +({ \ + struct net_device *dev = d; \ + struct list_head *lh; \ + struct net *net; \ + \ + net = dev->nd_net; \ + lh = dev->dev_list.next; \ + lh == &net->dev_base_head ? NULL : net_device_entry(lh); \ +}) + +#define first_net_device(N) \ +({ \ + struct net *NET = (N); \ + list_empty(&NET->dev_base_head) ? NULL : \ + net_device_entry(NET->dev_base_head.next); \ +}) extern int netdev_boot_setup_check(struct net_device *dev); extern unsigned long netdev_boot_base(const char *prefix, int unit); -extern struct net_device *dev_getbyhwaddr(unsigned short type, char *hwaddr); -extern struct net_device *dev_getfirstbyhwtype(unsigned short type); -extern struct net_device *__dev_getfirstbyhwtype(unsigned short type); +extern struct net_device *dev_getbyhwaddr(struct net *net, unsigned short type, char *hwaddr); +extern struct net_device *dev_getfirstbyhwtype(struct net *net, unsigned short type); +extern struct net_device *__dev_getfirstbyhwtype(struct net *net, unsigned short type); extern void dev_add_pack(struct packet_type *pt); extern void dev_remove_pack(struct packet_type *pt); extern void __dev_remove_pack(struct packet_type *pt); -extern struct net_device *dev_get_by_flags(unsigned short flags, +extern struct net_device *dev_get_by_flags(struct net *net, unsigned short flags, unsigned short mask); -extern struct net_device *dev_get_by_name(const char *name); -extern struct net_device *__dev_get_by_name(const char *name); +extern struct net_device *dev_get_by_name(struct net *net, const char *name); +extern struct net_device *__dev_get_by_name(struct net *net, const char *name); extern int dev_alloc_name(struct net_device *dev, const char *name); extern int dev_open(struct net_device *dev); extern int dev_close(struct net_device *dev); @@ -790,8 +794,8 @@ extern void synchronize_net(void); extern int register_netdevice_notifier(struct notifier_block *nb); extern int unregister_netdevice_notifier(struct notifier_block *nb); extern int call_netdevice_notifiers(unsigned long val, void *v); -extern struct net_device *dev_get_by_index(int ifindex); -extern struct net_device *__dev_get_by_index(int ifindex); +extern struct net_device *dev_get_by_index(struct net *net, int ifindex); +extern struct net_device *__dev_get_by_index(struct net *net, int ifindex); extern int dev_restart(struct net_device *dev); #ifdef CONFIG_NETPOLL_TRAP extern int netpoll_trap(void); @@ -1007,8 +1011,8 @@ extern int netif_rx_ni(struct sk_buff *skb); #define HAVE_NETIF_RECEIVE_SKB 1 extern int netif_receive_skb(struct sk_buff *skb); extern int dev_valid_name(const char *name); -extern int dev_ioctl(unsigned int cmd, void __user *); -extern int dev_ethtool(struct ifreq *); +extern int dev_ioctl(struct net *net, unsigned int cmd, void __user *); +extern int dev_ethtool(struct net *net, struct ifreq *); extern unsigned dev_get_flags(const struct net_device *); extern int dev_change_flags(struct net_device *, unsigned); extern int dev_change_name(struct net_device *, char *); @@ -1327,7 +1331,7 @@ extern void dev_set_allmulti(struct net_device *dev, int inc); extern void netdev_state_change(struct net_device *dev); extern void netdev_features_change(struct net_device *dev); /* Load a device via the kmod */ -extern void dev_load(const char *name); +extern void dev_load(struct net *net, const char *name); extern void dev_mcast_init(void); extern int netdev_max_backlog; extern int weight_p; diff --git a/include/net/net_namespace.h b/include/net/net_namespace.h index 547247681345..fac42db7f6d0 100644 --- a/include/net/net_namespace.h +++ b/include/net/net_namespace.h @@ -22,6 +22,10 @@ struct net { struct proc_dir_entry *proc_net; struct proc_dir_entry *proc_net_stat; struct proc_dir_entry *proc_net_root; + + struct list_head dev_base_head; + struct hlist_head *dev_name_head; + struct hlist_head *dev_index_head; }; extern struct net init_net; diff --git a/include/net/pkt_cls.h b/include/net/pkt_cls.h index 7968b1d66369..f285de69c615 100644 --- a/include/net/pkt_cls.h +++ b/include/net/pkt_cls.h @@ -2,6 +2,7 @@ #define __NET_PKT_CLS_H #include +#include #include #include @@ -351,7 +352,7 @@ tcf_match_indev(struct sk_buff *skb, char *indev) if (indev[0]) { if (!skb->iif) return 0; - dev = __dev_get_by_index(skb->iif); + dev = __dev_get_by_index(&init_net, skb->iif); if (!dev || strcmp(indev, dev->name)) return 0; } diff --git a/include/net/rtnetlink.h b/include/net/rtnetlink.h index 8218288ab7ee..793863e09c69 100644 --- a/include/net/rtnetlink.h +++ b/include/net/rtnetlink.h @@ -78,7 +78,7 @@ extern void __rtnl_link_unregister(struct rtnl_link_ops *ops); extern int rtnl_link_register(struct rtnl_link_ops *ops); extern void rtnl_link_unregister(struct rtnl_link_ops *ops); -extern struct net_device *rtnl_create_link(char *ifname, +extern struct net_device *rtnl_create_link(struct net *net, char *ifname, const struct rtnl_link_ops *ops, struct nlattr *tb[]); extern const struct nla_policy ifla_policy[IFLA_MAX+1]; diff --git a/include/net/wext.h b/include/net/wext.h index c02b8decf3af..80b31d826b7a 100644 --- a/include/net/wext.h +++ b/include/net/wext.h @@ -5,16 +5,23 @@ * wireless extensions interface to the core code */ +struct net; + #ifdef CONFIG_WIRELESS_EXT -extern int wext_proc_init(void); -extern int wext_handle_ioctl(struct ifreq *ifr, unsigned int cmd, +extern int wext_proc_init(struct net *net); +extern void wext_proc_exit(struct net *net); +extern int wext_handle_ioctl(struct net *net, struct ifreq *ifr, unsigned int cmd, void __user *arg); #else -static inline int wext_proc_init(void) +static inline int wext_proc_init(struct net *net) { return 0; } -static inline int wext_handle_ioctl(struct ifreq *ifr, unsigned int cmd, +static inline void wext_proc_exit(struct net *net) +{ + return; +} +static inline int wext_handle_ioctl(struct net *net, struct ifreq *ifr, unsigned int cmd, void __user *arg) { return -EINVAL; diff --git a/net/802/tr.c b/net/802/tr.c index 032c31e748eb..55c76d77d322 100644 --- a/net/802/tr.c +++ b/net/802/tr.c @@ -533,7 +533,7 @@ static int rif_seq_show(struct seq_file *seq, void *v) seq_puts(seq, "if TR address TTL rcf routing segments\n"); else { - struct net_device *dev = dev_get_by_index(entry->iface); + struct net_device *dev = dev_get_by_index(&init_net, entry->iface); long ttl = (long) (entry->last_used + sysctl_tr_rif_timeout) - (long) jiffies; diff --git a/net/8021q/vlan.c b/net/8021q/vlan.c index d0d36fdedbe9..a9ced0a6f4c0 100644 --- a/net/8021q/vlan.c +++ b/net/8021q/vlan.c @@ -51,7 +51,7 @@ static char vlan_copyright[] = "Ben Greear "; static char vlan_buggyright[] = "David S. Miller "; static int vlan_device_event(struct notifier_block *, unsigned long, void *); -static int vlan_ioctl_handler(void __user *); +static int vlan_ioctl_handler(struct net *net, void __user *); static int unregister_vlan_dev(struct net_device *, unsigned short ); static struct notifier_block vlan_notifier_block = { @@ -697,7 +697,7 @@ out: * o execute requested action or pass command to the device driver * arg is really a struct vlan_ioctl_args __user *. */ -static int vlan_ioctl_handler(void __user *arg) +static int vlan_ioctl_handler(struct net *net, void __user *arg) { int err; unsigned short vid = 0; @@ -726,7 +726,7 @@ static int vlan_ioctl_handler(void __user *arg) case GET_VLAN_REALDEV_NAME_CMD: case GET_VLAN_VID_CMD: err = -ENODEV; - dev = __dev_get_by_name(args.device1); + dev = __dev_get_by_name(&init_net, args.device1); if (!dev) goto out; diff --git a/net/8021q/vlan_netlink.c b/net/8021q/vlan_netlink.c index 6cdd1e015e2d..0996185e2ed5 100644 --- a/net/8021q/vlan_netlink.c +++ b/net/8021q/vlan_netlink.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include "vlan.h" @@ -112,7 +113,7 @@ static int vlan_newlink(struct net_device *dev, if (!tb[IFLA_LINK]) return -EINVAL; - real_dev = __dev_get_by_index(nla_get_u32(tb[IFLA_LINK])); + real_dev = __dev_get_by_index(&init_net, nla_get_u32(tb[IFLA_LINK])); if (!real_dev) return -ENODEV; diff --git a/net/8021q/vlanproc.c b/net/8021q/vlanproc.c index ac80e6b9ef53..6cefdf8e381a 100644 --- a/net/8021q/vlanproc.c +++ b/net/8021q/vlanproc.c @@ -254,7 +254,7 @@ static void *vlan_seq_start(struct seq_file *seq, loff_t *pos) if (*pos == 0) return SEQ_START_TOKEN; - for_each_netdev(dev) { + for_each_netdev(&init_net, dev) { if (!is_vlan_dev(dev)) continue; @@ -273,9 +273,9 @@ static void *vlan_seq_next(struct seq_file *seq, void *v, loff_t *pos) dev = (struct net_device *)v; if (v == SEQ_START_TOKEN) - dev = net_device_entry(&dev_base_head); + dev = net_device_entry(&init_net.dev_base_head); - for_each_netdev_continue(dev) { + for_each_netdev_continue(&init_net, dev) { if (!is_vlan_dev(dev)) continue; diff --git a/net/appletalk/ddp.c b/net/appletalk/ddp.c index 36fcdbf923c4..7c0b5151d526 100644 --- a/net/appletalk/ddp.c +++ b/net/appletalk/ddp.c @@ -677,7 +677,7 @@ static int atif_ioctl(int cmd, void __user *arg) if (copy_from_user(&atreq, arg, sizeof(atreq))) return -EFAULT; - dev = __dev_get_by_name(atreq.ifr_name); + dev = __dev_get_by_name(&init_net, atreq.ifr_name); if (!dev) return -ENODEV; @@ -901,7 +901,7 @@ static int atrtr_ioctl(unsigned int cmd, void __user *arg) if (copy_from_user(name, rt.rt_dev, IFNAMSIZ-1)) return -EFAULT; name[IFNAMSIZ-1] = '\0'; - dev = __dev_get_by_name(name); + dev = __dev_get_by_name(&init_net, name); if (!dev) return -ENODEV; } @@ -1273,7 +1273,7 @@ static __inline__ int is_ip_over_ddp(struct sk_buff *skb) static int handle_ip_over_ddp(struct sk_buff *skb) { - struct net_device *dev = __dev_get_by_name("ipddp0"); + struct net_device *dev = __dev_get_by_name(&init_net, "ipddp0"); struct net_device_stats *stats; /* This needs to be able to handle ipddp"N" devices */ diff --git a/net/atm/mpc.c b/net/atm/mpc.c index 0968430a7f58..2086396de177 100644 --- a/net/atm/mpc.c +++ b/net/atm/mpc.c @@ -244,7 +244,7 @@ static struct net_device *find_lec_by_itfnum(int itf) char name[IFNAMSIZ]; sprintf(name, "lec%d", itf); - dev = dev_get_by_name(name); + dev = dev_get_by_name(&init_net, name); return dev; } diff --git a/net/ax25/af_ax25.c b/net/ax25/af_ax25.c index 8d13a8bca0e0..993e5c75e909 100644 --- a/net/ax25/af_ax25.c +++ b/net/ax25/af_ax25.c @@ -631,7 +631,7 @@ static int ax25_setsockopt(struct socket *sock, int level, int optname, break; } - dev = dev_get_by_name(devname); + dev = dev_get_by_name(&init_net, devname); if (dev == NULL) { res = -ENODEV; break; diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c index 9272f12f664c..935784f736b3 100644 --- a/net/bridge/br_if.c +++ b/net/bridge/br_if.c @@ -303,7 +303,7 @@ int br_del_bridge(const char *name) int ret = 0; rtnl_lock(); - dev = __dev_get_by_name(name); + dev = __dev_get_by_name(&init_net, name); if (dev == NULL) ret = -ENXIO; /* Could not find device */ @@ -444,7 +444,7 @@ void __exit br_cleanup_bridges(void) struct net_device *dev, *nxt; rtnl_lock(); - for_each_netdev_safe(dev, nxt) + for_each_netdev_safe(&init_net, dev, nxt) if (dev->priv_flags & IFF_EBRIDGE) del_br(dev->priv); rtnl_unlock(); diff --git a/net/bridge/br_ioctl.c b/net/bridge/br_ioctl.c index bb15e9e259b1..0655a5f07f58 100644 --- a/net/bridge/br_ioctl.c +++ b/net/bridge/br_ioctl.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include "br_private.h" @@ -27,7 +28,7 @@ static int get_bridge_ifindices(int *indices, int num) struct net_device *dev; int i = 0; - for_each_netdev(dev) { + for_each_netdev(&init_net, dev) { if (i >= num) break; if (dev->priv_flags & IFF_EBRIDGE) @@ -90,7 +91,7 @@ static int add_del_if(struct net_bridge *br, int ifindex, int isadd) if (!capable(CAP_NET_ADMIN)) return -EPERM; - dev = dev_get_by_index(ifindex); + dev = dev_get_by_index(&init_net, ifindex); if (dev == NULL) return -EINVAL; @@ -364,7 +365,7 @@ static int old_deviceless(void __user *uarg) return -EOPNOTSUPP; } -int br_ioctl_deviceless_stub(unsigned int cmd, void __user *uarg) +int br_ioctl_deviceless_stub(struct net *net, unsigned int cmd, void __user *uarg) { switch (cmd) { case SIOCGIFBR: diff --git a/net/bridge/br_netlink.c b/net/bridge/br_netlink.c index 0fcf6f073064..53ab8e0cb518 100644 --- a/net/bridge/br_netlink.c +++ b/net/bridge/br_netlink.c @@ -12,6 +12,7 @@ #include #include +#include #include "br_private.h" static inline size_t br_nlmsg_size(void) @@ -110,7 +111,7 @@ static int br_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb) int idx; idx = 0; - for_each_netdev(dev) { + for_each_netdev(&init_net, dev) { /* not a bridge port */ if (dev->br_port == NULL || idx < cb->args[0]) goto skip; @@ -155,7 +156,7 @@ static int br_rtm_setlink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) if (new_state > BR_STATE_BLOCKING) return -EINVAL; - dev = __dev_get_by_index(ifm->ifi_index); + dev = __dev_get_by_index(&init_net, ifm->ifi_index); if (!dev) return -ENODEV; diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h index e6dc6f52990d..f666f7b28ff5 100644 --- a/net/bridge/br_private.h +++ b/net/bridge/br_private.h @@ -192,7 +192,7 @@ extern struct sk_buff *br_handle_frame(struct net_bridge_port *p, /* br_ioctl.c */ extern int br_dev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); -extern int br_ioctl_deviceless_stub(unsigned int cmd, void __user *arg); +extern int br_ioctl_deviceless_stub(struct net *net, unsigned int cmd, void __user *arg); /* br_netfilter.c */ #ifdef CONFIG_BRIDGE_NETFILTER diff --git a/net/core/dev.c b/net/core/dev.c index 40fd66fbe4e1..3a3d5ee73909 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -190,25 +190,22 @@ static struct net_dma net_dma = { * unregister_netdevice(), which must be called with the rtnl * semaphore held. */ -LIST_HEAD(dev_base_head); DEFINE_RWLOCK(dev_base_lock); -EXPORT_SYMBOL(dev_base_head); EXPORT_SYMBOL(dev_base_lock); #define NETDEV_HASHBITS 8 -static struct hlist_head dev_name_head[1<dev_name_head[hash & ((1 << NETDEV_HASHBITS) - 1)]; } -static inline struct hlist_head *dev_index_hash(int ifindex) +static inline struct hlist_head *dev_index_hash(struct net *net, int ifindex) { - return &dev_index_head[ifindex & ((1<dev_index_head[ifindex & ((1 << NETDEV_HASHBITS) - 1)]; } /* @@ -492,7 +489,7 @@ unsigned long netdev_boot_base(const char *prefix, int unit) * If device already registered then return base of 1 * to indicate not to probe for this interface */ - if (__dev_get_by_name(name)) + if (__dev_get_by_name(&init_net, name)) return 1; for (i = 0; i < NETDEV_BOOT_SETUP_MAX; i++) @@ -547,11 +544,11 @@ __setup("netdev=", netdev_boot_setup); * careful with locks. */ -struct net_device *__dev_get_by_name(const char *name) +struct net_device *__dev_get_by_name(struct net *net, const char *name) { struct hlist_node *p; - hlist_for_each(p, dev_name_hash(name)) { + hlist_for_each(p, dev_name_hash(net, name)) { struct net_device *dev = hlist_entry(p, struct net_device, name_hlist); if (!strncmp(dev->name, name, IFNAMSIZ)) @@ -571,12 +568,12 @@ struct net_device *__dev_get_by_name(const char *name) * matching device is found. */ -struct net_device *dev_get_by_name(const char *name) +struct net_device *dev_get_by_name(struct net *net, const char *name) { struct net_device *dev; read_lock(&dev_base_lock); - dev = __dev_get_by_name(name); + dev = __dev_get_by_name(net, name); if (dev) dev_hold(dev); read_unlock(&dev_base_lock); @@ -594,11 +591,11 @@ struct net_device *dev_get_by_name(const char *name) * or @dev_base_lock. */ -struct net_device *__dev_get_by_index(int ifindex) +struct net_device *__dev_get_by_index(struct net *net, int ifindex) { struct hlist_node *p; - hlist_for_each(p, dev_index_hash(ifindex)) { + hlist_for_each(p, dev_index_hash(net, ifindex)) { struct net_device *dev = hlist_entry(p, struct net_device, index_hlist); if (dev->ifindex == ifindex) @@ -618,12 +615,12 @@ struct net_device *__dev_get_by_index(int ifindex) * dev_put to indicate they have finished with it. */ -struct net_device *dev_get_by_index(int ifindex) +struct net_device *dev_get_by_index(struct net *net, int ifindex) { struct net_device *dev; read_lock(&dev_base_lock); - dev = __dev_get_by_index(ifindex); + dev = __dev_get_by_index(net, ifindex); if (dev) dev_hold(dev); read_unlock(&dev_base_lock); @@ -644,13 +641,13 @@ struct net_device *dev_get_by_index(int ifindex) * If the API was consistent this would be __dev_get_by_hwaddr */ -struct net_device *dev_getbyhwaddr(unsigned short type, char *ha) +struct net_device *dev_getbyhwaddr(struct net *net, unsigned short type, char *ha) { struct net_device *dev; ASSERT_RTNL(); - for_each_netdev(dev) + for_each_netdev(&init_net, dev) if (dev->type == type && !memcmp(dev->dev_addr, ha, dev->addr_len)) return dev; @@ -660,12 +657,12 @@ struct net_device *dev_getbyhwaddr(unsigned short type, char *ha) EXPORT_SYMBOL(dev_getbyhwaddr); -struct net_device *__dev_getfirstbyhwtype(unsigned short type) +struct net_device *__dev_getfirstbyhwtype(struct net *net, unsigned short type) { struct net_device *dev; ASSERT_RTNL(); - for_each_netdev(dev) + for_each_netdev(net, dev) if (dev->type == type) return dev; @@ -674,12 +671,12 @@ struct net_device *__dev_getfirstbyhwtype(unsigned short type) EXPORT_SYMBOL(__dev_getfirstbyhwtype); -struct net_device *dev_getfirstbyhwtype(unsigned short type) +struct net_device *dev_getfirstbyhwtype(struct net *net, unsigned short type) { struct net_device *dev; rtnl_lock(); - dev = __dev_getfirstbyhwtype(type); + dev = __dev_getfirstbyhwtype(net, type); if (dev) dev_hold(dev); rtnl_unlock(); @@ -699,13 +696,13 @@ EXPORT_SYMBOL(dev_getfirstbyhwtype); * dev_put to indicate they have finished with it. */ -struct net_device * dev_get_by_flags(unsigned short if_flags, unsigned short mask) +struct net_device * dev_get_by_flags(struct net *net, unsigned short if_flags, unsigned short mask) { struct net_device *dev, *ret; ret = NULL; read_lock(&dev_base_lock); - for_each_netdev(dev) { + for_each_netdev(net, dev) { if (((dev->flags ^ if_flags) & mask) == 0) { dev_hold(dev); ret = dev; @@ -763,6 +760,10 @@ int dev_alloc_name(struct net_device *dev, const char *name) const int max_netdevices = 8*PAGE_SIZE; long *inuse; struct net_device *d; + struct net *net; + + BUG_ON(!dev->nd_net); + net = dev->nd_net; p = strnchr(name, IFNAMSIZ-1, '%'); if (p) { @@ -779,7 +780,7 @@ int dev_alloc_name(struct net_device *dev, const char *name) if (!inuse) return -ENOMEM; - for_each_netdev(d) { + for_each_netdev(net, d) { if (!sscanf(d->name, name, &i)) continue; if (i < 0 || i >= max_netdevices) @@ -796,7 +797,7 @@ int dev_alloc_name(struct net_device *dev, const char *name) } snprintf(buf, sizeof(buf), name, i); - if (!__dev_get_by_name(buf)) { + if (!__dev_get_by_name(net, buf)) { strlcpy(dev->name, buf, IFNAMSIZ); return i; } @@ -822,9 +823,12 @@ int dev_change_name(struct net_device *dev, char *newname) char oldname[IFNAMSIZ]; int err = 0; int ret; + struct net *net; ASSERT_RTNL(); + BUG_ON(!dev->nd_net); + net = dev->nd_net; if (dev->flags & IFF_UP) return -EBUSY; @@ -839,7 +843,7 @@ int dev_change_name(struct net_device *dev, char *newname) return err; strcpy(newname, dev->name); } - else if (__dev_get_by_name(newname)) + else if (__dev_get_by_name(net, newname)) return -EEXIST; else strlcpy(dev->name, newname, IFNAMSIZ); @@ -849,7 +853,7 @@ rollback: write_lock_bh(&dev_base_lock); hlist_del(&dev->name_hlist); - hlist_add_head(&dev->name_hlist, dev_name_hash(dev->name)); + hlist_add_head(&dev->name_hlist, dev_name_hash(net, dev->name)); write_unlock_bh(&dev_base_lock); ret = raw_notifier_call_chain(&netdev_chain, NETDEV_CHANGENAME, dev); @@ -908,12 +912,12 @@ void netdev_state_change(struct net_device *dev) * available in this kernel then it becomes a nop. */ -void dev_load(const char *name) +void dev_load(struct net *net, const char *name) { struct net_device *dev; read_lock(&dev_base_lock); - dev = __dev_get_by_name(name); + dev = __dev_get_by_name(net, name); read_unlock(&dev_base_lock); if (!dev && capable(CAP_SYS_MODULE)) @@ -1052,6 +1056,8 @@ int dev_close(struct net_device *dev) } +static int dev_boot_phase = 1; + /* * Device change register/unregister. These are not inline or static * as we export them to the world. @@ -1075,23 +1081,27 @@ int register_netdevice_notifier(struct notifier_block *nb) { struct net_device *dev; struct net_device *last; + struct net *net; int err; rtnl_lock(); err = raw_notifier_chain_register(&netdev_chain, nb); if (err) goto unlock; + if (dev_boot_phase) + goto unlock; + for_each_net(net) { + for_each_netdev(net, dev) { + err = nb->notifier_call(nb, NETDEV_REGISTER, dev); + err = notifier_to_errno(err); + if (err) + goto rollback; + + if (!(dev->flags & IFF_UP)) + continue; - for_each_netdev(dev) { - err = nb->notifier_call(nb, NETDEV_REGISTER, dev); - err = notifier_to_errno(err); - if (err) - goto rollback; - - if (!(dev->flags & IFF_UP)) - continue; - - nb->notifier_call(nb, NETDEV_UP, dev); + nb->notifier_call(nb, NETDEV_UP, dev); + } } unlock: @@ -1100,15 +1110,17 @@ unlock: rollback: last = dev; - for_each_netdev(dev) { - if (dev == last) - break; + for_each_net(net) { + for_each_netdev(net, dev) { + if (dev == last) + break; - if (dev->flags & IFF_UP) { - nb->notifier_call(nb, NETDEV_GOING_DOWN, dev); - nb->notifier_call(nb, NETDEV_DOWN, dev); + if (dev->flags & IFF_UP) { + nb->notifier_call(nb, NETDEV_GOING_DOWN, dev); + nb->notifier_call(nb, NETDEV_DOWN, dev); + } + nb->notifier_call(nb, NETDEV_UNREGISTER, dev); } - nb->notifier_call(nb, NETDEV_UNREGISTER, dev); } goto unlock; } @@ -2187,7 +2199,7 @@ int register_gifconf(unsigned int family, gifconf_func_t * gifconf) * match. --pb */ -static int dev_ifname(struct ifreq __user *arg) +static int dev_ifname(struct net *net, struct ifreq __user *arg) { struct net_device *dev; struct ifreq ifr; @@ -2200,7 +2212,7 @@ static int dev_ifname(struct ifreq __user *arg) return -EFAULT; read_lock(&dev_base_lock); - dev = __dev_get_by_index(ifr.ifr_ifindex); + dev = __dev_get_by_index(net, ifr.ifr_ifindex); if (!dev) { read_unlock(&dev_base_lock); return -ENODEV; @@ -2220,7 +2232,7 @@ static int dev_ifname(struct ifreq __user *arg) * Thus we will need a 'compatibility mode'. */ -static int dev_ifconf(char __user *arg) +static int dev_ifconf(struct net *net, char __user *arg) { struct ifconf ifc; struct net_device *dev; @@ -2244,7 +2256,7 @@ static int dev_ifconf(char __user *arg) */ total = 0; - for_each_netdev(dev) { + for_each_netdev(net, dev) { for (i = 0; i < NPROTO; i++) { if (gifconf_list[i]) { int done; @@ -2278,6 +2290,7 @@ static int dev_ifconf(char __user *arg) */ void *dev_seq_start(struct seq_file *seq, loff_t *pos) { + struct net *net = seq->private; loff_t off; struct net_device *dev; @@ -2286,7 +2299,7 @@ void *dev_seq_start(struct seq_file *seq, loff_t *pos) return SEQ_START_TOKEN; off = 1; - for_each_netdev(dev) + for_each_netdev(net, dev) if (off++ == *pos) return dev; @@ -2295,9 +2308,10 @@ void *dev_seq_start(struct seq_file *seq, loff_t *pos) void *dev_seq_next(struct seq_file *seq, void *v, loff_t *pos) { + struct net *net = seq->private; ++*pos; return v == SEQ_START_TOKEN ? - first_net_device() : next_net_device((struct net_device *)v); + first_net_device(net) : next_net_device((struct net_device *)v); } void dev_seq_stop(struct seq_file *seq, void *v) @@ -2393,7 +2407,22 @@ static const struct seq_operations dev_seq_ops = { static int dev_seq_open(struct inode *inode, struct file *file) { - return seq_open(file, &dev_seq_ops); + struct seq_file *seq; + int res; + res = seq_open(file, &dev_seq_ops); + if (!res) { + seq = file->private_data; + seq->private = get_net(PROC_NET(inode)); + } + return res; +} + +static int dev_seq_release(struct inode *inode, struct file *file) +{ + struct seq_file *seq = file->private_data; + struct net *net = seq->private; + put_net(net); + return seq_release(inode, file); } static const struct file_operations dev_seq_fops = { @@ -2401,7 +2430,7 @@ static const struct file_operations dev_seq_fops = { .open = dev_seq_open, .read = seq_read, .llseek = seq_lseek, - .release = seq_release, + .release = dev_seq_release, }; static const struct seq_operations softnet_seq_ops = { @@ -2553,30 +2582,49 @@ static const struct file_operations ptype_seq_fops = { }; -static int __init dev_proc_init(void) +static int dev_proc_net_init(struct net *net) { int rc = -ENOMEM; - if (!proc_net_fops_create(&init_net, "dev", S_IRUGO, &dev_seq_fops)) + if (!proc_net_fops_create(net, "dev", S_IRUGO, &dev_seq_fops)) goto out; - if (!proc_net_fops_create(&init_net, "softnet_stat", S_IRUGO, &softnet_seq_fops)) + if (!proc_net_fops_create(net, "softnet_stat", S_IRUGO, &softnet_seq_fops)) goto out_dev; - if (!proc_net_fops_create(&init_net, "ptype", S_IRUGO, &ptype_seq_fops)) + if (!proc_net_fops_create(net, "ptype", S_IRUGO, &ptype_seq_fops)) goto out_softnet; - if (wext_proc_init()) + if (wext_proc_init(net)) goto out_ptype; rc = 0; out: return rc; out_ptype: - proc_net_remove(&init_net, "ptype"); + proc_net_remove(net, "ptype"); out_softnet: - proc_net_remove(&init_net, "softnet_stat"); + proc_net_remove(net, "softnet_stat"); out_dev: - proc_net_remove(&init_net, "dev"); + proc_net_remove(net, "dev"); goto out; } + +static void dev_proc_net_exit(struct net *net) +{ + wext_proc_exit(net); + + proc_net_remove(net, "ptype"); + proc_net_remove(net, "softnet_stat"); + proc_net_remove(net, "dev"); +} + +static struct pernet_operations dev_proc_ops = { + .init = dev_proc_net_init, + .exit = dev_proc_net_exit, +}; + +static int __init dev_proc_init(void) +{ + return register_pernet_subsys(&dev_proc_ops); +} #else #define dev_proc_init() 0 #endif /* CONFIG_PROC_FS */ @@ -3011,10 +3059,10 @@ int dev_set_mac_address(struct net_device *dev, struct sockaddr *sa) /* * Perform the SIOCxIFxxx calls. */ -static int dev_ifsioc(struct ifreq *ifr, unsigned int cmd) +static int dev_ifsioc(struct net *net, struct ifreq *ifr, unsigned int cmd) { int err; - struct net_device *dev = __dev_get_by_name(ifr->ifr_name); + struct net_device *dev = __dev_get_by_name(net, ifr->ifr_name); if (!dev) return -ENODEV; @@ -3167,7 +3215,7 @@ static int dev_ifsioc(struct ifreq *ifr, unsigned int cmd) * positive or a negative errno code on error. */ -int dev_ioctl(unsigned int cmd, void __user *arg) +int dev_ioctl(struct net *net, unsigned int cmd, void __user *arg) { struct ifreq ifr; int ret; @@ -3180,12 +3228,12 @@ int dev_ioctl(unsigned int cmd, void __user *arg) if (cmd == SIOCGIFCONF) { rtnl_lock(); - ret = dev_ifconf((char __user *) arg); + ret = dev_ifconf(net, (char __user *) arg); rtnl_unlock(); return ret; } if (cmd == SIOCGIFNAME) - return dev_ifname((struct ifreq __user *)arg); + return dev_ifname(net, (struct ifreq __user *)arg); if (copy_from_user(&ifr, arg, sizeof(struct ifreq))) return -EFAULT; @@ -3215,9 +3263,9 @@ int dev_ioctl(unsigned int cmd, void __user *arg) case SIOCGIFMAP: case SIOCGIFINDEX: case SIOCGIFTXQLEN: - dev_load(ifr.ifr_name); + dev_load(net, ifr.ifr_name); read_lock(&dev_base_lock); - ret = dev_ifsioc(&ifr, cmd); + ret = dev_ifsioc(net, &ifr, cmd); read_unlock(&dev_base_lock); if (!ret) { if (colon) @@ -3229,9 +3277,9 @@ int dev_ioctl(unsigned int cmd, void __user *arg) return ret; case SIOCETHTOOL: - dev_load(ifr.ifr_name); + dev_load(net, ifr.ifr_name); rtnl_lock(); - ret = dev_ethtool(&ifr); + ret = dev_ethtool(net, &ifr); rtnl_unlock(); if (!ret) { if (colon) @@ -3253,9 +3301,9 @@ int dev_ioctl(unsigned int cmd, void __user *arg) case SIOCSIFNAME: if (!capable(CAP_NET_ADMIN)) return -EPERM; - dev_load(ifr.ifr_name); + dev_load(net, ifr.ifr_name); rtnl_lock(); - ret = dev_ifsioc(&ifr, cmd); + ret = dev_ifsioc(net, &ifr, cmd); rtnl_unlock(); if (!ret) { if (colon) @@ -3294,9 +3342,9 @@ int dev_ioctl(unsigned int cmd, void __user *arg) /* fall through */ case SIOCBONDSLAVEINFOQUERY: case SIOCBONDINFOQUERY: - dev_load(ifr.ifr_name); + dev_load(net, ifr.ifr_name); rtnl_lock(); - ret = dev_ifsioc(&ifr, cmd); + ret = dev_ifsioc(net, &ifr, cmd); rtnl_unlock(); return ret; @@ -3316,9 +3364,9 @@ int dev_ioctl(unsigned int cmd, void __user *arg) if (cmd == SIOCWANDEV || (cmd >= SIOCDEVPRIVATE && cmd <= SIOCDEVPRIVATE + 15)) { - dev_load(ifr.ifr_name); + dev_load(net, ifr.ifr_name); rtnl_lock(); - ret = dev_ifsioc(&ifr, cmd); + ret = dev_ifsioc(net, &ifr, cmd); rtnl_unlock(); if (!ret && copy_to_user(arg, &ifr, sizeof(struct ifreq))) @@ -3327,7 +3375,7 @@ int dev_ioctl(unsigned int cmd, void __user *arg) } /* Take care of Wireless Extensions */ if (cmd >= SIOCIWFIRST && cmd <= SIOCIWLAST) - return wext_handle_ioctl(&ifr, cmd, arg); + return wext_handle_ioctl(net, &ifr, cmd, arg); return -EINVAL; } } @@ -3340,19 +3388,17 @@ int dev_ioctl(unsigned int cmd, void __user *arg) * number. The caller must hold the rtnl semaphore or the * dev_base_lock to be sure it remains unique. */ -static int dev_new_index(void) +static int dev_new_index(struct net *net) { static int ifindex; for (;;) { if (++ifindex <= 0) ifindex = 1; - if (!__dev_get_by_index(ifindex)) + if (!__dev_get_by_index(net, ifindex)) return ifindex; } } -static int dev_boot_phase = 1; - /* Delayed registration/unregisteration */ static DEFINE_SPINLOCK(net_todo_list_lock); static struct list_head net_todo_list = LIST_HEAD_INIT(net_todo_list); @@ -3386,6 +3432,7 @@ int register_netdevice(struct net_device *dev) struct hlist_head *head; struct hlist_node *p; int ret; + struct net *net; BUG_ON(dev_boot_phase); ASSERT_RTNL(); @@ -3394,6 +3441,8 @@ int register_netdevice(struct net_device *dev) /* When net_device's are persistent, this will be fatal. */ BUG_ON(dev->reg_state != NETREG_UNINITIALIZED); + BUG_ON(!dev->nd_net); + net = dev->nd_net; spin_lock_init(&dev->queue_lock); spin_lock_init(&dev->_xmit_lock); @@ -3418,12 +3467,12 @@ int register_netdevice(struct net_device *dev) goto err_uninit; } - dev->ifindex = dev_new_index(); + dev->ifindex = dev_new_index(net); if (dev->iflink == -1) dev->iflink = dev->ifindex; /* Check for existence of name */ - head = dev_name_hash(dev->name); + head = dev_name_hash(net, dev->name); hlist_for_each(p, head) { struct net_device *d = hlist_entry(p, struct net_device, name_hlist); @@ -3501,9 +3550,9 @@ int register_netdevice(struct net_device *dev) dev_init_scheduler(dev); write_lock_bh(&dev_base_lock); - list_add_tail(&dev->dev_list, &dev_base_head); + list_add_tail(&dev->dev_list, &net->dev_base_head); hlist_add_head(&dev->name_hlist, head); - hlist_add_head(&dev->index_hlist, dev_index_hash(dev->ifindex)); + hlist_add_head(&dev->index_hlist, dev_index_hash(net, dev->ifindex)); dev_hold(dev); write_unlock_bh(&dev_base_lock); @@ -4067,6 +4116,45 @@ int netdev_compute_features(unsigned long all, unsigned long one) } EXPORT_SYMBOL(netdev_compute_features); +/* Initialize per network namespace state */ +static int netdev_init(struct net *net) +{ + int i; + INIT_LIST_HEAD(&net->dev_base_head); + rwlock_init(&dev_base_lock); + + net->dev_name_head = kmalloc( + sizeof(*net->dev_name_head)*NETDEV_HASHENTRIES, GFP_KERNEL); + if (!net->dev_name_head) + return -ENOMEM; + + net->dev_index_head = kmalloc( + sizeof(*net->dev_index_head)*NETDEV_HASHENTRIES, GFP_KERNEL); + if (!net->dev_index_head) { + kfree(net->dev_name_head); + return -ENOMEM; + } + + for (i = 0; i < NETDEV_HASHENTRIES; i++) + INIT_HLIST_HEAD(&net->dev_name_head[i]); + + for (i = 0; i < NETDEV_HASHENTRIES; i++) + INIT_HLIST_HEAD(&net->dev_index_head[i]); + + return 0; +} + +static void netdev_exit(struct net *net) +{ + kfree(net->dev_name_head); + kfree(net->dev_index_head); +} + +static struct pernet_operations netdev_net_ops = { + .init = netdev_init, + .exit = netdev_exit, +}; + /* * Initialize the DEV module. At boot time this walks the device list and * unhooks any devices that fail to initialise (normally hardware not @@ -4094,11 +4182,8 @@ static int __init net_dev_init(void) for (i = 0; i < 16; i++) INIT_LIST_HEAD(&ptype_base[i]); - for (i = 0; i < ARRAY_SIZE(dev_name_head); i++) - INIT_HLIST_HEAD(&dev_name_head[i]); - - for (i = 0; i < ARRAY_SIZE(dev_index_head); i++) - INIT_HLIST_HEAD(&dev_index_head[i]); + if (register_pernet_subsys(&netdev_net_ops)) + goto out; /* * Initialise the packet receive queues. diff --git a/net/core/dev_mcast.c b/net/core/dev_mcast.c index 8e069fc207cb..1c4f6198459b 100644 --- a/net/core/dev_mcast.c +++ b/net/core/dev_mcast.c @@ -187,11 +187,12 @@ EXPORT_SYMBOL(dev_mc_unsync); #ifdef CONFIG_PROC_FS static void *dev_mc_seq_start(struct seq_file *seq, loff_t *pos) { + struct net *net = seq->private; struct net_device *dev; loff_t off = 0; read_lock(&dev_base_lock); - for_each_netdev(dev) { + for_each_netdev(net, dev) { if (off++ == *pos) return dev; } @@ -240,7 +241,22 @@ static const struct seq_operations dev_mc_seq_ops = { static int dev_mc_seq_open(struct inode *inode, struct file *file) { - return seq_open(file, &dev_mc_seq_ops); + struct seq_file *seq; + int res; + res = seq_open(file, &dev_mc_seq_ops); + if (!res) { + seq = file->private_data; + seq->private = get_net(PROC_NET(inode)); + } + return res; +} + +static int dev_mc_seq_release(struct inode *inode, struct file *file) +{ + struct seq_file *seq = file->private_data; + struct net *net = seq->private; + put_net(net); + return seq_release(inode, file); } static const struct file_operations dev_mc_seq_fops = { @@ -248,14 +264,31 @@ static const struct file_operations dev_mc_seq_fops = { .open = dev_mc_seq_open, .read = seq_read, .llseek = seq_lseek, - .release = seq_release, + .release = dev_mc_seq_release, }; #endif +static int dev_mc_net_init(struct net *net) +{ + if (!proc_net_fops_create(net, "dev_mcast", 0, &dev_mc_seq_fops)) + return -ENOMEM; + return 0; +} + +static void dev_mc_net_exit(struct net *net) +{ + proc_net_remove(net, "dev_mcast"); +} + +static struct pernet_operations dev_mc_net_ops = { + .init = dev_mc_net_init, + .exit = dev_mc_net_exit, +}; + void __init dev_mcast_init(void) { - proc_net_fops_create(&init_net, "dev_mcast", 0, &dev_mc_seq_fops); + register_pernet_subsys(&dev_mc_net_ops); } EXPORT_SYMBOL(dev_mc_add); diff --git a/net/core/ethtool.c b/net/core/ethtool.c index 7c43f032a7f9..0d0b13cc1dd3 100644 --- a/net/core/ethtool.c +++ b/net/core/ethtool.c @@ -779,9 +779,9 @@ static int ethtool_set_value(struct net_device *dev, char __user *useraddr, /* The main entry point in this file. Called from net/core/dev.c */ -int dev_ethtool(struct ifreq *ifr) +int dev_ethtool(struct net *net, struct ifreq *ifr) { - struct net_device *dev = __dev_get_by_name(ifr->ifr_name); + struct net_device *dev = __dev_get_by_name(net, ifr->ifr_name); void __user *useraddr = ifr->ifr_data; u32 ethcmd; int rc; diff --git a/net/core/fib_rules.c b/net/core/fib_rules.c index 9eabe1ae01dc..1ba71baf87ef 100644 --- a/net/core/fib_rules.c +++ b/net/core/fib_rules.c @@ -12,6 +12,7 @@ #include #include #include +#include #include static LIST_HEAD(rules_ops); @@ -198,6 +199,7 @@ errout: static int fib_nl_newrule(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg) { + struct net *net = skb->sk->sk_net; struct fib_rule_hdr *frh = nlmsg_data(nlh); struct fib_rules_ops *ops = NULL; struct fib_rule *rule, *r, *last = NULL; @@ -235,7 +237,7 @@ static int fib_nl_newrule(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg) rule->ifindex = -1; nla_strlcpy(rule->ifname, tb[FRA_IFNAME], IFNAMSIZ); - dev = __dev_get_by_name(rule->ifname); + dev = __dev_get_by_name(net, rule->ifname); if (dev) rule->ifindex = dev->ifindex; } diff --git a/net/core/neighbour.c b/net/core/neighbour.c index 5f25f4f79b8c..2c6577c1eedd 100644 --- a/net/core/neighbour.c +++ b/net/core/neighbour.c @@ -1441,6 +1441,7 @@ int neigh_table_clear(struct neigh_table *tbl) static int neigh_delete(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) { + struct net *net = skb->sk->sk_net; struct ndmsg *ndm; struct nlattr *dst_attr; struct neigh_table *tbl; @@ -1456,7 +1457,7 @@ static int neigh_delete(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) ndm = nlmsg_data(nlh); if (ndm->ndm_ifindex) { - dev = dev_get_by_index(ndm->ndm_ifindex); + dev = dev_get_by_index(net, ndm->ndm_ifindex); if (dev == NULL) { err = -ENODEV; goto out; @@ -1506,6 +1507,7 @@ out: static int neigh_add(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) { + struct net *net = skb->sk->sk_net; struct ndmsg *ndm; struct nlattr *tb[NDA_MAX+1]; struct neigh_table *tbl; @@ -1522,7 +1524,7 @@ static int neigh_add(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) ndm = nlmsg_data(nlh); if (ndm->ndm_ifindex) { - dev = dev_get_by_index(ndm->ndm_ifindex); + dev = dev_get_by_index(net, ndm->ndm_ifindex); if (dev == NULL) { err = -ENODEV; goto out; diff --git a/net/core/netpoll.c b/net/core/netpoll.c index 0952f936b292..bb7523a5b408 100644 --- a/net/core/netpoll.c +++ b/net/core/netpoll.c @@ -653,7 +653,7 @@ int netpoll_setup(struct netpoll *np) int err; if (np->dev_name) - ndev = dev_get_by_name(np->dev_name); + ndev = dev_get_by_name(&init_net, np->dev_name); if (!ndev) { printk(KERN_ERR "%s: %s doesn't exist, aborting.\n", np->name, np->dev_name); diff --git a/net/core/pktgen.c b/net/core/pktgen.c index d7c30ce095a1..94e42be16daa 100644 --- a/net/core/pktgen.c +++ b/net/core/pktgen.c @@ -2008,7 +2008,7 @@ static int pktgen_setup_dev(struct pktgen_dev *pkt_dev, const char *ifname) pkt_dev->odev = NULL; } - odev = dev_get_by_name(ifname); + odev = dev_get_by_name(&init_net, ifname); if (!odev) { printk(KERN_ERR "pktgen: no such netdevice: \"%s\"\n", ifname); return -ENODEV; diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index 416768d1e0cd..44f91bb1ae8d 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c @@ -306,10 +306,13 @@ EXPORT_SYMBOL_GPL(rtnl_link_register); void __rtnl_link_unregister(struct rtnl_link_ops *ops) { struct net_device *dev, *n; + struct net *net; - for_each_netdev_safe(dev, n) { - if (dev->rtnl_link_ops == ops) - ops->dellink(dev); + for_each_net(net) { + for_each_netdev_safe(net, dev, n) { + if (dev->rtnl_link_ops == ops) + ops->dellink(dev); + } } list_del(&ops->list); } @@ -693,12 +696,13 @@ nla_put_failure: static int rtnl_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb) { + struct net *net = skb->sk->sk_net; int idx; int s_idx = cb->args[0]; struct net_device *dev; idx = 0; - for_each_netdev(dev) { + for_each_netdev(net, dev) { if (idx < s_idx) goto cont; if (rtnl_fill_ifinfo(skb, dev, RTM_NEWLINK, @@ -858,6 +862,7 @@ errout: static int rtnl_setlink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) { + struct net *net = skb->sk->sk_net; struct ifinfomsg *ifm; struct net_device *dev; int err; @@ -876,9 +881,9 @@ static int rtnl_setlink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) err = -EINVAL; ifm = nlmsg_data(nlh); if (ifm->ifi_index > 0) - dev = dev_get_by_index(ifm->ifi_index); + dev = dev_get_by_index(net, ifm->ifi_index); else if (tb[IFLA_IFNAME]) - dev = dev_get_by_name(ifname); + dev = dev_get_by_name(net, ifname); else goto errout; @@ -904,6 +909,7 @@ errout: static int rtnl_dellink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) { + struct net *net = skb->sk->sk_net; const struct rtnl_link_ops *ops; struct net_device *dev; struct ifinfomsg *ifm; @@ -920,9 +926,9 @@ static int rtnl_dellink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) ifm = nlmsg_data(nlh); if (ifm->ifi_index > 0) - dev = __dev_get_by_index(ifm->ifi_index); + dev = __dev_get_by_index(net, ifm->ifi_index); else if (tb[IFLA_IFNAME]) - dev = __dev_get_by_name(ifname); + dev = __dev_get_by_name(net, ifname); else return -EINVAL; @@ -937,7 +943,7 @@ static int rtnl_dellink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) return 0; } -struct net_device *rtnl_create_link(char *ifname, +struct net_device *rtnl_create_link(struct net *net, char *ifname, const struct rtnl_link_ops *ops, struct nlattr *tb[]) { int err; @@ -954,6 +960,7 @@ struct net_device *rtnl_create_link(char *ifname, goto err_free; } + dev->nd_net = net; dev->rtnl_link_ops = ops; if (tb[IFLA_MTU]) @@ -981,6 +988,7 @@ err: static int rtnl_newlink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) { + struct net *net = skb->sk->sk_net; const struct rtnl_link_ops *ops; struct net_device *dev; struct ifinfomsg *ifm; @@ -1004,9 +1012,9 @@ replay: ifm = nlmsg_data(nlh); if (ifm->ifi_index > 0) - dev = __dev_get_by_index(ifm->ifi_index); + dev = __dev_get_by_index(net, ifm->ifi_index); else if (ifname[0]) - dev = __dev_get_by_name(ifname); + dev = __dev_get_by_name(net, ifname); else dev = NULL; @@ -1092,7 +1100,7 @@ replay: if (!ifname[0]) snprintf(ifname, IFNAMSIZ, "%s%%d", ops->kind); - dev = rtnl_create_link(ifname, ops, tb); + dev = rtnl_create_link(net, ifname, ops, tb); if (IS_ERR(dev)) err = PTR_ERR(dev); @@ -1109,6 +1117,7 @@ replay: static int rtnl_getlink(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg) { + struct net *net = skb->sk->sk_net; struct ifinfomsg *ifm; struct nlattr *tb[IFLA_MAX+1]; struct net_device *dev = NULL; @@ -1121,7 +1130,7 @@ static int rtnl_getlink(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg) ifm = nlmsg_data(nlh); if (ifm->ifi_index > 0) { - dev = dev_get_by_index(ifm->ifi_index); + dev = dev_get_by_index(net, ifm->ifi_index); if (dev == NULL) return -ENODEV; } else diff --git a/net/core/sock.c b/net/core/sock.c index a31455dc7024..4ed9b507c1e7 100644 --- a/net/core/sock.c +++ b/net/core/sock.c @@ -367,6 +367,7 @@ static int sock_bindtodevice(struct sock *sk, char __user *optval, int optlen) { int ret = -ENOPROTOOPT; #ifdef CONFIG_NETDEVICES + struct net *net = sk->sk_net; char devname[IFNAMSIZ]; int index; @@ -395,7 +396,7 @@ static int sock_bindtodevice(struct sock *sk, char __user *optval, int optlen) if (devname[0] == '\0') { index = 0; } else { - struct net_device *dev = dev_get_by_name(devname); + struct net_device *dev = dev_get_by_name(net, devname); ret = -ENODEV; if (!dev) diff --git a/net/decnet/af_decnet.c b/net/decnet/af_decnet.c index 83398da5d763..aabe98d9402f 100644 --- a/net/decnet/af_decnet.c +++ b/net/decnet/af_decnet.c @@ -751,7 +751,7 @@ static int dn_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) if (dn_ntohs(saddr->sdn_nodeaddrl)) { read_lock(&dev_base_lock); ldev = NULL; - for_each_netdev(dev) { + for_each_netdev(&init_net, dev) { if (!dev->dn_ptr) continue; if (dn_dev_islocal(dev, dn_saddr2dn(saddr))) { diff --git a/net/decnet/dn_dev.c b/net/decnet/dn_dev.c index 83cb0761336a..ddfd2aff44d8 100644 --- a/net/decnet/dn_dev.c +++ b/net/decnet/dn_dev.c @@ -513,7 +513,7 @@ int dn_dev_ioctl(unsigned int cmd, void __user *arg) ifr->ifr_name[IFNAMSIZ-1] = 0; #ifdef CONFIG_KMOD - dev_load(ifr->ifr_name); + dev_load(&init_net, ifr->ifr_name); #endif switch(cmd) { @@ -531,7 +531,7 @@ int dn_dev_ioctl(unsigned int cmd, void __user *arg) rtnl_lock(); - if ((dev = __dev_get_by_name(ifr->ifr_name)) == NULL) { + if ((dev = __dev_get_by_name(&init_net, ifr->ifr_name)) == NULL) { ret = -ENODEV; goto done; } @@ -629,7 +629,7 @@ static struct dn_dev *dn_dev_by_index(int ifindex) { struct net_device *dev; struct dn_dev *dn_dev = NULL; - dev = dev_get_by_index(ifindex); + dev = dev_get_by_index(&init_net, ifindex); if (dev) { dn_dev = dev->dn_ptr; dev_put(dev); @@ -694,7 +694,7 @@ static int dn_nl_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) return -EINVAL; ifm = nlmsg_data(nlh); - if ((dev = __dev_get_by_index(ifm->ifa_index)) == NULL) + if ((dev = __dev_get_by_index(&init_net, ifm->ifa_index)) == NULL) return -ENODEV; if ((dn_db = dev->dn_ptr) == NULL) { @@ -800,7 +800,7 @@ static int dn_nl_dump_ifaddr(struct sk_buff *skb, struct netlink_callback *cb) skip_naddr = cb->args[1]; idx = 0; - for_each_netdev(dev) { + for_each_netdev(&init_net, dev) { if (idx < skip_ndevs) goto cont; else if (idx > skip_ndevs) { @@ -1297,7 +1297,7 @@ void dn_dev_devices_off(void) struct net_device *dev; rtnl_lock(); - for_each_netdev(dev) + for_each_netdev(&init_net, dev) dn_dev_down(dev); rtnl_unlock(); @@ -1308,7 +1308,7 @@ void dn_dev_devices_on(void) struct net_device *dev; rtnl_lock(); - for_each_netdev(dev) { + for_each_netdev(&init_net, dev) { if (dev->flags & IFF_UP) dn_dev_up(dev); } @@ -1342,7 +1342,7 @@ static void *dn_dev_seq_start(struct seq_file *seq, loff_t *pos) return SEQ_START_TOKEN; i = 1; - for_each_netdev(dev) { + for_each_netdev(&init_net, dev) { if (!is_dn_dev(dev)) continue; @@ -1361,9 +1361,9 @@ static void *dn_dev_seq_next(struct seq_file *seq, void *v, loff_t *pos) dev = (struct net_device *)v; if (v == SEQ_START_TOKEN) - dev = net_device_entry(&dev_base_head); + dev = net_device_entry(&init_net.dev_base_head); - for_each_netdev_continue(dev) { + for_each_netdev_continue(&init_net, dev) { if (!is_dn_dev(dev)) continue; diff --git a/net/decnet/dn_fib.c b/net/decnet/dn_fib.c index d2bc19d47950..3760a20d10d0 100644 --- a/net/decnet/dn_fib.c +++ b/net/decnet/dn_fib.c @@ -212,7 +212,7 @@ static int dn_fib_check_nh(const struct rtmsg *r, struct dn_fib_info *fi, struct return -EINVAL; if (dnet_addr_type(nh->nh_gw) != RTN_UNICAST) return -EINVAL; - if ((dev = __dev_get_by_index(nh->nh_oif)) == NULL) + if ((dev = __dev_get_by_index(&init_net, nh->nh_oif)) == NULL) return -ENODEV; if (!(dev->flags&IFF_UP)) return -ENETDOWN; @@ -255,7 +255,7 @@ out: if (nh->nh_flags&(RTNH_F_PERVASIVE|RTNH_F_ONLINK)) return -EINVAL; - dev = __dev_get_by_index(nh->nh_oif); + dev = __dev_get_by_index(&init_net, nh->nh_oif); if (dev == NULL || dev->dn_ptr == NULL) return -ENODEV; if (!(dev->flags&IFF_UP)) @@ -355,7 +355,7 @@ struct dn_fib_info *dn_fib_create_info(const struct rtmsg *r, struct dn_kern_rta if (nhs != 1 || nh->nh_gw) goto err_inval; nh->nh_scope = RT_SCOPE_NOWHERE; - nh->nh_dev = dev_get_by_index(fi->fib_nh->nh_oif); + nh->nh_dev = dev_get_by_index(&init_net, fi->fib_nh->nh_oif); err = -ENODEV; if (nh->nh_dev == NULL) goto failure; @@ -602,7 +602,7 @@ static void dn_fib_del_ifaddr(struct dn_ifaddr *ifa) /* Scan device list */ read_lock(&dev_base_lock); - for_each_netdev(dev) { + for_each_netdev(&init_net, dev) { dn_db = dev->dn_ptr; if (dn_db == NULL) continue; diff --git a/net/decnet/dn_route.c b/net/decnet/dn_route.c index 580e786d0c38..70b1c3fa00f3 100644 --- a/net/decnet/dn_route.c +++ b/net/decnet/dn_route.c @@ -908,7 +908,7 @@ static int dn_route_output_slow(struct dst_entry **pprt, const struct flowi *old /* If we have an output interface, verify its a DECnet device */ if (oldflp->oif) { - dev_out = dev_get_by_index(oldflp->oif); + dev_out = dev_get_by_index(&init_net, oldflp->oif); err = -ENODEV; if (dev_out && dev_out->dn_ptr == NULL) { dev_put(dev_out); @@ -929,7 +929,7 @@ static int dn_route_output_slow(struct dst_entry **pprt, const struct flowi *old goto out; } read_lock(&dev_base_lock); - for_each_netdev(dev) { + for_each_netdev(&init_net, dev) { if (!dev->dn_ptr) continue; if (!dn_dev_islocal(dev, oldflp->fld_src)) @@ -1556,7 +1556,7 @@ static int dn_cache_getroute(struct sk_buff *in_skb, struct nlmsghdr *nlh, void if (fl.iif) { struct net_device *dev; - if ((dev = dev_get_by_index(fl.iif)) == NULL) { + if ((dev = dev_get_by_index(&init_net, fl.iif)) == NULL) { kfree_skb(skb); return -ENODEV; } diff --git a/net/decnet/sysctl_net_decnet.c b/net/decnet/sysctl_net_decnet.c index 52e40d7eb22d..ae354a43fb97 100644 --- a/net/decnet/sysctl_net_decnet.c +++ b/net/decnet/sysctl_net_decnet.c @@ -259,7 +259,7 @@ static int dn_def_dev_strategy(ctl_table *table, int __user *name, int nlen, devname[newlen] = 0; - dev = dev_get_by_name(devname); + dev = dev_get_by_name(&init_net, devname); if (dev == NULL) return -ENODEV; @@ -299,7 +299,7 @@ static int dn_def_dev_handler(ctl_table *table, int write, devname[*lenp] = 0; strip_it(devname); - dev = dev_get_by_name(devname); + dev = dev_get_by_name(&init_net, devname); if (dev == NULL) return -ENODEV; diff --git a/net/econet/af_econet.c b/net/econet/af_econet.c index f877f3b5c725..9938e76a8ff6 100644 --- a/net/econet/af_econet.c +++ b/net/econet/af_econet.c @@ -662,7 +662,7 @@ static int ec_dev_ioctl(struct socket *sock, unsigned int cmd, void __user *arg) if (copy_from_user(&ifr, arg, sizeof(struct ifreq))) return -EFAULT; - if ((dev = dev_get_by_name(ifr.ifr_name)) == NULL) + if ((dev = dev_get_by_name(&init_net, ifr.ifr_name)) == NULL) return -ENODEV; sec = (struct sockaddr_ec *)&ifr.ifr_addr; diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c index a11e7a5c1da4..3a683006d761 100644 --- a/net/ipv4/arp.c +++ b/net/ipv4/arp.c @@ -981,7 +981,7 @@ static int arp_req_set(struct arpreq *r, struct net_device * dev) if (mask && mask != htonl(0xFFFFFFFF)) return -EINVAL; if (!dev && (r->arp_flags & ATF_COM)) { - dev = dev_getbyhwaddr(r->arp_ha.sa_family, r->arp_ha.sa_data); + dev = dev_getbyhwaddr(&init_net, r->arp_ha.sa_family, r->arp_ha.sa_data); if (!dev) return -ENODEV; } @@ -1169,7 +1169,7 @@ int arp_ioctl(unsigned int cmd, void __user *arg) rtnl_lock(); if (r.arp_dev[0]) { err = -ENODEV; - if ((dev = __dev_get_by_name(r.arp_dev)) == NULL) + if ((dev = __dev_get_by_name(&init_net, r.arp_dev)) == NULL) goto out; /* Mmmm... It is wrong... ARPHRD_NETROM==0 */ diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c index c5eb1a29a5cf..721b89b60963 100644 --- a/net/ipv4/devinet.c +++ b/net/ipv4/devinet.c @@ -420,7 +420,7 @@ struct in_device *inetdev_by_index(int ifindex) struct net_device *dev; struct in_device *in_dev = NULL; read_lock(&dev_base_lock); - dev = __dev_get_by_index(ifindex); + dev = __dev_get_by_index(&init_net, ifindex); if (dev) in_dev = in_dev_get(dev); read_unlock(&dev_base_lock); @@ -506,7 +506,7 @@ static struct in_ifaddr *rtm_to_ifaddr(struct nlmsghdr *nlh) goto errout; } - dev = __dev_get_by_index(ifm->ifa_index); + dev = __dev_get_by_index(&init_net, ifm->ifa_index); if (dev == NULL) { err = -ENODEV; goto errout; @@ -628,7 +628,7 @@ int devinet_ioctl(unsigned int cmd, void __user *arg) *colon = 0; #ifdef CONFIG_KMOD - dev_load(ifr.ifr_name); + dev_load(&init_net, ifr.ifr_name); #endif switch (cmd) { @@ -669,7 +669,7 @@ int devinet_ioctl(unsigned int cmd, void __user *arg) rtnl_lock(); ret = -ENODEV; - if ((dev = __dev_get_by_name(ifr.ifr_name)) == NULL) + if ((dev = __dev_get_by_name(&init_net, ifr.ifr_name)) == NULL) goto done; if (colon) @@ -909,7 +909,7 @@ no_in_dev: */ read_lock(&dev_base_lock); rcu_read_lock(); - for_each_netdev(dev) { + for_each_netdev(&init_net, dev) { if ((in_dev = __in_dev_get_rcu(dev)) == NULL) continue; @@ -988,7 +988,7 @@ __be32 inet_confirm_addr(const struct net_device *dev, __be32 dst, __be32 local, read_lock(&dev_base_lock); rcu_read_lock(); - for_each_netdev(dev) { + for_each_netdev(&init_net, dev) { if ((in_dev = __in_dev_get_rcu(dev))) { addr = confirm_addr_indev(in_dev, dst, local, scope); if (addr) @@ -1185,7 +1185,7 @@ static int inet_dump_ifaddr(struct sk_buff *skb, struct netlink_callback *cb) s_ip_idx = ip_idx = cb->args[1]; idx = 0; - for_each_netdev(dev) { + for_each_netdev(&init_net, dev) { if (idx < s_idx) goto cont; if (idx > s_idx) @@ -1244,7 +1244,7 @@ static void devinet_copy_dflt_conf(int i) struct net_device *dev; read_lock(&dev_base_lock); - for_each_netdev(dev) { + for_each_netdev(&init_net, dev) { struct in_device *in_dev; rcu_read_lock(); in_dev = __in_dev_get_rcu(dev); @@ -1333,7 +1333,7 @@ void inet_forward_change(void) IPV4_DEVCONF_DFLT(FORWARDING) = on; read_lock(&dev_base_lock); - for_each_netdev(dev) { + for_each_netdev(&init_net, dev) { struct in_device *in_dev; rcu_read_lock(); in_dev = __in_dev_get_rcu(dev); diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c index 140bf7a8d877..df17aab193b4 100644 --- a/net/ipv4/fib_frontend.c +++ b/net/ipv4/fib_frontend.c @@ -334,7 +334,7 @@ static int rtentry_to_fib_config(int cmd, struct rtentry *rt, colon = strchr(devname, ':'); if (colon) *colon = 0; - dev = __dev_get_by_name(devname); + dev = __dev_get_by_name(&init_net, devname); if (!dev) return -ENODEV; cfg->fc_oif = dev->ifindex; diff --git a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c index c434119deb52..d30fb68d5f4e 100644 --- a/net/ipv4/fib_semantics.c +++ b/net/ipv4/fib_semantics.c @@ -533,7 +533,7 @@ static int fib_check_nh(struct fib_config *cfg, struct fib_info *fi, return -EINVAL; if (inet_addr_type(nh->nh_gw) != RTN_UNICAST) return -EINVAL; - if ((dev = __dev_get_by_index(nh->nh_oif)) == NULL) + if ((dev = __dev_get_by_index(&init_net, nh->nh_oif)) == NULL) return -ENODEV; if (!(dev->flags&IFF_UP)) return -ENETDOWN; @@ -799,7 +799,7 @@ struct fib_info *fib_create_info(struct fib_config *cfg) if (nhs != 1 || nh->nh_gw) goto err_inval; nh->nh_scope = RT_SCOPE_NOWHERE; - nh->nh_dev = dev_get_by_index(fi->fib_nh->nh_oif); + nh->nh_dev = dev_get_by_index(&init_net, fi->fib_nh->nh_oif); err = -ENODEV; if (nh->nh_dev == NULL) goto failure; diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c index 02a899bec196..68a22670f597 100644 --- a/net/ipv4/icmp.c +++ b/net/ipv4/icmp.c @@ -517,7 +517,7 @@ void icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info) struct net_device *dev = NULL; if (rt->fl.iif && sysctl_icmp_errors_use_inbound_ifaddr) - dev = dev_get_by_index(rt->fl.iif); + dev = dev_get_by_index(&init_net, rt->fl.iif); if (dev) { saddr = inet_select_addr(dev, 0, RT_SCOPE_LINK); diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c index d78599a9dbd5..ad500a43b359 100644 --- a/net/ipv4/igmp.c +++ b/net/ipv4/igmp.c @@ -2292,7 +2292,7 @@ static inline struct ip_mc_list *igmp_mc_get_first(struct seq_file *seq) struct igmp_mc_iter_state *state = igmp_mc_seq_private(seq); state->in_dev = NULL; - for_each_netdev(state->dev) { + for_each_netdev(&init_net, state->dev) { struct in_device *in_dev; in_dev = in_dev_get(state->dev); if (!in_dev) @@ -2454,7 +2454,7 @@ static inline struct ip_sf_list *igmp_mcf_get_first(struct seq_file *seq) state->idev = NULL; state->im = NULL; - for_each_netdev(state->dev) { + for_each_netdev(&init_net, state->dev) { struct in_device *idev; idev = in_dev_get(state->dev); if (unlikely(idev == NULL)) diff --git a/net/ipv4/ip_fragment.c b/net/ipv4/ip_fragment.c index 0231bdcb2ab7..fabb86db763b 100644 --- a/net/ipv4/ip_fragment.c +++ b/net/ipv4/ip_fragment.c @@ -292,7 +292,7 @@ static void ip_expire(unsigned long arg) if ((qp->last_in&FIRST_IN) && qp->fragments != NULL) { struct sk_buff *head = qp->fragments; /* Send an ICMP "Fragment Reassembly Timeout" message. */ - if ((head->dev = dev_get_by_index(qp->iif)) != NULL) { + if ((head->dev = dev_get_by_index(&init_net, qp->iif)) != NULL) { icmp_send(head, ICMP_TIME_EXCEEDED, ICMP_EXC_FRAGTIME, 0); dev_put(head->dev); } diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c index 5c14ed63e56c..3106225c5e50 100644 --- a/net/ipv4/ip_gre.c +++ b/net/ipv4/ip_gre.c @@ -262,7 +262,7 @@ static struct ip_tunnel * ipgre_tunnel_locate(struct ip_tunnel_parm *parms, int int i; for (i=1; i<100; i++) { sprintf(name, "gre%d", i); - if (__dev_get_by_name(name) == NULL) + if (__dev_get_by_name(&init_net, name) == NULL) break; } if (i==100) @@ -1196,7 +1196,7 @@ static int ipgre_tunnel_init(struct net_device *dev) } if (!tdev && tunnel->parms.link) - tdev = __dev_get_by_index(tunnel->parms.link); + tdev = __dev_get_by_index(&init_net, tunnel->parms.link); if (tdev) { hlen = tdev->hard_header_len; diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c index 6b420aedcdcf..b2b3053dfef7 100644 --- a/net/ipv4/ip_sockglue.c +++ b/net/ipv4/ip_sockglue.c @@ -602,7 +602,7 @@ static int do_ip_setsockopt(struct sock *sk, int level, dev_put(dev); } } else - dev = __dev_get_by_index(mreq.imr_ifindex); + dev = __dev_get_by_index(&init_net, mreq.imr_ifindex); err = -EADDRNOTAVAIL; diff --git a/net/ipv4/ipconfig.c b/net/ipv4/ipconfig.c index 08ff623371f0..4303851749f6 100644 --- a/net/ipv4/ipconfig.c +++ b/net/ipv4/ipconfig.c @@ -193,7 +193,7 @@ static int __init ic_open_devs(void) if (dev_change_flags(&loopback_dev, loopback_dev.flags | IFF_UP) < 0) printk(KERN_ERR "IP-Config: Failed to open %s\n", loopback_dev.name); - for_each_netdev(dev) { + for_each_netdev(&init_net, dev) { if (dev == &loopback_dev) continue; if (user_dev_name[0] ? !strcmp(dev->name, user_dev_name) : diff --git a/net/ipv4/ipip.c b/net/ipv4/ipip.c index 396437242a1b..652bd86e33a3 100644 --- a/net/ipv4/ipip.c +++ b/net/ipv4/ipip.c @@ -225,7 +225,7 @@ static struct ip_tunnel * ipip_tunnel_locate(struct ip_tunnel_parm *parms, int c int i; for (i=1; i<100; i++) { sprintf(name, "tunl%d", i); - if (__dev_get_by_name(name) == NULL) + if (__dev_get_by_name(&init_net, name) == NULL) break; } if (i==100) @@ -822,7 +822,7 @@ static int ipip_tunnel_init(struct net_device *dev) } if (!tdev && tunnel->parms.link) - tdev = __dev_get_by_index(tunnel->parms.link); + tdev = __dev_get_by_index(&init_net, tunnel->parms.link); if (tdev) { dev->hard_header_len = tdev->hard_header_len + sizeof(struct iphdr); diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c index 036598835c63..b8b4b497fb57 100644 --- a/net/ipv4/ipmr.c +++ b/net/ipv4/ipmr.c @@ -125,7 +125,7 @@ struct net_device *ipmr_new_tunnel(struct vifctl *v) { struct net_device *dev; - dev = __dev_get_by_name("tunl0"); + dev = __dev_get_by_name(&init_net, "tunl0"); if (dev) { int err; @@ -149,7 +149,7 @@ struct net_device *ipmr_new_tunnel(struct vifctl *v) dev = NULL; - if (err == 0 && (dev = __dev_get_by_name(p.name)) != NULL) { + if (err == 0 && (dev = __dev_get_by_name(&init_net, p.name)) != NULL) { dev->flags |= IFF_MULTICAST; in_dev = __in_dev_get_rtnl(dev); diff --git a/net/ipv4/ipvs/ip_vs_sync.c b/net/ipv4/ipvs/ip_vs_sync.c index 356f067484e3..1960747f354c 100644 --- a/net/ipv4/ipvs/ip_vs_sync.c +++ b/net/ipv4/ipvs/ip_vs_sync.c @@ -387,7 +387,7 @@ static int set_mcast_if(struct sock *sk, char *ifname) struct net_device *dev; struct inet_sock *inet = inet_sk(sk); - if ((dev = __dev_get_by_name(ifname)) == NULL) + if ((dev = __dev_get_by_name(&init_net, ifname)) == NULL) return -ENODEV; if (sk->sk_bound_dev_if && dev->ifindex != sk->sk_bound_dev_if) @@ -412,7 +412,7 @@ static int set_sync_mesg_maxlen(int sync_state) int num; if (sync_state == IP_VS_STATE_MASTER) { - if ((dev = __dev_get_by_name(ip_vs_master_mcast_ifn)) == NULL) + if ((dev = __dev_get_by_name(&init_net, ip_vs_master_mcast_ifn)) == NULL) return -ENODEV; num = (dev->mtu - sizeof(struct iphdr) - @@ -423,7 +423,7 @@ static int set_sync_mesg_maxlen(int sync_state) IP_VS_DBG(7, "setting the maximum length of sync sending " "message %d.\n", sync_send_mesg_maxlen); } else if (sync_state == IP_VS_STATE_BACKUP) { - if ((dev = __dev_get_by_name(ip_vs_backup_mcast_ifn)) == NULL) + if ((dev = __dev_get_by_name(&init_net, ip_vs_backup_mcast_ifn)) == NULL) return -ENODEV; sync_recv_mesg_maxlen = dev->mtu - @@ -451,7 +451,7 @@ join_mcast_group(struct sock *sk, struct in_addr *addr, char *ifname) memset(&mreq, 0, sizeof(mreq)); memcpy(&mreq.imr_multiaddr, addr, sizeof(struct in_addr)); - if ((dev = __dev_get_by_name(ifname)) == NULL) + if ((dev = __dev_get_by_name(&init_net, ifname)) == NULL) return -ENODEV; if (sk->sk_bound_dev_if && dev->ifindex != sk->sk_bound_dev_if) return -EINVAL; @@ -472,7 +472,7 @@ static int bind_mcastif_addr(struct socket *sock, char *ifname) __be32 addr; struct sockaddr_in sin; - if ((dev = __dev_get_by_name(ifname)) == NULL) + if ((dev = __dev_get_by_name(&init_net, ifname)) == NULL) return -ENODEV; addr = inet_select_addr(dev, 0, RT_SCOPE_UNIVERSE); diff --git a/net/ipv4/netfilter/ipt_CLUSTERIP.c b/net/ipv4/netfilter/ipt_CLUSTERIP.c index 50fc9e009fe4..27f14e1ebd8b 100644 --- a/net/ipv4/netfilter/ipt_CLUSTERIP.c +++ b/net/ipv4/netfilter/ipt_CLUSTERIP.c @@ -401,7 +401,7 @@ checkentry(const char *tablename, return false; } - dev = dev_get_by_name(e->ip.iniface); + dev = dev_get_by_name(&init_net, e->ip.iniface); if (!dev) { printk(KERN_WARNING "CLUSTERIP: no such interface %s\n", e->ip.iniface); return false; diff --git a/net/ipv4/route.c b/net/ipv4/route.c index efd2a9202d68..396c631166a4 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -2213,7 +2213,7 @@ static int ip_route_output_slow(struct rtable **rp, const struct flowi *oldflp) if (oldflp->oif) { - dev_out = dev_get_by_index(oldflp->oif); + dev_out = dev_get_by_index(&init_net, oldflp->oif); err = -ENODEV; if (dev_out == NULL) goto out; @@ -2592,7 +2592,7 @@ static int inet_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr* nlh, void if (iif) { struct net_device *dev; - dev = __dev_get_by_index(iif); + dev = __dev_get_by_index(&init_net, iif); if (dev == NULL) { err = -ENODEV; goto errout_free; diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 1a6783646520..ee55be975407 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -450,7 +450,7 @@ static void addrconf_forward_change(void) struct inet6_dev *idev; read_lock(&dev_base_lock); - for_each_netdev(dev) { + for_each_netdev(&init_net, dev) { rcu_read_lock(); idev = __in6_dev_get(dev); if (idev) { @@ -912,7 +912,7 @@ int ipv6_dev_get_saddr(struct net_device *daddr_dev, read_lock(&dev_base_lock); rcu_read_lock(); - for_each_netdev(dev) { + for_each_netdev(&init_net, dev) { struct inet6_dev *idev; struct inet6_ifaddr *ifa; @@ -1858,7 +1858,7 @@ int addrconf_set_dstaddr(void __user *arg) if (copy_from_user(&ireq, arg, sizeof(struct in6_ifreq))) goto err_exit; - dev = __dev_get_by_index(ireq.ifr6_ifindex); + dev = __dev_get_by_index(&init_net, ireq.ifr6_ifindex); err = -ENODEV; if (dev == NULL) @@ -1889,7 +1889,7 @@ int addrconf_set_dstaddr(void __user *arg) if (err == 0) { err = -ENOBUFS; - if ((dev = __dev_get_by_name(p.name)) == NULL) + if ((dev = __dev_get_by_name(&init_net, p.name)) == NULL) goto err_exit; err = dev_open(dev); } @@ -1919,7 +1919,7 @@ static int inet6_addr_add(int ifindex, struct in6_addr *pfx, int plen, if (!valid_lft || prefered_lft > valid_lft) return -EINVAL; - if ((dev = __dev_get_by_index(ifindex)) == NULL) + if ((dev = __dev_get_by_index(&init_net, ifindex)) == NULL) return -ENODEV; if ((idev = addrconf_add_dev(dev)) == NULL) @@ -1970,7 +1970,7 @@ static int inet6_addr_del(int ifindex, struct in6_addr *pfx, int plen) struct inet6_dev *idev; struct net_device *dev; - if ((dev = __dev_get_by_index(ifindex)) == NULL) + if ((dev = __dev_get_by_index(&init_net, ifindex)) == NULL) return -ENODEV; if ((idev = __in6_dev_get(dev)) == NULL) @@ -2065,7 +2065,7 @@ static void sit_add_v4_addrs(struct inet6_dev *idev) return; } - for_each_netdev(dev) { + for_each_netdev(&init_net, dev) { struct in_device * in_dev = __in_dev_get_rtnl(dev); if (in_dev && (dev->flags & IFF_UP)) { struct in_ifaddr * ifa; @@ -2221,12 +2221,12 @@ static void ip6_tnl_add_linklocal(struct inet6_dev *idev) /* first try to inherit the link-local address from the link device */ if (idev->dev->iflink && - (link_dev = __dev_get_by_index(idev->dev->iflink))) { + (link_dev = __dev_get_by_index(&init_net, idev->dev->iflink))) { if (!ipv6_inherit_linklocal(idev, link_dev)) return; } /* then try to inherit it from any device */ - for_each_netdev(link_dev) { + for_each_netdev(&init_net, link_dev) { if (!ipv6_inherit_linklocal(idev, link_dev)) return; } @@ -3084,7 +3084,7 @@ inet6_rtm_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) valid_lft = INFINITY_LIFE_TIME; } - dev = __dev_get_by_index(ifm->ifa_index); + dev = __dev_get_by_index(&init_net, ifm->ifa_index); if (dev == NULL) return -ENODEV; @@ -3268,7 +3268,7 @@ static int inet6_dump_addr(struct sk_buff *skb, struct netlink_callback *cb, s_ip_idx = ip_idx = cb->args[1]; idx = 0; - for_each_netdev(dev) { + for_each_netdev(&init_net, dev) { if (idx < s_idx) goto cont; if (idx > s_idx) @@ -3377,7 +3377,7 @@ static int inet6_rtm_getaddr(struct sk_buff *in_skb, struct nlmsghdr* nlh, ifm = nlmsg_data(nlh); if (ifm->ifa_index) - dev = __dev_get_by_index(ifm->ifa_index); + dev = __dev_get_by_index(&init_net, ifm->ifa_index); if ((ifa = ipv6_get_ifaddr(addr, dev, 1)) == NULL) { err = -EADDRNOTAVAIL; @@ -3589,7 +3589,7 @@ static int inet6_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb) read_lock(&dev_base_lock); idx = 0; - for_each_netdev(dev) { + for_each_netdev(&init_net, dev) { if (idx < s_idx) goto cont; if ((idev = in6_dev_get(dev)) == NULL) @@ -4266,7 +4266,7 @@ void __exit addrconf_cleanup(void) * clean dev list. */ - for_each_netdev(dev) { + for_each_netdev(&init_net, dev) { if (__in6_dev_get(dev) == NULL) continue; addrconf_ifdown(dev, 1); diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c index 21931c86e95b..e5c5aad44bb1 100644 --- a/net/ipv6/af_inet6.c +++ b/net/ipv6/af_inet6.c @@ -302,7 +302,7 @@ int inet6_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) err = -EINVAL; goto out; } - dev = dev_get_by_index(sk->sk_bound_dev_if); + dev = dev_get_by_index(&init_net, sk->sk_bound_dev_if); if (!dev) { err = -ENODEV; goto out; diff --git a/net/ipv6/anycast.c b/net/ipv6/anycast.c index 0bd665498d06..d407992c1481 100644 --- a/net/ipv6/anycast.c +++ b/net/ipv6/anycast.c @@ -112,10 +112,10 @@ int ipv6_sock_ac_join(struct sock *sk, int ifindex, struct in6_addr *addr) } else { /* router, no matching interface: just pick one */ - dev = dev_get_by_flags(IFF_UP, IFF_UP|IFF_LOOPBACK); + dev = dev_get_by_flags(&init_net, IFF_UP, IFF_UP|IFF_LOOPBACK); } } else - dev = dev_get_by_index(ifindex); + dev = dev_get_by_index(&init_net, ifindex); if (dev == NULL) { err = -ENODEV; @@ -196,7 +196,7 @@ int ipv6_sock_ac_drop(struct sock *sk, int ifindex, struct in6_addr *addr) write_unlock_bh(&ipv6_sk_ac_lock); - dev = dev_get_by_index(pac->acl_ifindex); + dev = dev_get_by_index(&init_net, pac->acl_ifindex); if (dev) { ipv6_dev_ac_dec(dev, &pac->acl_addr); dev_put(dev); @@ -224,7 +224,7 @@ void ipv6_sock_ac_close(struct sock *sk) if (pac->acl_ifindex != prev_index) { if (dev) dev_put(dev); - dev = dev_get_by_index(pac->acl_ifindex); + dev = dev_get_by_index(&init_net, pac->acl_ifindex); prev_index = pac->acl_ifindex; } if (dev) @@ -429,7 +429,7 @@ int ipv6_chk_acast_addr(struct net_device *dev, struct in6_addr *addr) if (dev) return ipv6_chk_acast_dev(dev, addr); read_lock(&dev_base_lock); - for_each_netdev(dev) + for_each_netdev(&init_net, dev) if (ipv6_chk_acast_dev(dev, addr)) { found = 1; break; @@ -453,7 +453,7 @@ static inline struct ifacaddr6 *ac6_get_first(struct seq_file *seq) struct ac6_iter_state *state = ac6_seq_private(seq); state->idev = NULL; - for_each_netdev(state->dev) { + for_each_netdev(&init_net, state->dev) { struct inet6_dev *idev; idev = in6_dev_get(state->dev); if (!idev) diff --git a/net/ipv6/datagram.c b/net/ipv6/datagram.c index fe0f49024a0a..2ed689ac449e 100644 --- a/net/ipv6/datagram.c +++ b/net/ipv6/datagram.c @@ -544,7 +544,7 @@ int datagram_send_ctl(struct msghdr *msg, struct flowi *fl, if (!src_info->ipi6_ifindex) return -EINVAL; else { - dev = dev_get_by_index(src_info->ipi6_ifindex); + dev = dev_get_by_index(&init_net, src_info->ipi6_ifindex); if (!dev) return -ENODEV; } diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c index ca774d8e3be3..937625e577c1 100644 --- a/net/ipv6/ip6_tunnel.c +++ b/net/ipv6/ip6_tunnel.c @@ -235,7 +235,7 @@ static struct ip6_tnl *ip6_tnl_create(struct ip6_tnl_parm *p) int i; for (i = 1; i < IP6_TNL_MAX; i++) { sprintf(name, "ip6tnl%d", i); - if (__dev_get_by_name(name) == NULL) + if (__dev_get_by_name(&init_net, name) == NULL) break; } if (i == IP6_TNL_MAX) @@ -650,7 +650,7 @@ static inline int ip6_tnl_rcv_ctl(struct ip6_tnl *t) struct net_device *ldev = NULL; if (p->link) - ldev = dev_get_by_index(p->link); + ldev = dev_get_by_index(&init_net, p->link); if ((ipv6_addr_is_multicast(&p->laddr) || likely(ipv6_chk_addr(&p->laddr, ldev, 0))) && @@ -786,7 +786,7 @@ static inline int ip6_tnl_xmit_ctl(struct ip6_tnl *t) struct net_device *ldev = NULL; if (p->link) - ldev = dev_get_by_index(p->link); + ldev = dev_get_by_index(&init_net, p->link); if (unlikely(!ipv6_chk_addr(&p->laddr, ldev, 0))) printk(KERN_WARNING diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c index 74254fccbcc8..eb330a44bacd 100644 --- a/net/ipv6/ipv6_sockglue.c +++ b/net/ipv6/ipv6_sockglue.c @@ -542,7 +542,7 @@ done: if (sk->sk_bound_dev_if && sk->sk_bound_dev_if != val) goto e_inval; - if (__dev_get_by_index(val) == NULL) { + if (__dev_get_by_index(&init_net, val) == NULL) { retv = -ENODEV; break; } diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c index a41d5a0b50cc..e2ab43c989d4 100644 --- a/net/ipv6/mcast.c +++ b/net/ipv6/mcast.c @@ -215,7 +215,7 @@ int ipv6_sock_mc_join(struct sock *sk, int ifindex, struct in6_addr *addr) dst_release(&rt->u.dst); } } else - dev = dev_get_by_index(ifindex); + dev = dev_get_by_index(&init_net, ifindex); if (dev == NULL) { sock_kfree_s(sk, mc_lst, sizeof(*mc_lst)); @@ -266,7 +266,7 @@ int ipv6_sock_mc_drop(struct sock *sk, int ifindex, struct in6_addr *addr) *lnk = mc_lst->next; write_unlock_bh(&ipv6_sk_mc_lock); - if ((dev = dev_get_by_index(mc_lst->ifindex)) != NULL) { + if ((dev = dev_get_by_index(&init_net, mc_lst->ifindex)) != NULL) { struct inet6_dev *idev = in6_dev_get(dev); (void) ip6_mc_leave_src(sk, mc_lst, idev); @@ -301,7 +301,7 @@ static struct inet6_dev *ip6_mc_find_dev(struct in6_addr *group, int ifindex) dst_release(&rt->u.dst); } } else - dev = dev_get_by_index(ifindex); + dev = dev_get_by_index(&init_net, ifindex); if (!dev) return NULL; @@ -332,7 +332,7 @@ void ipv6_sock_mc_close(struct sock *sk) np->ipv6_mc_list = mc_lst->next; write_unlock_bh(&ipv6_sk_mc_lock); - dev = dev_get_by_index(mc_lst->ifindex); + dev = dev_get_by_index(&init_net, mc_lst->ifindex); if (dev) { struct inet6_dev *idev = in6_dev_get(dev); @@ -2333,7 +2333,7 @@ static inline struct ifmcaddr6 *igmp6_mc_get_first(struct seq_file *seq) struct igmp6_mc_iter_state *state = igmp6_mc_seq_private(seq); state->idev = NULL; - for_each_netdev(state->dev) { + for_each_netdev(&init_net, state->dev) { struct inet6_dev *idev; idev = in6_dev_get(state->dev); if (!idev) @@ -2477,7 +2477,7 @@ static inline struct ip6_sf_list *igmp6_mcf_get_first(struct seq_file *seq) state->idev = NULL; state->im = NULL; - for_each_netdev(state->dev) { + for_each_netdev(&init_net, state->dev) { struct inet6_dev *idev; idev = in6_dev_get(state->dev); if (unlikely(idev == NULL)) diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c index 38a3d21c2585..bdd0974e6775 100644 --- a/net/ipv6/raw.c +++ b/net/ipv6/raw.c @@ -283,7 +283,7 @@ static int rawv6_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len) if (!sk->sk_bound_dev_if) goto out; - dev = dev_get_by_index(sk->sk_bound_dev_if); + dev = dev_get_by_index(&init_net, sk->sk_bound_dev_if); if (!dev) { err = -ENODEV; goto out; diff --git a/net/ipv6/reassembly.c b/net/ipv6/reassembly.c index de795c04e34c..31601c993541 100644 --- a/net/ipv6/reassembly.c +++ b/net/ipv6/reassembly.c @@ -301,7 +301,7 @@ static void ip6_frag_expire(unsigned long data) fq_kill(fq); - dev = dev_get_by_index(fq->iif); + dev = dev_get_by_index(&init_net, fq->iif); if (!dev) goto out; diff --git a/net/ipv6/route.c b/net/ipv6/route.c index f4f0c341e5c8..5bdd9d4010fe 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c @@ -1130,7 +1130,7 @@ int ip6_route_add(struct fib6_config *cfg) #endif if (cfg->fc_ifindex) { err = -ENODEV; - dev = dev_get_by_index(cfg->fc_ifindex); + dev = dev_get_by_index(&init_net, cfg->fc_ifindex); if (!dev) goto out; idev = in6_dev_get(dev); @@ -2265,7 +2265,7 @@ static int inet6_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr* nlh, void if (iif) { struct net_device *dev; - dev = __dev_get_by_index(iif); + dev = __dev_get_by_index(&init_net, iif); if (!dev) { err = -ENODEV; goto errout; diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c index eb20bb690abd..e79f419b1731 100644 --- a/net/ipv6/sit.c +++ b/net/ipv6/sit.c @@ -167,7 +167,7 @@ static struct ip_tunnel * ipip6_tunnel_locate(struct ip_tunnel_parm *parms, int int i; for (i=1; i<100; i++) { sprintf(name, "sit%d", i); - if (__dev_get_by_name(name) == NULL) + if (__dev_get_by_name(&init_net, name) == NULL) break; } if (i==100) @@ -761,7 +761,7 @@ static int ipip6_tunnel_init(struct net_device *dev) } if (!tdev && tunnel->parms.link) - tdev = __dev_get_by_index(tunnel->parms.link); + tdev = __dev_get_by_index(&init_net, tunnel->parms.link); if (tdev) { dev->hard_header_len = tdev->hard_header_len + sizeof(struct iphdr); diff --git a/net/ipx/af_ipx.c b/net/ipx/af_ipx.c index 24921f12e9af..29b063d43120 100644 --- a/net/ipx/af_ipx.c +++ b/net/ipx/af_ipx.c @@ -989,7 +989,7 @@ static int ipxitf_create(struct ipx_interface_definition *idef) if (intrfc) ipxitf_put(intrfc); - dev = dev_get_by_name(idef->ipx_device); + dev = dev_get_by_name(&init_net, idef->ipx_device); rc = -ENODEV; if (!dev) goto out; @@ -1097,7 +1097,7 @@ static int ipxitf_delete(struct ipx_interface_definition *idef) if (!dlink_type) goto out; - dev = __dev_get_by_name(idef->ipx_device); + dev = __dev_get_by_name(&init_net, idef->ipx_device); rc = -ENODEV; if (!dev) goto out; @@ -1192,7 +1192,7 @@ static int ipxitf_ioctl(unsigned int cmd, void __user *arg) if (copy_from_user(&ifr, arg, sizeof(ifr))) break; sipx = (struct sockaddr_ipx *)&ifr.ifr_addr; - dev = __dev_get_by_name(ifr.ifr_name); + dev = __dev_get_by_name(&init_net, ifr.ifr_name); rc = -ENODEV; if (!dev) break; diff --git a/net/irda/irnetlink.c b/net/irda/irnetlink.c index 1e429c929739..cd9ff176ecde 100644 --- a/net/irda/irnetlink.c +++ b/net/irda/irnetlink.c @@ -15,6 +15,7 @@ #include #include +#include #include #include #include @@ -30,7 +31,7 @@ static struct genl_family irda_nl_family = { .maxattr = IRDA_NL_CMD_MAX, }; -static struct net_device * ifname_to_netdev(struct genl_info *info) +static struct net_device * ifname_to_netdev(struct net *net, struct genl_info *info) { char * ifname; @@ -41,7 +42,7 @@ static struct net_device * ifname_to_netdev(struct genl_info *info) IRDA_DEBUG(5, "%s(): Looking for %s\n", __FUNCTION__, ifname); - return dev_get_by_name(ifname); + return dev_get_by_name(net, ifname); } static int irda_nl_set_mode(struct sk_buff *skb, struct genl_info *info) @@ -57,7 +58,7 @@ static int irda_nl_set_mode(struct sk_buff *skb, struct genl_info *info) IRDA_DEBUG(5, "%s(): Switching to mode: %d\n", __FUNCTION__, mode); - dev = ifname_to_netdev(info); + dev = ifname_to_netdev(&init_net, info); if (!dev) return -ENODEV; @@ -82,7 +83,7 @@ static int irda_nl_get_mode(struct sk_buff *skb, struct genl_info *info) void *hdr; int ret = -ENOBUFS; - dev = ifname_to_netdev(info); + dev = ifname_to_netdev(&init_net, info); if (!dev) return -ENODEV; diff --git a/net/llc/af_llc.c b/net/llc/af_llc.c index b48244156e75..49eacba824df 100644 --- a/net/llc/af_llc.c +++ b/net/llc/af_llc.c @@ -252,7 +252,7 @@ static int llc_ui_autobind(struct socket *sock, struct sockaddr_llc *addr) if (!sock_flag(sk, SOCK_ZAPPED)) goto out; rc = -ENODEV; - llc->dev = dev_getfirstbyhwtype(addr->sllc_arphrd); + llc->dev = dev_getfirstbyhwtype(&init_net, addr->sllc_arphrd); if (!llc->dev) goto out; rc = -EUSERS; @@ -303,7 +303,7 @@ static int llc_ui_bind(struct socket *sock, struct sockaddr *uaddr, int addrlen) goto out; rc = -ENODEV; rtnl_lock(); - llc->dev = dev_getbyhwaddr(addr->sllc_arphrd, addr->sllc_mac); + llc->dev = dev_getbyhwaddr(&init_net, addr->sllc_arphrd, addr->sllc_mac); rtnl_unlock(); if (!llc->dev) goto out; diff --git a/net/llc/llc_core.c b/net/llc/llc_core.c index d4b13a031fd5..248b5903bb13 100644 --- a/net/llc/llc_core.c +++ b/net/llc/llc_core.c @@ -19,6 +19,7 @@ #include #include #include +#include #include LIST_HEAD(llc_sap_list); @@ -162,7 +163,7 @@ static int __init llc_init(void) { struct net_device *dev; - dev = first_net_device(); + dev = first_net_device(&init_net); if (dev != NULL) dev = next_net_device(dev); diff --git a/net/mac80211/ieee80211.c b/net/mac80211/ieee80211.c index 73e314e33de2..506cfa06b184 100644 --- a/net/mac80211/ieee80211.c +++ b/net/mac80211/ieee80211.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include "ieee80211_common.h" diff --git a/net/mac80211/ieee80211_cfg.c b/net/mac80211/ieee80211_cfg.c index 509096edb324..b1c13bc9c3ca 100644 --- a/net/mac80211/ieee80211_cfg.c +++ b/net/mac80211/ieee80211_cfg.c @@ -8,6 +8,7 @@ #include #include +#include #include #include "ieee80211_i.h" #include "ieee80211_cfg.h" @@ -50,7 +51,7 @@ static int ieee80211_del_iface(struct wiphy *wiphy, int ifindex) if (unlikely(local->reg_state != IEEE80211_DEV_REGISTERED)) return -ENODEV; - dev = dev_get_by_index(ifindex); + dev = dev_get_by_index(&init_net, ifindex); if (!dev) return 0; diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index b65ff6536244..9e952e37b7df 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -1018,7 +1019,7 @@ static int inline ieee80211_tx_prepare(struct ieee80211_txrx_data *tx, struct net_device *dev; pkt_data = (struct ieee80211_tx_packet_data *)skb->cb; - dev = dev_get_by_index(pkt_data->ifindex); + dev = dev_get_by_index(&init_net, pkt_data->ifindex); if (unlikely(dev && !is_ieee80211_device(dev, mdev))) { dev_put(dev); dev = NULL; @@ -1226,7 +1227,7 @@ int ieee80211_master_start_xmit(struct sk_buff *skb, memset(&control, 0, sizeof(struct ieee80211_tx_control)); if (pkt_data->ifindex) - odev = dev_get_by_index(pkt_data->ifindex); + odev = dev_get_by_index(&init_net, pkt_data->ifindex); if (unlikely(odev && !is_ieee80211_device(odev, dev))) { dev_put(odev); odev = NULL; @@ -1722,7 +1723,7 @@ struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw, int if_id, u8 *b_head, *b_tail; int bh_len, bt_len; - bdev = dev_get_by_index(if_id); + bdev = dev_get_by_index(&init_net, if_id); if (bdev) { sdata = IEEE80211_DEV_TO_SUB_IF(bdev); ap = &sdata->u.ap; @@ -1836,7 +1837,7 @@ ieee80211_get_buffered_bc(struct ieee80211_hw *hw, int if_id, struct ieee80211_sub_if_data *sdata; struct ieee80211_if_ap *bss = NULL; - bdev = dev_get_by_index(if_id); + bdev = dev_get_by_index(&init_net, if_id); if (bdev) { sdata = IEEE80211_DEV_TO_SUB_IF(bdev); bss = &sdata->u.ap; diff --git a/net/mac80211/util.c b/net/mac80211/util.c index 07686bda26cd..c970996ba6f9 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include "ieee80211_i.h" @@ -318,7 +319,7 @@ __le16 ieee80211_generic_frame_duration(struct ieee80211_hw *hw, int if_id, size_t frame_len, int rate) { struct ieee80211_local *local = hw_to_local(hw); - struct net_device *bdev = dev_get_by_index(if_id); + struct net_device *bdev = dev_get_by_index(&init_net, if_id); struct ieee80211_sub_if_data *sdata; u16 dur; int erp; @@ -342,7 +343,7 @@ __le16 ieee80211_rts_duration(struct ieee80211_hw *hw, int if_id, { struct ieee80211_local *local = hw_to_local(hw); struct ieee80211_rate *rate; - struct net_device *bdev = dev_get_by_index(if_id); + struct net_device *bdev = dev_get_by_index(&init_net, if_id); struct ieee80211_sub_if_data *sdata; int short_preamble; int erp; @@ -378,7 +379,7 @@ __le16 ieee80211_ctstoself_duration(struct ieee80211_hw *hw, int if_id, { struct ieee80211_local *local = hw_to_local(hw); struct ieee80211_rate *rate; - struct net_device *bdev = dev_get_by_index(if_id); + struct net_device *bdev = dev_get_by_index(&init_net, if_id); struct ieee80211_sub_if_data *sdata; int short_preamble; int erp; diff --git a/net/netrom/nr_route.c b/net/netrom/nr_route.c index 24fe4a66d297..e943c16552a2 100644 --- a/net/netrom/nr_route.c +++ b/net/netrom/nr_route.c @@ -580,7 +580,7 @@ static struct net_device *nr_ax25_dev_get(char *devname) { struct net_device *dev; - if ((dev = dev_get_by_name(devname)) == NULL) + if ((dev = dev_get_by_name(&init_net, devname)) == NULL) return NULL; if ((dev->flags & IFF_UP) && dev->type == ARPHRD_AX25) @@ -598,7 +598,7 @@ struct net_device *nr_dev_first(void) struct net_device *dev, *first = NULL; read_lock(&dev_base_lock); - for_each_netdev(dev) { + for_each_netdev(&init_net, dev) { if ((dev->flags & IFF_UP) && dev->type == ARPHRD_NETROM) if (first == NULL || strncmp(dev->name, first->name, 3) < 0) first = dev; @@ -618,7 +618,7 @@ struct net_device *nr_dev_get(ax25_address *addr) struct net_device *dev; read_lock(&dev_base_lock); - for_each_netdev(dev) { + for_each_netdev(&init_net, dev) { if ((dev->flags & IFF_UP) && dev->type == ARPHRD_NETROM && ax25cmp(addr, (ax25_address *)dev->dev_addr) == 0) { dev_hold(dev); goto out; diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c index ad0052524e88..745e2cb87c96 100644 --- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c @@ -347,7 +347,7 @@ static int packet_sendmsg_spkt(struct kiocb *iocb, struct socket *sock, */ saddr->spkt_device[13] = 0; - dev = dev_get_by_name(saddr->spkt_device); + dev = dev_get_by_name(&init_net, saddr->spkt_device); err = -ENODEV; if (dev == NULL) goto out_unlock; @@ -742,7 +742,7 @@ static int packet_sendmsg(struct kiocb *iocb, struct socket *sock, } - dev = dev_get_by_index(ifindex); + dev = dev_get_by_index(&init_net, ifindex); err = -ENXIO; if (dev == NULL) goto out_unlock; @@ -937,7 +937,7 @@ static int packet_bind_spkt(struct socket *sock, struct sockaddr *uaddr, int add return -EINVAL; strlcpy(name,uaddr->sa_data,sizeof(name)); - dev = dev_get_by_name(name); + dev = dev_get_by_name(&init_net, name); if (dev) { err = packet_do_bind(sk, dev, pkt_sk(sk)->num); dev_put(dev); @@ -964,7 +964,7 @@ static int packet_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len if (sll->sll_ifindex) { err = -ENODEV; - dev = dev_get_by_index(sll->sll_ifindex); + dev = dev_get_by_index(&init_net, sll->sll_ifindex); if (dev == NULL) goto out; } @@ -1161,7 +1161,7 @@ static int packet_getname_spkt(struct socket *sock, struct sockaddr *uaddr, return -EOPNOTSUPP; uaddr->sa_family = AF_PACKET; - dev = dev_get_by_index(pkt_sk(sk)->ifindex); + dev = dev_get_by_index(&init_net, pkt_sk(sk)->ifindex); if (dev) { strlcpy(uaddr->sa_data, dev->name, 15); dev_put(dev); @@ -1186,7 +1186,7 @@ static int packet_getname(struct socket *sock, struct sockaddr *uaddr, sll->sll_family = AF_PACKET; sll->sll_ifindex = po->ifindex; sll->sll_protocol = po->num; - dev = dev_get_by_index(po->ifindex); + dev = dev_get_by_index(&init_net, po->ifindex); if (dev) { sll->sll_hatype = dev->type; sll->sll_halen = dev->addr_len; @@ -1238,7 +1238,7 @@ static int packet_mc_add(struct sock *sk, struct packet_mreq_max *mreq) rtnl_lock(); err = -ENODEV; - dev = __dev_get_by_index(mreq->mr_ifindex); + dev = __dev_get_by_index(&init_net, mreq->mr_ifindex); if (!dev) goto done; @@ -1292,7 +1292,7 @@ static int packet_mc_drop(struct sock *sk, struct packet_mreq_max *mreq) if (--ml->count == 0) { struct net_device *dev; *mlp = ml->next; - dev = dev_get_by_index(ml->ifindex); + dev = dev_get_by_index(&init_net, ml->ifindex); if (dev) { packet_dev_mc(dev, ml, -1); dev_put(dev); @@ -1320,7 +1320,7 @@ static void packet_flush_mclist(struct sock *sk) struct net_device *dev; po->mclist = ml->next; - if ((dev = dev_get_by_index(ml->ifindex)) != NULL) { + if ((dev = dev_get_by_index(&init_net, ml->ifindex)) != NULL) { packet_dev_mc(dev, ml, -1); dev_put(dev); } diff --git a/net/rose/rose_route.c b/net/rose/rose_route.c index 96f61a71b252..540c0f26ffee 100644 --- a/net/rose/rose_route.c +++ b/net/rose/rose_route.c @@ -583,7 +583,7 @@ static struct net_device *rose_ax25_dev_get(char *devname) { struct net_device *dev; - if ((dev = dev_get_by_name(devname)) == NULL) + if ((dev = dev_get_by_name(&init_net, devname)) == NULL) return NULL; if ((dev->flags & IFF_UP) && dev->type == ARPHRD_AX25) @@ -601,7 +601,7 @@ struct net_device *rose_dev_first(void) struct net_device *dev, *first = NULL; read_lock(&dev_base_lock); - for_each_netdev(dev) { + for_each_netdev(&init_net, dev) { if ((dev->flags & IFF_UP) && dev->type == ARPHRD_ROSE) if (first == NULL || strncmp(dev->name, first->name, 3) < 0) first = dev; @@ -619,7 +619,7 @@ struct net_device *rose_dev_get(rose_address *addr) struct net_device *dev; read_lock(&dev_base_lock); - for_each_netdev(dev) { + for_each_netdev(&init_net, dev) { if ((dev->flags & IFF_UP) && dev->type == ARPHRD_ROSE && rosecmp(addr, (rose_address *)dev->dev_addr) == 0) { dev_hold(dev); goto out; @@ -636,7 +636,7 @@ static int rose_dev_exists(rose_address *addr) struct net_device *dev; read_lock(&dev_base_lock); - for_each_netdev(dev) { + for_each_netdev(&init_net, dev) { if ((dev->flags & IFF_UP) && dev->type == ARPHRD_ROSE && rosecmp(addr, (rose_address *)dev->dev_addr) == 0) goto out; } diff --git a/net/sched/act_mirred.c b/net/sched/act_mirred.c index 579578944ae7..fd7bca4d5c20 100644 --- a/net/sched/act_mirred.c +++ b/net/sched/act_mirred.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -73,7 +74,7 @@ static int tcf_mirred_init(struct rtattr *rta, struct rtattr *est, parm = RTA_DATA(tb[TCA_MIRRED_PARMS-1]); if (parm->ifindex) { - dev = __dev_get_by_index(parm->ifindex); + dev = __dev_get_by_index(&init_net, parm->ifindex); if (dev == NULL) return -ENODEV; switch (dev->type) { diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c index 5f0fbca7393f..03657976fd50 100644 --- a/net/sched/cls_api.c +++ b/net/sched/cls_api.c @@ -154,7 +154,7 @@ replay: /* Find head of filter chain. */ /* Find link */ - if ((dev = __dev_get_by_index(t->tcm_ifindex)) == NULL) + if ((dev = __dev_get_by_index(&init_net, t->tcm_ifindex)) == NULL) return -ENODEV; /* Find qdisc */ @@ -387,7 +387,7 @@ static int tc_dump_tfilter(struct sk_buff *skb, struct netlink_callback *cb) if (cb->nlh->nlmsg_len < NLMSG_LENGTH(sizeof(*tcm))) return skb->len; - if ((dev = dev_get_by_index(tcm->tcm_ifindex)) == NULL) + if ((dev = dev_get_by_index(&init_net, tcm->tcm_ifindex)) == NULL) return skb->len; if (!tcm->tcm_parent) diff --git a/net/sched/em_meta.c b/net/sched/em_meta.c index 650f09c8bd6a..e9989610712c 100644 --- a/net/sched/em_meta.c +++ b/net/sched/em_meta.c @@ -291,7 +291,7 @@ META_COLLECTOR(var_sk_bound_if) } else { struct net_device *dev; - dev = dev_get_by_index(skb->sk->sk_bound_dev_if); + dev = dev_get_by_index(&init_net, skb->sk->sk_bound_dev_if); *err = var_dev(dev, dst); if (dev) dev_put(dev); diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c index efc383c58f1e..39d32780c80b 100644 --- a/net/sched/sch_api.c +++ b/net/sched/sch_api.c @@ -607,7 +607,7 @@ static int tc_get_qdisc(struct sk_buff *skb, struct nlmsghdr *n, void *arg) struct Qdisc *p = NULL; int err; - if ((dev = __dev_get_by_index(tcm->tcm_ifindex)) == NULL) + if ((dev = __dev_get_by_index(&init_net, tcm->tcm_ifindex)) == NULL) return -ENODEV; if (clid) { @@ -674,7 +674,7 @@ replay: clid = tcm->tcm_parent; q = p = NULL; - if ((dev = __dev_get_by_index(tcm->tcm_ifindex)) == NULL) + if ((dev = __dev_get_by_index(&init_net, tcm->tcm_ifindex)) == NULL) return -ENODEV; if (clid) { @@ -881,7 +881,7 @@ static int tc_dump_qdisc(struct sk_buff *skb, struct netlink_callback *cb) s_q_idx = q_idx = cb->args[1]; read_lock(&dev_base_lock); idx = 0; - for_each_netdev(dev) { + for_each_netdev(&init_net, dev) { if (idx < s_idx) goto cont; if (idx > s_idx) @@ -932,7 +932,7 @@ static int tc_ctl_tclass(struct sk_buff *skb, struct nlmsghdr *n, void *arg) u32 qid = TC_H_MAJ(clid); int err; - if ((dev = __dev_get_by_index(tcm->tcm_ifindex)) == NULL) + if ((dev = __dev_get_by_index(&init_net, tcm->tcm_ifindex)) == NULL) return -ENODEV; /* @@ -1115,7 +1115,7 @@ static int tc_dump_tclass(struct sk_buff *skb, struct netlink_callback *cb) if (cb->nlh->nlmsg_len < NLMSG_LENGTH(sizeof(*tcm))) return 0; - if ((dev = dev_get_by_index(tcm->tcm_ifindex)) == NULL) + if ((dev = dev_get_by_index(&init_net, tcm->tcm_ifindex)) == NULL) return 0; s_t = cb->args[0]; diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c index ddeb4882ec75..9de3ddaa2768 100644 --- a/net/sctp/ipv6.c +++ b/net/sctp/ipv6.c @@ -855,7 +855,7 @@ static int sctp_inet6_bind_verify(struct sctp_sock *opt, union sctp_addr *addr) if (type & IPV6_ADDR_LINKLOCAL) { if (!addr->v6.sin6_scope_id) return 0; - dev = dev_get_by_index(addr->v6.sin6_scope_id); + dev = dev_get_by_index(&init_net, addr->v6.sin6_scope_id); if (!dev) return 0; if (!ipv6_chk_addr(&addr->v6.sin6_addr, dev, 0)) { @@ -886,7 +886,7 @@ static int sctp_inet6_send_verify(struct sctp_sock *opt, union sctp_addr *addr) if (type & IPV6_ADDR_LINKLOCAL) { if (!addr->v6.sin6_scope_id) return 0; - dev = dev_get_by_index(addr->v6.sin6_scope_id); + dev = dev_get_by_index(&init_net, addr->v6.sin6_scope_id); if (!dev) return 0; dev_put(dev); diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c index af67c839ef98..54edcd978f75 100644 --- a/net/sctp/protocol.c +++ b/net/sctp/protocol.c @@ -179,7 +179,7 @@ static void sctp_get_local_addr_list(void) struct sctp_af *af; read_lock(&dev_base_lock); - for_each_netdev(dev) { + for_each_netdev(&init_net, dev) { __list_for_each(pos, &sctp_address_families) { af = list_entry(pos, struct sctp_af, list); af->copy_addrlist(&sctp_local_addr_list, dev); diff --git a/net/socket.c b/net/socket.c index a714c6d4e4a1..bc16eee4dc80 100644 --- a/net/socket.c +++ b/net/socket.c @@ -791,9 +791,9 @@ static ssize_t sock_aio_write(struct kiocb *iocb, const struct iovec *iov, */ static DEFINE_MUTEX(br_ioctl_mutex); -static int (*br_ioctl_hook) (unsigned int cmd, void __user *arg) = NULL; +static int (*br_ioctl_hook) (struct net *, unsigned int cmd, void __user *arg) = NULL; -void brioctl_set(int (*hook) (unsigned int, void __user *)) +void brioctl_set(int (*hook) (struct net *, unsigned int, void __user *)) { mutex_lock(&br_ioctl_mutex); br_ioctl_hook = hook; @@ -803,9 +803,9 @@ void brioctl_set(int (*hook) (unsigned int, void __user *)) EXPORT_SYMBOL(brioctl_set); static DEFINE_MUTEX(vlan_ioctl_mutex); -static int (*vlan_ioctl_hook) (void __user *arg); +static int (*vlan_ioctl_hook) (struct net *, void __user *arg); -void vlan_ioctl_set(int (*hook) (void __user *)) +void vlan_ioctl_set(int (*hook) (struct net *, void __user *)) { mutex_lock(&vlan_ioctl_mutex); vlan_ioctl_hook = hook; @@ -834,16 +834,20 @@ EXPORT_SYMBOL(dlci_ioctl_set); static long sock_ioctl(struct file *file, unsigned cmd, unsigned long arg) { struct socket *sock; + struct sock *sk; void __user *argp = (void __user *)arg; int pid, err; + struct net *net; sock = file->private_data; + sk = sock->sk; + net = sk->sk_net; if (cmd >= SIOCDEVPRIVATE && cmd <= (SIOCDEVPRIVATE + 15)) { - err = dev_ioctl(cmd, argp); + err = dev_ioctl(net, cmd, argp); } else #ifdef CONFIG_WIRELESS_EXT if (cmd >= SIOCIWFIRST && cmd <= SIOCIWLAST) { - err = dev_ioctl(cmd, argp); + err = dev_ioctl(net, cmd, argp); } else #endif /* CONFIG_WIRELESS_EXT */ switch (cmd) { @@ -869,7 +873,7 @@ static long sock_ioctl(struct file *file, unsigned cmd, unsigned long arg) mutex_lock(&br_ioctl_mutex); if (br_ioctl_hook) - err = br_ioctl_hook(cmd, argp); + err = br_ioctl_hook(net, cmd, argp); mutex_unlock(&br_ioctl_mutex); break; case SIOCGIFVLAN: @@ -880,7 +884,7 @@ static long sock_ioctl(struct file *file, unsigned cmd, unsigned long arg) mutex_lock(&vlan_ioctl_mutex); if (vlan_ioctl_hook) - err = vlan_ioctl_hook(argp); + err = vlan_ioctl_hook(net, argp); mutex_unlock(&vlan_ioctl_mutex); break; case SIOCADDDLCI: @@ -903,7 +907,7 @@ static long sock_ioctl(struct file *file, unsigned cmd, unsigned long arg) * to the NIC driver. */ if (err == -ENOIOCTLCMD) - err = dev_ioctl(cmd, argp); + err = dev_ioctl(net, cmd, argp); break; } return err; diff --git a/net/tipc/eth_media.c b/net/tipc/eth_media.c index 406f0d26fa81..d6fc0575816b 100644 --- a/net/tipc/eth_media.c +++ b/net/tipc/eth_media.c @@ -135,7 +135,7 @@ static int enable_bearer(struct tipc_bearer *tb_ptr) /* Find device with specified name */ - for_each_netdev(pdev){ + for_each_netdev(&init_net, pdev){ if (!strncmp(pdev->name, driver_name, IFNAMSIZ)) { dev = pdev; break; diff --git a/net/wireless/wext.c b/net/wireless/wext.c index b8069afe0410..e8b3409d6c8b 100644 --- a/net/wireless/wext.c +++ b/net/wireless/wext.c @@ -673,7 +673,22 @@ static const struct seq_operations wireless_seq_ops = { static int wireless_seq_open(struct inode *inode, struct file *file) { - return seq_open(file, &wireless_seq_ops); + struct seq_file *seq; + int res; + res = seq_open(file, &wireless_seq_ops); + if (!res) { + seq = file->private_data; + seq->private = get_net(PROC_NET(inode)); + } + return res; +} + +static int wireless_seq_release(struct inode *inode, struct file *file) +{ + struct seq_file *seq = file->private_data; + struct net *net = seq->private; + put_net(net); + return seq_release(inode, file); } static const struct file_operations wireless_seq_fops = { @@ -681,17 +696,22 @@ static const struct file_operations wireless_seq_fops = { .open = wireless_seq_open, .read = seq_read, .llseek = seq_lseek, - .release = seq_release, + .release = wireless_seq_release, }; -int __init wext_proc_init(void) +int wext_proc_init(struct net *net) { /* Create /proc/net/wireless entry */ - if (!proc_net_fops_create(&init_net, "wireless", S_IRUGO, &wireless_seq_fops)) + if (!proc_net_fops_create(net, "wireless", S_IRUGO, &wireless_seq_fops)) return -ENOMEM; return 0; } + +void wext_proc_exit(struct net *net) +{ + proc_net_remove(net, "wireless"); +} #endif /* CONFIG_PROC_FS */ /************************** IOCTL SUPPORT **************************/ @@ -1011,7 +1031,7 @@ static int ioctl_private_call(struct net_device *dev, struct ifreq *ifr, * Main IOCTl dispatcher. * Check the type of IOCTL and call the appropriate wrapper... */ -static int wireless_process_ioctl(struct ifreq *ifr, unsigned int cmd) +static int wireless_process_ioctl(struct net *net, struct ifreq *ifr, unsigned int cmd) { struct net_device *dev; iw_handler handler; @@ -1020,7 +1040,7 @@ static int wireless_process_ioctl(struct ifreq *ifr, unsigned int cmd) * The copy_to/from_user() of ifr is also dealt with in there */ /* Make sure the device exist */ - if ((dev = __dev_get_by_name(ifr->ifr_name)) == NULL) + if ((dev = __dev_get_by_name(net, ifr->ifr_name)) == NULL) return -ENODEV; /* A bunch of special cases, then the generic case... @@ -1054,7 +1074,7 @@ static int wireless_process_ioctl(struct ifreq *ifr, unsigned int cmd) } /* entry point from dev ioctl */ -int wext_handle_ioctl(struct ifreq *ifr, unsigned int cmd, +int wext_handle_ioctl(struct net *net, struct ifreq *ifr, unsigned int cmd, void __user *arg) { int ret; @@ -1066,9 +1086,9 @@ int wext_handle_ioctl(struct ifreq *ifr, unsigned int cmd, && !capable(CAP_NET_ADMIN)) return -EPERM; - dev_load(ifr->ifr_name); + dev_load(net, ifr->ifr_name); rtnl_lock(); - ret = wireless_process_ioctl(ifr, cmd); + ret = wireless_process_ioctl(net, ifr, cmd); rtnl_unlock(); if (IW_IS_GET(cmd) && copy_to_user(arg, ifr, sizeof(struct ifreq))) return -EFAULT; diff --git a/net/x25/x25_route.c b/net/x25/x25_route.c index 060fcfaa2f47..86b5b4da097c 100644 --- a/net/x25/x25_route.c +++ b/net/x25/x25_route.c @@ -129,7 +129,7 @@ void x25_route_device_down(struct net_device *dev) */ struct net_device *x25_dev_get(char *devname) { - struct net_device *dev = dev_get_by_name(devname); + struct net_device *dev = dev_get_by_name(&init_net, devname); if (dev && (!(dev->flags & IFF_UP) || (dev->type != ARPHRD_X25 -- cgit v1.2.3 From ce286d327341295f58d89864d746a524287cfdf9 Mon Sep 17 00:00:00 2001 From: "Eric W. Biederman" Date: Wed, 12 Sep 2007 13:53:49 +0200 Subject: [NET]: Implement network device movement between namespaces This patch introduces NETIF_F_NETNS_LOCAL a flag to indicate a network device is local to a single network namespace and should never be moved. Useful for pseudo devices that we need an instance in each network namespace (like the loopback device) and for any device we find that cannot handle multiple network namespaces so we may trap them in the initial network namespace. This patch introduces the function dev_change_net_namespace a function used to move a network device from one network namespace to another. To the network device nothing special appears to happen, to the components of the network stack it appears as if the network device was unregistered in the network namespace it is in, and a new device was registered in the network namespace the device was moved to. This patch sets up a namespace device destructor that upon the exit of a network namespace moves all of the movable network devices to the initial network namespace so they are not lost. Signed-off-by: Eric W. Biederman Signed-off-by: David S. Miller --- drivers/net/loopback.c | 3 +- include/linux/netdevice.h | 3 + net/core/dev.c | 189 +++++++++++++++++++++++++++++++++++++++++++--- 3 files changed, 184 insertions(+), 11 deletions(-) (limited to 'include/linux') diff --git a/drivers/net/loopback.c b/drivers/net/loopback.c index 5106c2328d12..e399f7b201e3 100644 --- a/drivers/net/loopback.c +++ b/drivers/net/loopback.c @@ -222,7 +222,8 @@ struct net_device loopback_dev = { | NETIF_F_TSO #endif | NETIF_F_NO_CSUM | NETIF_F_HIGHDMA - | NETIF_F_LLTX, + | NETIF_F_LLTX + | NETIF_F_NETNS_LOCAL, .ethtool_ops = &loopback_ethtool_ops, }; diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 7353b3e1f4fc..407658c64fb6 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -449,6 +449,7 @@ struct net_device #define NETIF_F_VLAN_CHALLENGED 1024 /* Device cannot handle VLAN packets */ #define NETIF_F_GSO 2048 /* Enable software GSO. */ #define NETIF_F_LLTX 4096 /* LockLess TX */ +#define NETIF_F_NETNS_LOCAL 8192 /* Does not change network namespaces */ #define NETIF_F_MULTI_QUEUE 16384 /* Has multiple TX/RX queues */ #define NETIF_F_LRO 32768 /* large receive offload */ @@ -1016,6 +1017,8 @@ extern int dev_ethtool(struct net *net, struct ifreq *); extern unsigned dev_get_flags(const struct net_device *); extern int dev_change_flags(struct net_device *, unsigned); extern int dev_change_name(struct net_device *, char *); +extern int dev_change_net_namespace(struct net_device *, + struct net *, const char *); extern int dev_set_mtu(struct net_device *, int); extern int dev_set_mac_address(struct net_device *, struct sockaddr *); diff --git a/net/core/dev.c b/net/core/dev.c index 520ef7b20862..215b8e97690a 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -208,6 +208,34 @@ static inline struct hlist_head *dev_index_hash(struct net *net, int ifindex) return &net->dev_index_head[ifindex & ((1 << NETDEV_HASHBITS) - 1)]; } +/* Device list insertion */ +static int list_netdevice(struct net_device *dev) +{ + struct net *net = dev->nd_net; + + ASSERT_RTNL(); + + write_lock_bh(&dev_base_lock); + list_add_tail(&dev->dev_list, &net->dev_base_head); + hlist_add_head(&dev->name_hlist, dev_name_hash(net, dev->name)); + hlist_add_head(&dev->index_hlist, dev_index_hash(net, dev->ifindex)); + write_unlock_bh(&dev_base_lock); + return 0; +} + +/* Device list removal */ +static void unlist_netdevice(struct net_device *dev) +{ + ASSERT_RTNL(); + + /* Unlink dev from the device chain */ + write_lock_bh(&dev_base_lock); + list_del(&dev->dev_list); + hlist_del(&dev->name_hlist); + hlist_del(&dev->index_hlist); + write_unlock_bh(&dev_base_lock); +} + /* * Our notifier list */ @@ -3571,12 +3599,8 @@ int register_netdevice(struct net_device *dev) set_bit(__LINK_STATE_PRESENT, &dev->state); dev_init_scheduler(dev); - write_lock_bh(&dev_base_lock); - list_add_tail(&dev->dev_list, &net->dev_base_head); - hlist_add_head(&dev->name_hlist, head); - hlist_add_head(&dev->index_hlist, dev_index_hash(net, dev->ifindex)); dev_hold(dev); - write_unlock_bh(&dev_base_lock); + list_netdevice(dev); /* Notify protocols, that a new device appeared. */ ret = raw_notifier_call_chain(&netdev_chain, NETDEV_REGISTER, dev); @@ -3883,11 +3907,7 @@ void unregister_netdevice(struct net_device *dev) dev_close(dev); /* And unlink it from device chain. */ - write_lock_bh(&dev_base_lock); - list_del(&dev->dev_list); - hlist_del(&dev->name_hlist); - hlist_del(&dev->index_hlist); - write_unlock_bh(&dev_base_lock); + unlist_netdevice(dev); dev->reg_state = NETREG_UNREGISTERING; @@ -3945,6 +3965,122 @@ void unregister_netdev(struct net_device *dev) EXPORT_SYMBOL(unregister_netdev); +/** + * dev_change_net_namespace - move device to different nethost namespace + * @dev: device + * @net: network namespace + * @pat: If not NULL name pattern to try if the current device name + * is already taken in the destination network namespace. + * + * This function shuts down a device interface and moves it + * to a new network namespace. On success 0 is returned, on + * a failure a netagive errno code is returned. + * + * Callers must hold the rtnl semaphore. + */ + +int dev_change_net_namespace(struct net_device *dev, struct net *net, const char *pat) +{ + char buf[IFNAMSIZ]; + const char *destname; + int err; + + ASSERT_RTNL(); + + /* Don't allow namespace local devices to be moved. */ + err = -EINVAL; + if (dev->features & NETIF_F_NETNS_LOCAL) + goto out; + + /* Ensure the device has been registrered */ + err = -EINVAL; + if (dev->reg_state != NETREG_REGISTERED) + goto out; + + /* Get out if there is nothing todo */ + err = 0; + if (dev->nd_net == net) + goto out; + + /* Pick the destination device name, and ensure + * we can use it in the destination network namespace. + */ + err = -EEXIST; + destname = dev->name; + if (__dev_get_by_name(net, destname)) { + /* We get here if we can't use the current device name */ + if (!pat) + goto out; + if (!dev_valid_name(pat)) + goto out; + if (strchr(pat, '%')) { + if (__dev_alloc_name(net, pat, buf) < 0) + goto out; + destname = buf; + } else + destname = pat; + if (__dev_get_by_name(net, destname)) + goto out; + } + + /* + * And now a mini version of register_netdevice unregister_netdevice. + */ + + /* If device is running close it first. */ + if (dev->flags & IFF_UP) + dev_close(dev); + + /* And unlink it from device chain */ + err = -ENODEV; + unlist_netdevice(dev); + + synchronize_net(); + + /* Shutdown queueing discipline. */ + dev_shutdown(dev); + + /* Notify protocols, that we are about to destroy + this device. They should clean all the things. + */ + call_netdevice_notifiers(NETDEV_UNREGISTER, dev); + + /* + * Flush the unicast and multicast chains + */ + dev_addr_discard(dev); + + /* Actually switch the network namespace */ + dev->nd_net = net; + + /* Assign the new device name */ + if (destname != dev->name) + strcpy(dev->name, destname); + + /* If there is an ifindex conflict assign a new one */ + if (__dev_get_by_index(net, dev->ifindex)) { + int iflink = (dev->iflink == dev->ifindex); + dev->ifindex = dev_new_index(net); + if (iflink) + dev->iflink = dev->ifindex; + } + + /* Fixup sysfs */ + err = device_rename(&dev->dev, dev->name); + BUG_ON(err); + + /* Add the device back in the hashes */ + list_netdevice(dev); + + /* Notify protocols, that a new device appeared. */ + call_netdevice_notifiers(NETDEV_REGISTER, dev); + + synchronize_net(); + err = 0; +out: + return err; +} + static int dev_cpu_callback(struct notifier_block *nfb, unsigned long action, void *ocpu) @@ -4177,6 +4313,36 @@ static struct pernet_operations netdev_net_ops = { .exit = netdev_exit, }; +static void default_device_exit(struct net *net) +{ + struct net_device *dev, *next; + /* + * Push all migratable of the network devices back to the + * initial network namespace + */ + rtnl_lock(); + for_each_netdev_safe(net, dev, next) { + int err; + + /* Ignore unmoveable devices (i.e. loopback) */ + if (dev->features & NETIF_F_NETNS_LOCAL) + continue; + + /* Push remaing network devices to init_net */ + err = dev_change_net_namespace(dev, &init_net, "dev%d"); + if (err) { + printk(KERN_WARNING "%s: failed to move %s to init_net: %d\n", + __func__, dev->name, err); + unregister_netdevice(dev); + } + } + rtnl_unlock(); +} + +static struct pernet_operations default_device_ops = { + .exit = default_device_exit, +}; + /* * Initialize the DEV module. At boot time this walks the device list and * unhooks any devices that fail to initialise (normally hardware not @@ -4207,6 +4373,9 @@ static int __init net_dev_init(void) if (register_pernet_subsys(&netdev_net_ops)) goto out; + if (register_pernet_device(&default_device_ops)) + goto out; + /* * Initialise the packet receive queues. */ -- cgit v1.2.3 From d8a5ec672768c3cf4d51d7a63fc071520afa1617 Mon Sep 17 00:00:00 2001 From: "Eric W. Biederman" Date: Wed, 12 Sep 2007 13:57:04 +0200 Subject: [NET]: netlink support for moving devices between network namespaces. The simplest thing to implement is moving network devices between namespaces. However with the same attribute IFLA_NET_NS_PID we can easily implement creating devices in the destination network namespace as well. However that is a little bit trickier so this patch sticks to what is simple and easy. A pid is used to identify a process that happens to be a member of the network namespace we want to move the network device to. Signed-off-by: Eric W. Biederman Signed-off-by: David S. Miller --- include/linux/if_link.h | 1 + net/core/rtnetlink.c | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+) (limited to 'include/linux') diff --git a/include/linux/if_link.h b/include/linux/if_link.h index 422084d18ce1..84c3492ae5cb 100644 --- a/include/linux/if_link.h +++ b/include/linux/if_link.h @@ -78,6 +78,7 @@ enum IFLA_LINKMODE, IFLA_LINKINFO, #define IFLA_LINKINFO IFLA_LINKINFO + IFLA_NET_NS_PID, __IFLA_MAX }; diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index 44f91bb1ae8d..1b9c32d79917 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c @@ -35,6 +35,7 @@ #include #include #include +#include #include #include @@ -727,6 +728,7 @@ const struct nla_policy ifla_policy[IFLA_MAX+1] = { [IFLA_WEIGHT] = { .type = NLA_U32 }, [IFLA_OPERSTATE] = { .type = NLA_U8 }, [IFLA_LINKMODE] = { .type = NLA_U8 }, + [IFLA_NET_NS_PID] = { .type = NLA_U32 }, }; static const struct nla_policy ifla_info_policy[IFLA_INFO_MAX+1] = { @@ -734,12 +736,45 @@ static const struct nla_policy ifla_info_policy[IFLA_INFO_MAX+1] = { [IFLA_INFO_DATA] = { .type = NLA_NESTED }, }; +static struct net *get_net_ns_by_pid(pid_t pid) +{ + struct task_struct *tsk; + struct net *net; + + /* Lookup the network namespace */ + net = ERR_PTR(-ESRCH); + rcu_read_lock(); + tsk = find_task_by_pid(pid); + if (tsk) { + task_lock(tsk); + if (tsk->nsproxy) + net = get_net(tsk->nsproxy->net_ns); + task_unlock(tsk); + } + rcu_read_unlock(); + return net; +} + static int do_setlink(struct net_device *dev, struct ifinfomsg *ifm, struct nlattr **tb, char *ifname, int modified) { int send_addr_notify = 0; int err; + if (tb[IFLA_NET_NS_PID]) { + struct net *net; + net = get_net_ns_by_pid(nla_get_u32(tb[IFLA_NET_NS_PID])); + if (IS_ERR(net)) { + err = PTR_ERR(net); + goto errout; + } + err = dev_change_net_namespace(dev, net, ifname); + put_net(net); + if (err) + goto errout; + modified = 1; + } + if (tb[IFLA_MAP]) { struct rtnl_link_ifmap *u_map; struct ifmap k_map; -- cgit v1.2.3 From 8f4c1f9b049df3be11090f1c2c4738700302acae Mon Sep 17 00:00:00 2001 From: Thomas Graf Date: Wed, 12 Sep 2007 14:44:36 +0200 Subject: [NETLINK]: Introduce nested and byteorder flag to netlink attribute This change allows the generic attribute interface to be used within the netfilter subsystem where this flag was initially introduced. The byte-order flag is yet unused, it's intended use is to allow automatic byte order convertions for all atomic types. Signed-off-by: Thomas Graf Signed-off-by: David S. Miller --- include/linux/netlink.h | 14 ++++++++++++++ include/net/netlink.h | 9 +++++++++ net/ipv4/fib_frontend.c | 2 +- net/ipv4/fib_semantics.c | 2 +- net/ipv6/route.c | 2 +- net/netlabel/netlabel_cipso_v4.c | 14 +++++++------- net/netlink/attr.c | 10 +++++----- 7 files changed, 38 insertions(+), 15 deletions(-) (limited to 'include/linux') diff --git a/include/linux/netlink.h b/include/linux/netlink.h index d2843ae4a83a..e638256ce472 100644 --- a/include/linux/netlink.h +++ b/include/linux/netlink.h @@ -131,6 +131,20 @@ struct nlattr __u16 nla_type; }; +/* + * nla_type (16 bits) + * +---+---+-------------------------------+ + * | N | O | Attribute Type | + * +---+---+-------------------------------+ + * N := Carries nested attributes + * O := Payload stored in network byte order + * + * Note: The N and O flag are mutually exclusive. + */ +#define NLA_F_NESTED (1 << 15) +#define NLA_F_NET_BYTEORDER (1 << 14) +#define NLA_TYPE_MASK ~(NLA_F_NESTED | NLA_F_NET_BYTEORDER) + #define NLA_ALIGNTO 4 #define NLA_ALIGN(len) (((len) + NLA_ALIGNTO - 1) & ~(NLA_ALIGNTO - 1)) #define NLA_HDRLEN ((int) NLA_ALIGN(sizeof(struct nlattr))) diff --git a/include/net/netlink.h b/include/net/netlink.h index d7b824be5422..695e613a207b 100644 --- a/include/net/netlink.h +++ b/include/net/netlink.h @@ -666,6 +666,15 @@ static inline int nla_padlen(int payload) return nla_total_size(payload) - nla_attr_size(payload); } +/** + * nla_type - attribute type + * @nla: netlink attribute + */ +static inline int nla_type(const struct nlattr *nla) +{ + return nla->nla_type & NLA_TYPE_MASK; +} + /** * nla_data - head of payload * @nla: netlink attribute diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c index df17aab193b4..f823ca34cb12 100644 --- a/net/ipv4/fib_frontend.c +++ b/net/ipv4/fib_frontend.c @@ -487,7 +487,7 @@ static int rtm_to_fib_config(struct sk_buff *skb, struct nlmsghdr *nlh, } nlmsg_for_each_attr(attr, nlh, sizeof(struct rtmsg), remaining) { - switch (attr->nla_type) { + switch (nla_type(attr)) { case RTA_DST: cfg->fc_dst = nla_get_be32(attr); break; diff --git a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c index d30fb68d5f4e..1351a2617dce 100644 --- a/net/ipv4/fib_semantics.c +++ b/net/ipv4/fib_semantics.c @@ -743,7 +743,7 @@ struct fib_info *fib_create_info(struct fib_config *cfg) int remaining; nla_for_each_attr(nla, cfg->fc_mx, cfg->fc_mx_len, remaining) { - int type = nla->nla_type; + int type = nla_type(nla); if (type) { if (type > RTAX_MAX) diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 5bdd9d4010fe..104070e92cea 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c @@ -1279,7 +1279,7 @@ install_route: int remaining; nla_for_each_attr(nla, cfg->fc_mx, cfg->fc_mx_len, remaining) { - int type = nla->nla_type; + int type = nla_type(nla); if (type) { if (type > RTAX_MAX) { diff --git a/net/netlabel/netlabel_cipso_v4.c b/net/netlabel/netlabel_cipso_v4.c index c060e3f991f1..ba0ca8d3f77d 100644 --- a/net/netlabel/netlabel_cipso_v4.c +++ b/net/netlabel/netlabel_cipso_v4.c @@ -130,7 +130,7 @@ static int netlbl_cipsov4_add_common(struct genl_info *info, return -EINVAL; nla_for_each_nested(nla, info->attrs[NLBL_CIPSOV4_A_TAGLST], nla_rem) - if (nla->nla_type == NLBL_CIPSOV4_A_TAG) { + if (nla_type(nla) == NLBL_CIPSOV4_A_TAG) { if (iter >= CIPSO_V4_TAG_MAXCNT) return -EINVAL; doi_def->tags[iter++] = nla_get_u8(nla); @@ -192,13 +192,13 @@ static int netlbl_cipsov4_add_std(struct genl_info *info) nla_for_each_nested(nla_a, info->attrs[NLBL_CIPSOV4_A_MLSLVLLST], nla_a_rem) - if (nla_a->nla_type == NLBL_CIPSOV4_A_MLSLVL) { + if (nla_type(nla_a) == NLBL_CIPSOV4_A_MLSLVL) { if (nla_validate_nested(nla_a, NLBL_CIPSOV4_A_MAX, netlbl_cipsov4_genl_policy) != 0) goto add_std_failure; nla_for_each_nested(nla_b, nla_a, nla_b_rem) - switch (nla_b->nla_type) { + switch (nla_type(nla_b)) { case NLBL_CIPSOV4_A_MLSLVLLOC: if (nla_get_u32(nla_b) > CIPSO_V4_MAX_LOC_LVLS) @@ -240,7 +240,7 @@ static int netlbl_cipsov4_add_std(struct genl_info *info) nla_for_each_nested(nla_a, info->attrs[NLBL_CIPSOV4_A_MLSLVLLST], nla_a_rem) - if (nla_a->nla_type == NLBL_CIPSOV4_A_MLSLVL) { + if (nla_type(nla_a) == NLBL_CIPSOV4_A_MLSLVL) { struct nlattr *lvl_loc; struct nlattr *lvl_rem; @@ -265,13 +265,13 @@ static int netlbl_cipsov4_add_std(struct genl_info *info) nla_for_each_nested(nla_a, info->attrs[NLBL_CIPSOV4_A_MLSCATLST], nla_a_rem) - if (nla_a->nla_type == NLBL_CIPSOV4_A_MLSCAT) { + if (nla_type(nla_a) == NLBL_CIPSOV4_A_MLSCAT) { if (nla_validate_nested(nla_a, NLBL_CIPSOV4_A_MAX, netlbl_cipsov4_genl_policy) != 0) goto add_std_failure; nla_for_each_nested(nla_b, nla_a, nla_b_rem) - switch (nla_b->nla_type) { + switch (nla_type(nla_b)) { case NLBL_CIPSOV4_A_MLSCATLOC: if (nla_get_u32(nla_b) > CIPSO_V4_MAX_LOC_CATS) @@ -315,7 +315,7 @@ static int netlbl_cipsov4_add_std(struct genl_info *info) nla_for_each_nested(nla_a, info->attrs[NLBL_CIPSOV4_A_MLSCATLST], nla_a_rem) - if (nla_a->nla_type == NLBL_CIPSOV4_A_MLSCAT) { + if (nla_type(nla_a) == NLBL_CIPSOV4_A_MLSCAT) { struct nlattr *cat_loc; struct nlattr *cat_rem; diff --git a/net/netlink/attr.c b/net/netlink/attr.c index e4d7bed99c2e..ec39d12c2423 100644 --- a/net/netlink/attr.c +++ b/net/netlink/attr.c @@ -27,12 +27,12 @@ static int validate_nla(struct nlattr *nla, int maxtype, const struct nla_policy *policy) { const struct nla_policy *pt; - int minlen = 0, attrlen = nla_len(nla); + int minlen = 0, attrlen = nla_len(nla), type = nla_type(nla); - if (nla->nla_type <= 0 || nla->nla_type > maxtype) + if (type <= 0 || type > maxtype) return 0; - pt = &policy[nla->nla_type]; + pt = &policy[type]; BUG_ON(pt->type > NLA_TYPE_MAX); @@ -149,7 +149,7 @@ int nla_parse(struct nlattr *tb[], int maxtype, struct nlattr *head, int len, memset(tb, 0, sizeof(struct nlattr *) * (maxtype + 1)); nla_for_each_attr(nla, head, len, rem) { - u16 type = nla->nla_type; + u16 type = nla_type(nla); if (type > 0 && type <= maxtype) { if (policy) { @@ -185,7 +185,7 @@ struct nlattr *nla_find(struct nlattr *head, int len, int attrtype) int rem; nla_for_each_attr(nla, head, len, rem) - if (nla->nla_type == attrtype) + if (nla_type(nla) == attrtype) return nla; return NULL; -- cgit v1.2.3 From a050c33f4a4d5babaf94a8ba6ae7a200135240b3 Mon Sep 17 00:00:00 2001 From: Daniel Lezcano Date: Wed, 12 Sep 2007 14:57:09 +0200 Subject: [NETNS]: Fix bad macro definition. The macro definition is bad. When calling next_net_device with parameter name "dev", the resulting code is: struct net_device *dev = dev and that leads to an unexpected behavior. Especially when llc_core is compiled in, the kernel panics at boot time. The patchset change macro definition with static inline functions as they were defined before. Signed-off-by: Benjamin Thery Signed-off-by: Daniel Lezcano Signed-off-by: David S. Miller --- include/linux/netdevice.h | 35 +++++++++++++++++------------------ 1 file changed, 17 insertions(+), 18 deletions(-) (limited to 'include/linux') diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 407658c64fb6..625240ce27f1 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -41,7 +41,8 @@ #include #include -struct net; +#include + struct vlan_group; struct ethtool_ops; struct netpoll_info; @@ -753,23 +754,21 @@ extern rwlock_t dev_base_lock; /* Device list lock */ list_for_each_entry_continue(d, &(net)->dev_base_head, dev_list) #define net_device_entry(lh) list_entry(lh, struct net_device, dev_list) -#define next_net_device(d) \ -({ \ - struct net_device *dev = d; \ - struct list_head *lh; \ - struct net *net; \ - \ - net = dev->nd_net; \ - lh = dev->dev_list.next; \ - lh == &net->dev_base_head ? NULL : net_device_entry(lh); \ -}) - -#define first_net_device(N) \ -({ \ - struct net *NET = (N); \ - list_empty(&NET->dev_base_head) ? NULL : \ - net_device_entry(NET->dev_base_head.next); \ -}) +static inline struct net_device *next_net_device(struct net_device *dev) +{ + struct list_head *lh; + struct net *net; + + net = dev->nd_net; + lh = dev->dev_list.next; + return lh == &net->dev_base_head ? NULL : net_device_entry(lh); +} + +static inline struct net_device *first_net_device(struct net *net) +{ + return list_empty(&net->dev_base_head) ? NULL : + net_device_entry(net->dev_base_head.next); +} extern int netdev_boot_setup_check(struct net_device *dev); extern unsigned long netdev_boot_base(const char *prefix, int unit); -- cgit v1.2.3 From e08b09983fe9cf379faf1aefdf9164268d4610e7 Mon Sep 17 00:00:00 2001 From: Jesper Dangaard Brouer Date: Wed, 12 Sep 2007 16:36:28 +0200 Subject: [NET_SCHED]: Making rate table lookups more flexible. This is done in order to, add support to changing the rate table to use the upper-boundry L2T (length to time) value. Currently we use the lower-boundry, which result in under-estimating the actual bandwidth usage. Extend the tc_ratespec struct, with two parameters: 1) "cell_align" that allow adjusting the alignment of the rate table. 2) "overhead" that allow adding a packet overhead before the lookup. Signed-off-by: Jesper Dangaard Brouer Acked-by: Patrick McHardy Signed-off-by: David S. Miller --- include/linux/pkt_sched.h | 4 ++-- include/net/sch_generic.h | 4 +++- 2 files changed, 5 insertions(+), 3 deletions(-) (limited to 'include/linux') diff --git a/include/linux/pkt_sched.h b/include/linux/pkt_sched.h index 268c51599eb8..919af93b7059 100644 --- a/include/linux/pkt_sched.h +++ b/include/linux/pkt_sched.h @@ -77,8 +77,8 @@ struct tc_ratespec { unsigned char cell_log; unsigned char __reserved; - unsigned short feature; - short addend; + unsigned short overhead; + short cell_align; unsigned short mpu; __u32 rate; }; diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h index 4ebd615bd013..a02ec9e5fea5 100644 --- a/include/net/sch_generic.h +++ b/include/net/sch_generic.h @@ -307,7 +307,9 @@ drop: */ static inline u32 qdisc_l2t(struct qdisc_rate_table* rtab, unsigned int pktlen) { - int slot = pktlen; + int slot = pktlen + rtab->rate.cell_align + rtab->rate.overhead; + if (slot < 0) + slot = 0; slot >>= rtab->rate.cell_log; if (slot > 255) return (rtab->data[255]*(slot >> 8) + rtab->data[slot & 0xFF]); -- cgit v1.2.3 From 4fabcd7118162e36eea5c53e8895ecc13762bef3 Mon Sep 17 00:00:00 2001 From: Daniel Lezcano Date: Thu, 13 Sep 2007 09:16:29 +0200 Subject: [NETNS]: Fix allnoconfig compilation error. When CONFIG_NET=no, init_net is unresolved because net_namespace.c is not compiled and the include pull init_net definition. This problem was very similar with the ipc namespace where the kernel can be compiled with SYSV ipc out. This patch fix that defining a macro which simply remove init_net initialization from nsproxy namespace aggregator. Compiled and booted on qemu-i386 with CONFIG_NET=no and CONFIG_NET=yes. Signed-off-by: Daniel Lezcano Acked-by: "Eric W. Biederman" Signed-off-by: David S. Miller --- include/linux/init_task.h | 2 +- include/net/net_namespace.h | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/init_task.h b/include/linux/init_task.h index e2c1ffcff62c..513bc3e489f0 100644 --- a/include/linux/init_task.h +++ b/include/linux/init_task.h @@ -79,7 +79,7 @@ extern struct nsproxy init_nsproxy; .nslock = __SPIN_LOCK_UNLOCKED(nsproxy.nslock), \ .uts_ns = &init_uts_ns, \ .mnt_ns = NULL, \ - .net_ns = &init_net, \ + INIT_NET_NS(net_ns) \ INIT_IPC_NS(ipc_ns) \ .user_ns = &init_user_ns, \ } diff --git a/include/net/net_namespace.h b/include/net/net_namespace.h index fac42db7f6d0..3081b6ed35fe 100644 --- a/include/net/net_namespace.h +++ b/include/net/net_namespace.h @@ -28,7 +28,14 @@ struct net { struct hlist_head *dev_index_head; }; +#ifdef CONFIG_NET +/* Init's network namespace */ extern struct net init_net; +#define INIT_NET_NS(net_ns) .net_ns = &init_net, +#else +#define INIT_NET_NS(net_ns) +#endif + extern struct list_head net_namespace_list; extern void __put_net(struct net *net); -- cgit v1.2.3 From 077130c0cf7d5ba1992f5b51b96136d7b1c8aad5 Mon Sep 17 00:00:00 2001 From: "Eric W. Biederman" Date: Thu, 13 Sep 2007 09:18:57 +0200 Subject: [NET]: Fix race when opening a proc file while a network namespace is exiting. The problem: proc_net files remember which network namespace the are against but do not remember hold a reference count (as that would pin the network namespace). So we currently have a small window where the reference count on a network namespace may be incremented when opening a /proc file when it has already gone to zero. To fix this introduce maybe_get_net and get_proc_net. maybe_get_net increments the network namespace reference count only if it is greater then zero, ensuring we don't increment a reference count after it has gone to zero. get_proc_net handles all of the magic to go from a proc inode to the network namespace instance and call maybe_get_net on it. PROC_NET the old accessor is removed so that we don't get confused and use the wrong helper function. Then I fix up the callers to use get_proc_net and handle the case case where get_proc_net returns NULL. In that case I return -ENXIO because effectively the network namespace has already gone away so the files we are trying to access don't exist anymore. Signed-off-by: Eric W. Biederman Acked-by: Paul E. McKenney Signed-off-by: David S. Miller --- fs/proc/proc_net.c | 6 ++++++ include/linux/proc_fs.h | 5 +---- include/net/net_namespace.h | 12 ++++++++++++ net/core/dev.c | 6 +++++- net/core/dev_mcast.c | 6 +++++- net/netlink/af_netlink.c | 6 +++++- net/wireless/wext.c | 6 +++++- 7 files changed, 39 insertions(+), 8 deletions(-) (limited to 'include/linux') diff --git a/fs/proc/proc_net.c b/fs/proc/proc_net.c index 358930a3142a..85cc8e8bb862 100644 --- a/fs/proc/proc_net.c +++ b/fs/proc/proc_net.c @@ -51,6 +51,12 @@ void proc_net_remove(struct net *net, const char *name) } EXPORT_SYMBOL_GPL(proc_net_remove); +struct net *get_proc_net(const struct inode *inode) +{ + return maybe_get_net(PDE_NET(PDE(inode))); +} +EXPORT_SYMBOL_GPL(get_proc_net); + static struct proc_dir_entry *proc_net_shadow; static struct dentry *proc_net_shadow_dentry(struct dentry *parent, diff --git a/include/linux/proc_fs.h b/include/linux/proc_fs.h index 59646705f151..20741f668f7b 100644 --- a/include/linux/proc_fs.h +++ b/include/linux/proc_fs.h @@ -270,10 +270,7 @@ static inline struct net *PDE_NET(struct proc_dir_entry *pde) return pde->parent->data; } -static inline struct net *PROC_NET(const struct inode *inode) -{ - return PDE_NET(PDE(inode)); -} +struct net *get_proc_net(const struct inode *inode); struct proc_maps_private { struct pid *pid; diff --git a/include/net/net_namespace.h b/include/net/net_namespace.h index 3081b6ed35fe..ac8f8304094e 100644 --- a/include/net/net_namespace.h +++ b/include/net/net_namespace.h @@ -46,6 +46,18 @@ static inline struct net *get_net(struct net *net) return net; } +static inline struct net *maybe_get_net(struct net *net) +{ + /* Used when we know struct net exists but we + * aren't guaranteed a previous reference count + * exists. If the reference count is zero this + * function fails and returns NULL. + */ + if (!atomic_inc_not_zero(&net->count)) + net = NULL; + return net; +} + static inline void put_net(struct net *net) { if (atomic_dec_and_test(&net->count)) diff --git a/net/core/dev.c b/net/core/dev.c index d16dcab49c60..666c112efb55 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -2464,7 +2464,11 @@ static int dev_seq_open(struct inode *inode, struct file *file) res = seq_open(file, &dev_seq_ops); if (!res) { seq = file->private_data; - seq->private = get_net(PROC_NET(inode)); + seq->private = get_proc_net(inode); + if (!seq->private) { + seq_release(inode, file); + res = -ENXIO; + } } return res; } diff --git a/net/core/dev_mcast.c b/net/core/dev_mcast.c index 1c4f6198459b..896b0ca5aed7 100644 --- a/net/core/dev_mcast.c +++ b/net/core/dev_mcast.c @@ -246,7 +246,11 @@ static int dev_mc_seq_open(struct inode *inode, struct file *file) res = seq_open(file, &dev_mc_seq_ops); if (!res) { seq = file->private_data; - seq->private = get_net(PROC_NET(inode)); + seq->private = get_proc_net(inode); + if (!seq->private) { + seq_release(inode, file); + res = -ENXIO; + } } return res; } diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c index 3029f865cd61..dc9f8c2ab1d5 100644 --- a/net/netlink/af_netlink.c +++ b/net/netlink/af_netlink.c @@ -1859,7 +1859,11 @@ static int netlink_seq_open(struct inode *inode, struct file *file) seq = file->private_data; seq->private = iter; - iter->net = get_net(PROC_NET(inode)); + iter->net = get_proc_net(inode); + if (!iter->net) { + seq_release_private(inode, file); + return -ENXIO; + } return 0; } diff --git a/net/wireless/wext.c b/net/wireless/wext.c index e8b3409d6c8b..85e5f9dd0d8e 100644 --- a/net/wireless/wext.c +++ b/net/wireless/wext.c @@ -678,7 +678,11 @@ static int wireless_seq_open(struct inode *inode, struct file *file) res = seq_open(file, &wireless_seq_ops); if (!res) { seq = file->private_data; - seq->private = get_net(PROC_NET(inode)); + seq->private = get_proc_net(inode); + if (!seq->private) { + seq_release(inode, file); + res = -ENXIO; + } } return res; } -- cgit v1.2.3 From 234a0ca6f1d67ba4c3c3fc8378bbd98d722468e1 Mon Sep 17 00:00:00 2001 From: Ivo van Doorn Date: Thu, 13 Sep 2007 09:20:42 +0200 Subject: [RFKILL]: Remove IRDA As Dmitry pointed out earlier, rfkill-input.c doesn't support irda because there are no users and we shouldn't add unrequired KEY_ defines. However, RFKILL_TYPE_IRDA was defined in the rfkill.h header file and would confuse people about whether it is implemented or not. This patch removes IRDA support completely, so it can be added whenever a driver wants the feature. Signed-off-by: Ivo van Doorn Signed-off-by: David S. Miller --- include/linux/rfkill.h | 8 +++----- net/rfkill/Kconfig | 2 +- net/rfkill/rfkill.c | 5 +---- 3 files changed, 5 insertions(+), 10 deletions(-) (limited to 'include/linux') diff --git a/include/linux/rfkill.h b/include/linux/rfkill.h index a8a6ea809da0..c4546e15c853 100644 --- a/include/linux/rfkill.h +++ b/include/linux/rfkill.h @@ -31,13 +31,11 @@ * enum rfkill_type - type of rfkill switch. * RFKILL_TYPE_WLAN: switch is no a Wireless network devices. * RFKILL_TYPE_BlUETOOTH: switch is on a bluetooth device. - * RFKILL_TYPE_IRDA: switch is on an infrared devices. */ enum rfkill_type { - RFKILL_TYPE_WLAN = 0, - RFKILL_TYPE_BLUETOOTH = 1, - RFKILL_TYPE_IRDA = 2, - RFKILL_TYPE_MAX = 3, + RFKILL_TYPE_WLAN , + RFKILL_TYPE_BLUETOOTH, + RFKILL_TYPE_MAX, }; enum rfkill_state { diff --git a/net/rfkill/Kconfig b/net/rfkill/Kconfig index 8b31759ee8b0..d28a6d9303e4 100644 --- a/net/rfkill/Kconfig +++ b/net/rfkill/Kconfig @@ -5,7 +5,7 @@ menuconfig RFKILL tristate "RF switch subsystem support" help Say Y here if you want to have control over RF switches - found on many WiFi, Bluetooth and IRDA cards. + found on many WiFi and Bluetooth cards. To compile this driver as a module, choose M here: the module will be called rfkill. diff --git a/net/rfkill/rfkill.c b/net/rfkill/rfkill.c index db3395bfbcfa..50e010272e47 100644 --- a/net/rfkill/rfkill.c +++ b/net/rfkill/rfkill.c @@ -106,9 +106,6 @@ static ssize_t rfkill_type_show(struct device *dev, case RFKILL_TYPE_BLUETOOTH: type = "bluetooth"; break; - case RFKILL_TYPE_IRDA: - type = "irda"; - break; default: BUG(); } @@ -281,7 +278,7 @@ static void rfkill_remove_switch(struct rfkill *rfkill) /** * rfkill_allocate - allocate memory for rfkill structure. * @parent: device that has rf switch on it - * @type: type of the switch (wlan, bluetooth, irda) + * @type: type of the switch (RFKILL_TYPE_*) * * This function should be called by the network driver when it needs * rfkill structure. Once the structure is allocated the driver shoud -- cgit v1.2.3 From e0665486b78b8efb9c25019ad29b4a4c9c1e9dfc Mon Sep 17 00:00:00 2001 From: Ivo van Doorn Date: Thu, 13 Sep 2007 09:21:31 +0200 Subject: [RFKILL]: Add support for ultrawideband This patch will add support for UWB keys to rfkill, support for this has been requested by Inaky. Signed-off-by: Ivo van Doorn Signed-off-by: David S. Miller --- include/linux/input.h | 1 + include/linux/rfkill.h | 2 ++ net/rfkill/rfkill-input.c | 9 +++++++++ net/rfkill/rfkill.c | 3 +++ 4 files changed, 15 insertions(+) (limited to 'include/linux') diff --git a/include/linux/input.h b/include/linux/input.h index 36e00aa6f03b..6eb3aead7f1d 100644 --- a/include/linux/input.h +++ b/include/linux/input.h @@ -360,6 +360,7 @@ struct input_absinfo { #define KEY_BLUETOOTH 237 #define KEY_WLAN 238 +#define KEY_UWB 239 #define KEY_UNKNOWN 240 diff --git a/include/linux/rfkill.h b/include/linux/rfkill.h index c4546e15c853..f9a50dab4168 100644 --- a/include/linux/rfkill.h +++ b/include/linux/rfkill.h @@ -31,10 +31,12 @@ * enum rfkill_type - type of rfkill switch. * RFKILL_TYPE_WLAN: switch is no a Wireless network devices. * RFKILL_TYPE_BlUETOOTH: switch is on a bluetooth device. + * RFKILL_TYPE_UWB: switch is on a Ultra wideband device. */ enum rfkill_type { RFKILL_TYPE_WLAN , RFKILL_TYPE_BLUETOOTH, + RFKILL_TYPE_UWB, RFKILL_TYPE_MAX, }; diff --git a/net/rfkill/rfkill-input.c b/net/rfkill/rfkill-input.c index 9f746be58854..8e4516a5fe32 100644 --- a/net/rfkill/rfkill-input.c +++ b/net/rfkill/rfkill-input.c @@ -81,6 +81,7 @@ static void rfkill_schedule_toggle(struct rfkill_task *task) static DEFINE_RFKILL_TASK(rfkill_wlan, RFKILL_TYPE_WLAN); static DEFINE_RFKILL_TASK(rfkill_bt, RFKILL_TYPE_BLUETOOTH); +static DEFINE_RFKILL_TASK(rfkill_uwb, RFKILL_TYPE_UWB); static void rfkill_event(struct input_handle *handle, unsigned int type, unsigned int code, int down) @@ -93,6 +94,9 @@ static void rfkill_event(struct input_handle *handle, unsigned int type, case KEY_BLUETOOTH: rfkill_schedule_toggle(&rfkill_bt); break; + case KEY_UWB: + rfkill_schedule_toggle(&rfkill_uwb); + break; default: break; } @@ -148,6 +152,11 @@ static const struct input_device_id rfkill_ids[] = { .evbit = { BIT(EV_KEY) }, .keybit = { [LONG(KEY_BLUETOOTH)] = BIT(KEY_BLUETOOTH) }, }, + { + .flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_KEYBIT, + .evbit = { BIT(EV_KEY) }, + .keybit = { [LONG(KEY_UWB)] = BIT(KEY_UWB) }, + }, { } }; diff --git a/net/rfkill/rfkill.c b/net/rfkill/rfkill.c index 50e010272e47..03ed7fd8afe0 100644 --- a/net/rfkill/rfkill.c +++ b/net/rfkill/rfkill.c @@ -106,6 +106,9 @@ static ssize_t rfkill_type_show(struct device *dev, case RFKILL_TYPE_BLUETOOTH: type = "bluetooth"; break; + case RFKILL_TYPE_UWB: + type = "ultrawideband"; + break; default: BUG(); } -- cgit v1.2.3 From 10d024c1b2fd58af8362670d7d6e5ae52fc33353 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Mon, 17 Sep 2007 13:11:17 -0700 Subject: [NET]: Nuke SET_MODULE_OWNER macro. It's been a useless no-op for long enough in 2.6 so I figured it's time to remove it. The number of people that could object because they're maintaining unified 2.4 and 2.6 drivers is probably rather small. [ Handled drivers added by netdev tree and some missed IRDA cases... -DaveM ] Signed-off-by: Ralf Baechle Signed-off-by: Jeff Garzik Signed-off-by: David S. Miller --- drivers/ieee1394/eth1394.c | 1 - drivers/infiniband/hw/amso1100/c2.c | 1 - drivers/infiniband/hw/amso1100/c2_provider.c | 1 - drivers/infiniband/ulp/ipoib/ipoib_main.c | 2 -- drivers/message/fusion/mptlan.c | 2 -- drivers/net/3c501.c | 2 -- drivers/net/3c503.c | 2 -- drivers/net/3c505.c | 2 -- drivers/net/3c507.c | 2 -- drivers/net/3c509.c | 6 ------ drivers/net/3c515.c | 2 -- drivers/net/3c523.c | 1 - drivers/net/3c527.c | 2 -- drivers/net/3c59x.c | 1 - drivers/net/8139cp.c | 1 - drivers/net/8139too.c | 1 - drivers/net/82596.c | 1 - drivers/net/a2065.c | 1 - drivers/net/ac3200.c | 2 -- drivers/net/acenic.c | 1 - drivers/net/amd8111e.c | 1 - drivers/net/apne.c | 1 - drivers/net/appletalk/cops.c | 2 -- drivers/net/appletalk/ipddp.c | 1 - drivers/net/appletalk/ltpc.c | 2 -- drivers/net/arcnet/com90io.c | 2 -- drivers/net/ariadne.c | 1 - drivers/net/arm/at91_ether.c | 1 - drivers/net/arm/ether1.c | 1 - drivers/net/arm/ether3.c | 1 - drivers/net/arm/etherh.c | 1 - drivers/net/at1700.c | 2 -- drivers/net/atarilance.c | 1 - drivers/net/atl1/atl1_main.c | 1 - drivers/net/atp.c | 1 - drivers/net/b44.c | 1 - drivers/net/bfin_mac.c | 1 - drivers/net/bmac.c | 1 - drivers/net/bnx2.c | 1 - drivers/net/bonding/bond_main.c | 2 -- drivers/net/cassini.c | 1 - drivers/net/chelsio/cxgb2.c | 1 - drivers/net/cs89x0.c | 1 - drivers/net/cxgb3/cxgb3_main.c | 1 - drivers/net/de600.c | 1 - drivers/net/de620.c | 2 -- drivers/net/defxx.c | 1 - drivers/net/dgrs.c | 2 -- drivers/net/dl2k.c | 1 - drivers/net/dm9000.c | 1 - drivers/net/dummy.c | 1 - drivers/net/e100.c | 1 - drivers/net/e1000/e1000_main.c | 1 - drivers/net/e1000e/netdev.c | 1 - drivers/net/e2100.c | 2 -- drivers/net/eepro.c | 4 ---- drivers/net/eepro100.c | 1 - drivers/net/eexpress.c | 2 -- drivers/net/ehea/ehea_main.c | 2 -- drivers/net/epic100.c | 1 - drivers/net/eql.c | 2 -- drivers/net/es3210.c | 2 -- drivers/net/eth16i.c | 2 -- drivers/net/ewrk3.c | 1 - drivers/net/fealnx.c | 1 - drivers/net/fec_8xx/fec_main.c | 1 - drivers/net/forcedeth.c | 1 - drivers/net/fs_enet/fs_enet-main.c | 1 - drivers/net/gianfar.c | 1 - drivers/net/hamachi.c | 1 - drivers/net/hamradio/6pack.c | 2 -- drivers/net/hp-plus.c | 2 -- drivers/net/hp.c | 2 -- drivers/net/hp100.c | 5 ----- drivers/net/hydra.c | 1 - drivers/net/ibm_emac/ibm_emac_core.c | 1 - drivers/net/ibmlana.c | 2 -- drivers/net/ibmveth.c | 4 ---- drivers/net/ifb.c | 1 - drivers/net/ioc3-eth.c | 1 - drivers/net/irda/ali-ircc.c | 4 ---- drivers/net/irda/donauboe.c | 1 - drivers/net/irda/irda-usb.c | 1 - drivers/net/irda/irport.c | 2 -- drivers/net/irda/kingsun-sir.c | 1 - drivers/net/irda/ks959-sir.c | 1 - drivers/net/irda/ksdazzle-sir.c | 1 - drivers/net/irda/mcs7780.c | 2 -- drivers/net/irda/nsc-ircc.c | 1 - drivers/net/irda/sir_dev.c | 2 -- drivers/net/irda/smsc-ircc2.c | 2 -- drivers/net/irda/stir4200.c | 1 - drivers/net/irda/via-ircc.c | 3 --- drivers/net/irda/vlsi_ir.c | 2 -- drivers/net/irda/w83977af_ir.c | 3 --- drivers/net/isa-skeleton.c | 2 -- drivers/net/ixgb/ixgb_main.c | 1 - drivers/net/ixgbe/ixgbe_main.c | 1 - drivers/net/ixp2000/enp2611.c | 1 - drivers/net/jazzsonic.c | 1 - drivers/net/lance.c | 1 - drivers/net/lguest_net.c | 2 -- drivers/net/lne390.c | 2 -- drivers/net/mac8390.c | 2 -- drivers/net/mac89x0.c | 2 -- drivers/net/macb.c | 1 - drivers/net/mace.c | 1 - drivers/net/macmace.c | 1 - drivers/net/macsonic.c | 1 - drivers/net/mv643xx_eth.c | 1 - drivers/net/mvme147.c | 2 -- drivers/net/myri_sbus.c | 1 - drivers/net/natsemi.c | 1 - drivers/net/ne-h8300.c | 2 -- drivers/net/ne.c | 2 -- drivers/net/ne2.c | 2 -- drivers/net/ne2k-pci.c | 1 - drivers/net/ne3210.c | 1 - drivers/net/netx-eth.c | 1 - drivers/net/netxen/netxen_nic_main.c | 1 - drivers/net/ni5010.c | 2 -- drivers/net/ni52.c | 2 -- drivers/net/ni65.c | 1 - drivers/net/ns83820.c | 1 - drivers/net/pasemi_mac.c | 1 - drivers/net/pci-skeleton.c | 1 - drivers/net/pcmcia/3c589_cs.c | 1 - drivers/net/pcmcia/axnet_cs.c | 3 --- drivers/net/pcmcia/fmvj18x_cs.c | 1 - drivers/net/pcmcia/nmclan_cs.c | 1 - drivers/net/pcmcia/pcnet_cs.c | 1 - drivers/net/pcmcia/smc91c92_cs.c | 1 - drivers/net/pcmcia/xirc2ps_cs.c | 1 - drivers/net/pcnet32.c | 1 - drivers/net/plip.c | 1 - drivers/net/ps3_gelic_net.c | 1 - drivers/net/qla3xxx.c | 1 - drivers/net/r8169.c | 1 - drivers/net/rionet.c | 2 -- drivers/net/rrunner.c | 1 - drivers/net/s2io.c | 1 - drivers/net/sb1000.c | 1 - drivers/net/shaper.c | 2 -- drivers/net/sis190.c | 1 - drivers/net/sis900.c | 1 - drivers/net/sk98lin/skge.c | 1 - drivers/net/skfp/skfddi.c | 1 - drivers/net/skge.c | 1 - drivers/net/sky2.c | 1 - drivers/net/slip.c | 2 -- drivers/net/smc-mca.c | 1 - drivers/net/smc-ultra.c | 2 -- drivers/net/smc-ultra32.c | 2 -- drivers/net/smc911x.c | 1 - drivers/net/smc9194.c | 2 -- drivers/net/smc91x.c | 1 - drivers/net/spider_net.c | 1 - drivers/net/starfire.c | 1 - drivers/net/stnic.c | 1 - drivers/net/sun3_82586.c | 1 - drivers/net/sun3lance.c | 1 - drivers/net/sunbmac.c | 1 - drivers/net/sundance.c | 1 - drivers/net/sungem.c | 1 - drivers/net/sunhme.c | 2 -- drivers/net/sunlance.c | 1 - drivers/net/sunqe.c | 1 - drivers/net/tc35815.c | 1 - drivers/net/tg3.c | 1 - drivers/net/tlan.c | 1 - drivers/net/tokenring/3c359.c | 1 - drivers/net/tokenring/abyss.c | 2 -- drivers/net/tokenring/lanstreamer.c | 1 - drivers/net/tokenring/madgemc.c | 1 - drivers/net/tokenring/olympic.c | 1 - drivers/net/tokenring/proteon.c | 1 - drivers/net/tokenring/skisa.c | 1 - drivers/net/tokenring/smctr.c | 2 -- drivers/net/tokenring/tmspci.c | 1 - drivers/net/tsi108_eth.c | 1 - drivers/net/tulip/de2104x.c | 1 - drivers/net/tulip/de4x5.c | 1 - drivers/net/tulip/dmfe.c | 1 - drivers/net/tulip/tulip_core.c | 1 - drivers/net/tulip/uli526x.c | 1 - drivers/net/tulip/winbond-840.c | 1 - drivers/net/tulip/xircom_cb.c | 1 - drivers/net/tulip/xircom_tulip_cb.c | 1 - drivers/net/tun.c | 1 - drivers/net/typhoon.c | 1 - drivers/net/ucc_geth.c | 1 - drivers/net/usb/kaweth.c | 2 -- drivers/net/usb/pegasus.c | 1 - drivers/net/usb/rtl8150.c | 1 - drivers/net/usb/usbnet.c | 1 - drivers/net/via-rhine.c | 1 - drivers/net/via-velocity.c | 1 - drivers/net/wan/c101.c | 1 - drivers/net/wan/cycx_x25.c | 1 - drivers/net/wan/dscc4.c | 1 - drivers/net/wan/hostess_sv11.c | 2 -- drivers/net/wan/lapbether.c | 1 - drivers/net/wan/lmc/lmc_main.c | 1 - drivers/net/wan/n2.c | 1 - drivers/net/wan/pc300too.c | 1 - drivers/net/wan/pci200syn.c | 1 - drivers/net/wan/sbni.c | 2 -- drivers/net/wan/sdla.c | 1 - drivers/net/wan/wanxl.c | 1 - drivers/net/wd.c | 2 -- drivers/net/wireless/airo.c | 1 - drivers/net/wireless/airport.c | 1 - drivers/net/wireless/arlan-main.c | 2 -- drivers/net/wireless/atmel.c | 1 - drivers/net/wireless/bcm43xx/bcm43xx_main.c | 1 - drivers/net/wireless/ipw2100.c | 2 -- drivers/net/wireless/ipw2200.c | 1 - drivers/net/wireless/libertas/main.c | 4 ---- drivers/net/wireless/netwave_cs.c | 1 - drivers/net/wireless/orinoco_cs.c | 1 - drivers/net/wireless/orinoco_nortel.c | 1 - drivers/net/wireless/orinoco_pci.c | 1 - drivers/net/wireless/orinoco_plx.c | 1 - drivers/net/wireless/orinoco_tmd.c | 1 - drivers/net/wireless/prism54/islpci_dev.c | 1 - drivers/net/wireless/ray_cs.c | 1 - drivers/net/wireless/spectrum_cs.c | 1 - drivers/net/wireless/strip.c | 2 -- drivers/net/wireless/wavelan.c | 1 - drivers/net/wireless/wavelan_cs.c | 1 - drivers/net/wireless/wl3501_cs.c | 2 -- drivers/net/wireless/zd1211rw/zd_netdev.c | 1 - drivers/net/xen-netfront.c | 1 - drivers/net/yellowfin.c | 1 - drivers/net/znet.c | 2 -- drivers/net/zorro8390.c | 1 - drivers/s390/net/claw.c | 1 - drivers/s390/net/ctcmain.c | 1 - drivers/s390/net/lcs.c | 1 - drivers/s390/net/netiucv.c | 1 - drivers/s390/net/qeth_main.c | 1 - drivers/usb/gadget/ether.c | 1 - include/linux/netdevice.h | 1 - net/8021q/vlan.c | 2 -- net/bridge/br_device.c | 1 - net/ipv4/ip_gre.c | 1 - net/ipv4/ipip.c | 2 -- net/ipv6/ip6_tunnel.c | 1 - net/ipv6/sit.c | 1 - net/irda/irlan/irlan_eth.c | 2 -- net/sched/sch_teql.c | 1 - 251 files changed, 341 deletions(-) (limited to 'include/linux') diff --git a/drivers/ieee1394/eth1394.c b/drivers/ieee1394/eth1394.c index 3a9d7e2d4de6..33b80817d68c 100644 --- a/drivers/ieee1394/eth1394.c +++ b/drivers/ieee1394/eth1394.c @@ -598,7 +598,6 @@ static void ether1394_add_host(struct hpsb_host *host) goto out; } - SET_MODULE_OWNER(dev); SET_NETDEV_DEV(dev, &host->device); priv = netdev_priv(dev); diff --git a/drivers/infiniband/hw/amso1100/c2.c b/drivers/infiniband/hw/amso1100/c2.c index 0aecea67f3e6..f283a9f0c23b 100644 --- a/drivers/infiniband/hw/amso1100/c2.c +++ b/drivers/infiniband/hw/amso1100/c2.c @@ -886,7 +886,6 @@ static struct net_device *c2_devinit(struct c2_dev *c2dev, return NULL; } - SET_MODULE_OWNER(netdev); SET_NETDEV_DEV(netdev, &c2dev->pcidev->dev); netdev->open = c2_up; diff --git a/drivers/infiniband/hw/amso1100/c2_provider.c b/drivers/infiniband/hw/amso1100/c2_provider.c index 997cf1530762..7a6cece6ea9d 100644 --- a/drivers/infiniband/hw/amso1100/c2_provider.c +++ b/drivers/infiniband/hw/amso1100/c2_provider.c @@ -715,7 +715,6 @@ static int c2_pseudo_change_mtu(struct net_device *netdev, int new_mtu) static void setup(struct net_device *netdev) { - SET_MODULE_OWNER(netdev); netdev->open = c2_pseudo_up; netdev->stop = c2_pseudo_down; netdev->hard_start_xmit = c2_pseudo_xmit_frame; diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c index a59ff07ec3cd..b1c3d6cd8eba 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_main.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c @@ -978,8 +978,6 @@ static void ipoib_setup(struct net_device *dev) netif_carrier_off(dev); - SET_MODULE_OWNER(dev); - priv->dev = dev; spin_lock_init(&priv->lock); diff --git a/drivers/message/fusion/mptlan.c b/drivers/message/fusion/mptlan.c index 01fc397fdd97..3da4c37846ec 100644 --- a/drivers/message/fusion/mptlan.c +++ b/drivers/message/fusion/mptlan.c @@ -1427,8 +1427,6 @@ mpt_register_lan_device (MPT_ADAPTER *mpt_dev, int pnum) dlprintk((KERN_INFO MYNAM ": Finished registering dev " "and setting initial values\n")); - SET_MODULE_OWNER(dev); - if (register_netdev(dev) != 0) { free_netdev(dev); dev = NULL; diff --git a/drivers/net/3c501.c b/drivers/net/3c501.c index 4bee99ba7dbb..98e0bc4628a2 100644 --- a/drivers/net/3c501.c +++ b/drivers/net/3c501.c @@ -174,8 +174,6 @@ struct net_device * __init el1_probe(int unit) mem_start = dev->mem_start & 7; } - SET_MODULE_OWNER(dev); - if (io > 0x1ff) { /* Check a single specified location. */ err = el1_probe1(dev, io); } else if (io != 0) { diff --git a/drivers/net/3c503.c b/drivers/net/3c503.c index bc7e906571d3..f9e7ffbcb772 100644 --- a/drivers/net/3c503.c +++ b/drivers/net/3c503.c @@ -95,8 +95,6 @@ static int __init do_el2_probe(struct net_device *dev) int base_addr = dev->base_addr; int irq = dev->irq; - SET_MODULE_OWNER(dev); - if (base_addr > 0x1ff) /* Check a single specified location. */ return el2_probe1(dev, base_addr); else if (base_addr != 0) /* Don't probe at all. */ diff --git a/drivers/net/3c505.c b/drivers/net/3c505.c index acede307c05d..c05bb3fc57a2 100644 --- a/drivers/net/3c505.c +++ b/drivers/net/3c505.c @@ -1387,8 +1387,6 @@ static int __init elplus_setup(struct net_device *dev) unsigned long cookie = 0; int err = -ENODEV; - SET_MODULE_OWNER(dev); - /* * setup adapter structure */ diff --git a/drivers/net/3c507.c b/drivers/net/3c507.c index eed4299dc426..fac6edff2b8b 100644 --- a/drivers/net/3c507.c +++ b/drivers/net/3c507.c @@ -327,8 +327,6 @@ struct net_device * __init el16_probe(int unit) mem_start = dev->mem_start & 15; } - SET_MODULE_OWNER(dev); - if (io > 0x1ff) /* Check a single specified location. */ err = el16_probe1(dev, io); else if (io != 0) diff --git a/drivers/net/3c509.c b/drivers/net/3c509.c index 127f60841b10..7466987d8451 100644 --- a/drivers/net/3c509.c +++ b/drivers/net/3c509.c @@ -432,7 +432,6 @@ __again: return -ENOMEM; } - SET_MODULE_OWNER(dev); SET_NETDEV_DEV(dev, &idev->dev); pnp_cards++; @@ -524,8 +523,6 @@ no_pnp: if (!dev) return -ENOMEM; - SET_MODULE_OWNER(dev); - netdev_boot_setup_check(dev); /* Set passed-in IRQ or I/O Addr. */ @@ -644,7 +641,6 @@ static int __init el3_mca_probe(struct device *device) return -ENOMEM; } - SET_MODULE_OWNER(dev); netdev_boot_setup_check(dev); memcpy(dev->dev_addr, phys_addr, sizeof(phys_addr)); @@ -704,8 +700,6 @@ static int __init el3_eisa_probe (struct device *device) return -ENOMEM; } - SET_MODULE_OWNER(dev); - netdev_boot_setup_check(dev); memcpy(dev->dev_addr, phys_addr, sizeof(phys_addr)); diff --git a/drivers/net/3c515.c b/drivers/net/3c515.c index 290166d5e7d1..38a2ebea9b45 100644 --- a/drivers/net/3c515.c +++ b/drivers/net/3c515.c @@ -501,8 +501,6 @@ static struct net_device *corkscrew_scan(int unit) netdev_boot_setup_check(dev); } - SET_MODULE_OWNER(dev); - #ifdef __ISAPNP__ if(nopnp == 1) goto no_pnp; diff --git a/drivers/net/3c523.c b/drivers/net/3c523.c index ab18343e58ef..10852b2a40ab 100644 --- a/drivers/net/3c523.c +++ b/drivers/net/3c523.c @@ -423,7 +423,6 @@ static int __init do_elmc_probe(struct net_device *dev) int retval; struct priv *pr = dev->priv; - SET_MODULE_OWNER(dev); if (MCA_bus == 0) { return -ENODEV; } diff --git a/drivers/net/3c527.c b/drivers/net/3c527.c index c7b571be20e0..5b5f44cdfc1d 100644 --- a/drivers/net/3c527.c +++ b/drivers/net/3c527.c @@ -257,8 +257,6 @@ struct net_device *__init mc32_probe(int unit) if (unit >= 0) sprintf(dev->name, "eth%d", unit); - SET_MODULE_OWNER(dev); - /* Do not check any supplied i/o locations. POS registers usually don't fail :) */ diff --git a/drivers/net/3c59x.c b/drivers/net/3c59x.c index 29e558913eb5..ad0f6a729d29 100644 --- a/drivers/net/3c59x.c +++ b/drivers/net/3c59x.c @@ -1036,7 +1036,6 @@ static int __devinit vortex_probe1(struct device *gendev, printk (KERN_ERR PFX "unable to allocate etherdev, aborting\n"); goto out; } - SET_MODULE_OWNER(dev); SET_NETDEV_DEV(dev, gendev); vp = netdev_priv(dev); diff --git a/drivers/net/8139cp.c b/drivers/net/8139cp.c index 2dec3d6ae01a..30310ed9f75f 100644 --- a/drivers/net/8139cp.c +++ b/drivers/net/8139cp.c @@ -1845,7 +1845,6 @@ static int cp_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) dev = alloc_etherdev(sizeof(struct cp_private)); if (!dev) return -ENOMEM; - SET_MODULE_OWNER(dev); SET_NETDEV_DEV(dev, &pdev->dev); cp = netdev_priv(dev); diff --git a/drivers/net/8139too.c b/drivers/net/8139too.c index 7ba470ee2175..28c1aaf1fe1d 100644 --- a/drivers/net/8139too.c +++ b/drivers/net/8139too.c @@ -766,7 +766,6 @@ static int __devinit rtl8139_init_board (struct pci_dev *pdev, dev_err(&pdev->dev, "Unable to alloc new net device\n"); return -ENOMEM; } - SET_MODULE_OWNER(dev); SET_NETDEV_DEV(dev, &pdev->dev); tp = netdev_priv(dev); diff --git a/drivers/net/82596.c b/drivers/net/82596.c index d915837193cc..43dffdca708f 100644 --- a/drivers/net/82596.c +++ b/drivers/net/82596.c @@ -1234,7 +1234,6 @@ struct net_device * __init i82596_probe(int unit) DEB(DEB_PROBE,printk(KERN_INFO "%s", version)); /* The 82596-specific entries in the device structure. */ - SET_MODULE_OWNER(dev); dev->open = i596_open; dev->stop = i596_close; dev->hard_start_xmit = i596_start_xmit; diff --git a/drivers/net/a2065.c b/drivers/net/a2065.c index a45de6975bfe..fa0c6cb3d798 100644 --- a/drivers/net/a2065.c +++ b/drivers/net/a2065.c @@ -746,7 +746,6 @@ static int __devinit a2065_init_one(struct zorro_dev *z, return -ENOMEM; } - SET_MODULE_OWNER(dev); priv = netdev_priv(dev); r1->name = dev->name; diff --git a/drivers/net/ac3200.c b/drivers/net/ac3200.c index 644c408515df..65b2de56ed22 100644 --- a/drivers/net/ac3200.c +++ b/drivers/net/ac3200.c @@ -103,8 +103,6 @@ static int __init do_ac3200_probe(struct net_device *dev) int irq = dev->irq; int mem_start = dev->mem_start; - SET_MODULE_OWNER(dev); - if (ioaddr > 0x1ff) /* Check a single specified location. */ return ac_probe1(ioaddr, dev); else if (ioaddr > 0) /* Don't probe at all. */ diff --git a/drivers/net/acenic.c b/drivers/net/acenic.c index 62e660a79387..ca00f41e4d85 100644 --- a/drivers/net/acenic.c +++ b/drivers/net/acenic.c @@ -465,7 +465,6 @@ static int __devinit acenic_probe_one(struct pci_dev *pdev, return -ENOMEM; } - SET_MODULE_OWNER(dev); SET_NETDEV_DEV(dev, &pdev->dev); ap = dev->priv; diff --git a/drivers/net/amd8111e.c b/drivers/net/amd8111e.c index cf06fc067e92..afb60a5927ae 100644 --- a/drivers/net/amd8111e.c +++ b/drivers/net/amd8111e.c @@ -1982,7 +1982,6 @@ static int __devinit amd8111e_probe_one(struct pci_dev *pdev, goto err_free_reg; } - SET_MODULE_OWNER(dev); SET_NETDEV_DEV(dev, &pdev->dev); #if AMD8111E_VLAN_TAG_USED diff --git a/drivers/net/apne.c b/drivers/net/apne.c index 954191119d35..b073810f9fd8 100644 --- a/drivers/net/apne.c +++ b/drivers/net/apne.c @@ -148,7 +148,6 @@ struct net_device * __init apne_probe(int unit) sprintf(dev->name, "eth%d", unit); netdev_boot_setup_check(dev); } - SET_MODULE_OWNER(dev); /* disable pcmcia irq for readtuple */ pcmcia_disable_irq(); diff --git a/drivers/net/appletalk/cops.c b/drivers/net/appletalk/cops.c index da6ffa8cd81e..c4b560d42a67 100644 --- a/drivers/net/appletalk/cops.c +++ b/drivers/net/appletalk/cops.c @@ -235,8 +235,6 @@ struct net_device * __init cops_probe(int unit) base_addr = dev->base_addr = io; } - SET_MODULE_OWNER(dev); - if (base_addr > 0x1ff) { /* Check a single specified location. */ err = cops_probe1(dev, base_addr); } else if (base_addr != 0) { /* Don't probe at all. */ diff --git a/drivers/net/appletalk/ipddp.c b/drivers/net/appletalk/ipddp.c index f22e46dfd770..56cb96794026 100644 --- a/drivers/net/appletalk/ipddp.c +++ b/drivers/net/appletalk/ipddp.c @@ -65,7 +65,6 @@ static struct net_device * __init ipddp_init(void) if (!dev) return ERR_PTR(-ENOMEM); - SET_MODULE_OWNER(dev); strcpy(dev->name, "ipddp%d"); if (version_printed++ == 0) diff --git a/drivers/net/appletalk/ltpc.c b/drivers/net/appletalk/ltpc.c index 6a6cbd331a16..cb4744e56905 100644 --- a/drivers/net/appletalk/ltpc.c +++ b/drivers/net/appletalk/ltpc.c @@ -1046,8 +1046,6 @@ struct net_device * __init ltpc_probe(void) if (!dev) goto out; - SET_MODULE_OWNER(dev); - /* probe for the I/O port address */ if (io != 0x240 && request_region(0x220,8,"ltpc")) { diff --git a/drivers/net/arcnet/com90io.c b/drivers/net/arcnet/com90io.c index 1f0302735416..6599f1046c7b 100644 --- a/drivers/net/arcnet/com90io.c +++ b/drivers/net/arcnet/com90io.c @@ -398,8 +398,6 @@ static int __init com90io_init(void) if (!dev) return -ENOMEM; - SET_MODULE_OWNER(dev); - dev->base_addr = io; dev->irq = irq; if (dev->irq == 2) diff --git a/drivers/net/ariadne.c b/drivers/net/ariadne.c index bc5a38a6705f..2c020a36177e 100644 --- a/drivers/net/ariadne.c +++ b/drivers/net/ariadne.c @@ -183,7 +183,6 @@ static int __devinit ariadne_init_one(struct zorro_dev *z, return -ENOMEM; } - SET_MODULE_OWNER(dev); priv = netdev_priv(dev); r1->name = dev->name; diff --git a/drivers/net/arm/at91_ether.c b/drivers/net/arm/at91_ether.c index ef2cc80256a3..619810a01e5b 100644 --- a/drivers/net/arm/at91_ether.c +++ b/drivers/net/arm/at91_ether.c @@ -986,7 +986,6 @@ static int __init at91ether_setup(unsigned long phy_type, unsigned short phy_add dev->base_addr = AT91_VA_BASE_EMAC; dev->irq = AT91RM9200_ID_EMAC; - SET_MODULE_OWNER(dev); /* Install the interrupt handler */ if (request_irq(dev->irq, at91ether_interrupt, 0, dev->name, dev)) { diff --git a/drivers/net/arm/ether1.c b/drivers/net/arm/ether1.c index 80f33b6d5713..6ec8a587c1d2 100644 --- a/drivers/net/arm/ether1.c +++ b/drivers/net/arm/ether1.c @@ -1009,7 +1009,6 @@ ether1_probe(struct expansion_card *ec, const struct ecard_id *id) goto release; } - SET_MODULE_OWNER(dev); SET_NETDEV_DEV(dev, &ec->dev); dev->irq = ec->irq; diff --git a/drivers/net/arm/ether3.c b/drivers/net/arm/ether3.c index 3805506a3ab8..4a914748c0e4 100644 --- a/drivers/net/arm/ether3.c +++ b/drivers/net/arm/ether3.c @@ -789,7 +789,6 @@ ether3_probe(struct expansion_card *ec, const struct ecard_id *id) goto release; } - SET_MODULE_OWNER(dev); SET_NETDEV_DEV(dev, &ec->dev); priv(dev)->base = ecardm_iomap(ec, ECARD_RES_MEMC, 0, 0); diff --git a/drivers/net/arm/etherh.c b/drivers/net/arm/etherh.c index 0d37d9d1fd78..5d093b3ddcd4 100644 --- a/drivers/net/arm/etherh.c +++ b/drivers/net/arm/etherh.c @@ -661,7 +661,6 @@ etherh_probe(struct expansion_card *ec, const struct ecard_id *id) goto release; } - SET_MODULE_OWNER(dev); SET_NETDEV_DEV(dev, &ec->dev); dev->open = etherh_open; diff --git a/drivers/net/at1700.c b/drivers/net/at1700.c index bed8e0ebaf19..d20148e69fa1 100644 --- a/drivers/net/at1700.c +++ b/drivers/net/at1700.c @@ -225,8 +225,6 @@ struct net_device * __init at1700_probe(int unit) dev->irq = irq; } - SET_MODULE_OWNER(dev); - if (io > 0x1ff) { /* Check a single specified location. */ err = at1700_probe1(dev, io); } else if (io != 0) { /* Don't probe at all. */ diff --git a/drivers/net/atarilance.c b/drivers/net/atarilance.c index dfa8b9ba4c80..97cca505cf90 100644 --- a/drivers/net/atarilance.c +++ b/drivers/net/atarilance.c @@ -390,7 +390,6 @@ struct net_device * __init atarilance_probe(int unit) sprintf(dev->name, "eth%d", unit); netdev_boot_setup_check(dev); } - SET_MODULE_OWNER(dev); for( i = 0; i < N_LANCE_ADDR; ++i ) { if (lance_probe1( dev, &lance_addr_list[i] )) { diff --git a/drivers/net/atl1/atl1_main.c b/drivers/net/atl1/atl1_main.c index 469ff95be559..e1a9223d0c18 100644 --- a/drivers/net/atl1/atl1_main.c +++ b/drivers/net/atl1/atl1_main.c @@ -2234,7 +2234,6 @@ static int __devinit atl1_probe(struct pci_dev *pdev, err = -ENOMEM; goto err_alloc_etherdev; } - SET_MODULE_OWNER(netdev); SET_NETDEV_DEV(netdev, &pdev->dev); pci_set_drvdata(pdev, netdev); diff --git a/drivers/net/atp.c b/drivers/net/atp.c index 82d78ff8399b..6020d5ec38b9 100644 --- a/drivers/net/atp.c +++ b/drivers/net/atp.c @@ -299,7 +299,6 @@ static int __init atp_probe1(long ioaddr) dev = alloc_etherdev(sizeof(struct net_local)); if (!dev) return -ENOMEM; - SET_MODULE_OWNER(dev); /* Find the IRQ used by triggering an interrupt. */ write_reg_byte(ioaddr, CMR2, 0x01); /* No accept mode, IRQ out. */ diff --git a/drivers/net/b44.c b/drivers/net/b44.c index b92b3e25c42a..6d193705a3bc 100644 --- a/drivers/net/b44.c +++ b/drivers/net/b44.c @@ -2151,7 +2151,6 @@ static int __devinit b44_init_one(struct pci_dev *pdev, goto err_out_free_res; } - SET_MODULE_OWNER(dev); SET_NETDEV_DEV(dev,&pdev->dev); /* No interesting netdevice features in this card... */ diff --git a/drivers/net/bfin_mac.c b/drivers/net/bfin_mac.c index 3354c534335d..e5bbcbe8de5f 100644 --- a/drivers/net/bfin_mac.c +++ b/drivers/net/bfin_mac.c @@ -941,7 +941,6 @@ static int bfin_mac_probe(struct platform_device *pdev) return -ENOMEM; } - SET_MODULE_OWNER(ndev); SET_NETDEV_DEV(ndev, &pdev->dev); platform_set_drvdata(pdev, ndev); diff --git a/drivers/net/bmac.c b/drivers/net/bmac.c index 1eb95b603004..ee157f5a5dbc 100644 --- a/drivers/net/bmac.c +++ b/drivers/net/bmac.c @@ -1291,7 +1291,6 @@ static int __devinit bmac_probe(struct macio_dev *mdev, const struct of_device_i } bp = netdev_priv(dev); - SET_MODULE_OWNER(dev); SET_NETDEV_DEV(dev, &mdev->ofdev.dev); macio_set_drvdata(mdev, dev); diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c index ab028ad04235..61debba873ac 100644 --- a/drivers/net/bnx2.c +++ b/drivers/net/bnx2.c @@ -6474,7 +6474,6 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev) u32 reg; u64 dma_mask, persist_dma_mask; - SET_MODULE_OWNER(dev); SET_NETDEV_DEV(dev, &pdev->dev); bp = netdev_priv(dev); diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 559fe9437e0b..88ff72ac9b0a 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -4674,8 +4674,6 @@ int bond_create(char *name, struct bond_params *params, struct bonding **newbond goto out_netdev; } - SET_MODULE_OWNER(bond_dev); - res = register_netdevice(bond_dev); if (res < 0) { goto out_bond; diff --git a/drivers/net/cassini.c b/drivers/net/cassini.c index 13f14df21e6e..f44f3d2a4b4e 100644 --- a/drivers/net/cassini.c +++ b/drivers/net/cassini.c @@ -4900,7 +4900,6 @@ static int __devinit cas_init_one(struct pci_dev *pdev, err = -ENOMEM; goto err_out_disable_pdev; } - SET_MODULE_OWNER(dev); SET_NETDEV_DEV(dev, &pdev->dev); err = pci_request_regions(pdev, dev->name); diff --git a/drivers/net/chelsio/cxgb2.c b/drivers/net/chelsio/cxgb2.c index 593736c7550d..884aa0cd0006 100644 --- a/drivers/net/chelsio/cxgb2.c +++ b/drivers/net/chelsio/cxgb2.c @@ -1036,7 +1036,6 @@ static int __devinit init_one(struct pci_dev *pdev, goto out_free_dev; } - SET_MODULE_OWNER(netdev); SET_NETDEV_DEV(netdev, &pdev->dev); if (!adapter) { diff --git a/drivers/net/cs89x0.c b/drivers/net/cs89x0.c index 9774bb1b3e80..2b4c92193912 100644 --- a/drivers/net/cs89x0.c +++ b/drivers/net/cs89x0.c @@ -517,7 +517,6 @@ cs89x0_probe1(struct net_device *dev, int ioaddr, int modular) int eeprom_buff[CHKSUM_LEN]; int retval; - SET_MODULE_OWNER(dev); /* Initialize the device structure. */ if (!modular) { memset(lp, 0, sizeof(*lp)); diff --git a/drivers/net/cxgb3/cxgb3_main.c b/drivers/net/cxgb3/cxgb3_main.c index a6723ae79bdd..19937498589d 100644 --- a/drivers/net/cxgb3/cxgb3_main.c +++ b/drivers/net/cxgb3/cxgb3_main.c @@ -2465,7 +2465,6 @@ static int __devinit init_one(struct pci_dev *pdev, goto out_free_dev; } - SET_MODULE_OWNER(netdev); SET_NETDEV_DEV(netdev, &pdev->dev); adapter->port[i] = netdev; diff --git a/drivers/net/de600.c b/drivers/net/de600.c index dae97b860daa..5dd0d9c0eac9 100644 --- a/drivers/net/de600.c +++ b/drivers/net/de600.c @@ -394,7 +394,6 @@ static struct net_device * __init de600_probe(void) if (!dev) return ERR_PTR(-ENOMEM); - SET_MODULE_OWNER(dev); if (!request_region(DE600_IO, 3, "de600")) { printk(KERN_WARNING "DE600: port 0x%x busy\n", DE600_IO); diff --git a/drivers/net/de620.c b/drivers/net/de620.c index dc4892426174..a92c207b8839 100644 --- a/drivers/net/de620.c +++ b/drivers/net/de620.c @@ -823,8 +823,6 @@ struct net_device * __init de620_probe(int unit) if (!dev) goto out; - SET_MODULE_OWNER(dev); - spin_lock_init(&de620_lock); /* diff --git a/drivers/net/defxx.c b/drivers/net/defxx.c index 9c8e3f9f5e58..b07613e61f53 100644 --- a/drivers/net/defxx.c +++ b/drivers/net/defxx.c @@ -539,7 +539,6 @@ static int __devinit dfx_register(struct device *bdev) goto err_out; } - SET_MODULE_OWNER(dev); SET_NETDEV_DEV(dev, bdev); bp = netdev_priv(dev); diff --git a/drivers/net/dgrs.c b/drivers/net/dgrs.c index df62c0232f36..ddedb76303d5 100644 --- a/drivers/net/dgrs.c +++ b/drivers/net/dgrs.c @@ -1272,7 +1272,6 @@ dgrs_found_device( priv->chan = 1; priv->devtbl[0] = dev; - SET_MODULE_OWNER(dev); SET_NETDEV_DEV(dev, pdev); ret = dgrs_probe1(dev); @@ -1320,7 +1319,6 @@ dgrs_found_device( if (ret) goto fail; - SET_MODULE_OWNER(devN); SET_NETDEV_DEV(dev, pdev); ret = register_netdev(devN); diff --git a/drivers/net/dl2k.c b/drivers/net/dl2k.c index ca21a1888ffa..12486e13b85b 100644 --- a/drivers/net/dl2k.c +++ b/drivers/net/dl2k.c @@ -116,7 +116,6 @@ rio_probe1 (struct pci_dev *pdev, const struct pci_device_id *ent) err = -ENOMEM; goto err_out_res; } - SET_MODULE_OWNER (dev); SET_NETDEV_DEV(dev, &pdev->dev); #ifdef MEM_MAPPING diff --git a/drivers/net/dm9000.c b/drivers/net/dm9000.c index 738aa5906514..857eb366bb11 100644 --- a/drivers/net/dm9000.c +++ b/drivers/net/dm9000.c @@ -416,7 +416,6 @@ dm9000_probe(struct platform_device *pdev) return -ENOMEM; } - SET_MODULE_OWNER(ndev); SET_NETDEV_DEV(ndev, &pdev->dev); PRINTK2("dm9000_probe()"); diff --git a/drivers/net/dummy.c b/drivers/net/dummy.c index 756a6bcb038d..84e14f397d9a 100644 --- a/drivers/net/dummy.c +++ b/drivers/net/dummy.c @@ -71,7 +71,6 @@ static void dummy_setup(struct net_device *dev) dev->change_mtu = NULL; dev->flags |= IFF_NOARP; dev->flags &= ~IFF_MULTICAST; - SET_MODULE_OWNER(dev); random_ether_addr(dev->dev_addr); } diff --git a/drivers/net/e100.c b/drivers/net/e100.c index 10907f158bac..f9aa13e04ada 100644 --- a/drivers/net/e100.c +++ b/drivers/net/e100.c @@ -2604,7 +2604,6 @@ static int __devinit e100_probe(struct pci_dev *pdev, goto err_out_free_res; } - SET_MODULE_OWNER(netdev); SET_NETDEV_DEV(netdev, &pdev->dev); if (use_io) diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c index 723568d6e44a..7befb706ad55 100644 --- a/drivers/net/e1000/e1000_main.c +++ b/drivers/net/e1000/e1000_main.c @@ -897,7 +897,6 @@ e1000_probe(struct pci_dev *pdev, if (!netdev) goto err_alloc_etherdev; - SET_MODULE_OWNER(netdev); SET_NETDEV_DEV(netdev, &pdev->dev); pci_set_drvdata(pdev, netdev); diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c index eeb40ccbcb22..885d9467f40d 100644 --- a/drivers/net/e1000e/netdev.c +++ b/drivers/net/e1000e/netdev.c @@ -4040,7 +4040,6 @@ static int __devinit e1000_probe(struct pci_dev *pdev, if (!netdev) goto err_alloc_etherdev; - SET_MODULE_OWNER(netdev); SET_NETDEV_DEV(netdev, &pdev->dev); pci_set_drvdata(pdev, netdev); diff --git a/drivers/net/e2100.c b/drivers/net/e2100.c index b2b0a96218ca..6390f51ea6fb 100644 --- a/drivers/net/e2100.c +++ b/drivers/net/e2100.c @@ -124,8 +124,6 @@ static int __init do_e2100_probe(struct net_device *dev) int base_addr = dev->base_addr; int irq = dev->irq; - SET_MODULE_OWNER(dev); - if (base_addr > 0x1ff) /* Check a single specified location. */ return e21_probe1(dev, base_addr); else if (base_addr != 0) /* Don't probe at all. */ diff --git a/drivers/net/eepro.c b/drivers/net/eepro.c index 47680237f783..6eb84f14c88d 100644 --- a/drivers/net/eepro.c +++ b/drivers/net/eepro.c @@ -537,8 +537,6 @@ static int __init do_eepro_probe(struct net_device *dev) int base_addr = dev->base_addr; int irq = dev->irq; - SET_MODULE_OWNER(dev); - #ifdef PnPWakeup /* XXXX for multiple cards should this only be run once? */ @@ -594,8 +592,6 @@ struct net_device * __init eepro_probe(int unit) if (!dev) return ERR_PTR(-ENODEV); - SET_MODULE_OWNER(dev); - sprintf(dev->name, "eth%d", unit); netdev_boot_setup_check(dev); diff --git a/drivers/net/eepro100.c b/drivers/net/eepro100.c index 3c54014acece..f8b69ceb2be6 100644 --- a/drivers/net/eepro100.c +++ b/drivers/net/eepro100.c @@ -635,7 +635,6 @@ static int __devinit speedo_found1(struct pci_dev *pdev, return -1; } - SET_MODULE_OWNER(dev); SET_NETDEV_DEV(dev, &pdev->dev); if (dev->mem_start > 0) diff --git a/drivers/net/eexpress.c b/drivers/net/eexpress.c index 7934ea37f944..6c91bfa72bb2 100644 --- a/drivers/net/eexpress.c +++ b/drivers/net/eexpress.c @@ -341,8 +341,6 @@ static int __init do_express_probe(struct net_device *dev) int dev_irq = dev->irq; int err; - SET_MODULE_OWNER(dev); - dev->if_port = 0xff; /* not set */ #ifdef CONFIG_MCA_LEGACY diff --git a/drivers/net/ehea/ehea_main.c b/drivers/net/ehea/ehea_main.c index b8e00391a5e3..62d6c1e5f9d3 100644 --- a/drivers/net/ehea/ehea_main.c +++ b/drivers/net/ehea/ehea_main.c @@ -2710,8 +2710,6 @@ struct ehea_port *ehea_setup_single_port(struct ehea_adapter *adapter, SET_NETDEV_DEV(dev, port_dev); /* initialize net_device structure */ - SET_MODULE_OWNER(dev); - memcpy(dev->dev_addr, &port->mac_addr, ETH_ALEN); dev->open = ehea_open; diff --git a/drivers/net/epic100.c b/drivers/net/epic100.c index f8446e373bdd..122ffd2f0822 100644 --- a/drivers/net/epic100.c +++ b/drivers/net/epic100.c @@ -352,7 +352,6 @@ static int __devinit epic_init_one (struct pci_dev *pdev, dev_err(&pdev->dev, "no memory for eth device\n"); goto err_out_free_res; } - SET_MODULE_OWNER(dev); SET_NETDEV_DEV(dev, &pdev->dev); #ifdef USE_IO_OPS diff --git a/drivers/net/eql.c b/drivers/net/eql.c index f1cc66dcbdfd..7266f6dbdd95 100644 --- a/drivers/net/eql.c +++ b/drivers/net/eql.c @@ -167,8 +167,6 @@ static void __init eql_setup(struct net_device *dev) { equalizer_t *eql = netdev_priv(dev); - SET_MODULE_OWNER(dev); - init_timer(&eql->timer); eql->timer.data = (unsigned long) eql; eql->timer.expires = jiffies + EQL_DEFAULT_RESCHED_IVAL; diff --git a/drivers/net/es3210.c b/drivers/net/es3210.c index 822e5bfd1a71..238fa8aff02d 100644 --- a/drivers/net/es3210.c +++ b/drivers/net/es3210.c @@ -130,8 +130,6 @@ static int __init do_es_probe(struct net_device *dev) int irq = dev->irq; int mem_start = dev->mem_start; - SET_MODULE_OWNER(dev); - if (ioaddr > 0x1ff) /* Check a single specified location. */ return es_probe1(dev, ioaddr); else if (ioaddr > 0) /* Don't probe at all. */ diff --git a/drivers/net/eth16i.c b/drivers/net/eth16i.c index 04abf59e5007..0e3b33717cac 100644 --- a/drivers/net/eth16i.c +++ b/drivers/net/eth16i.c @@ -436,8 +436,6 @@ static int __init do_eth16i_probe(struct net_device *dev) int ioaddr; int base_addr = dev->base_addr; - SET_MODULE_OWNER(dev); - if(eth16i_debug > 4) printk(KERN_DEBUG "Probing started for %s\n", cardname); diff --git a/drivers/net/ewrk3.c b/drivers/net/ewrk3.c index cb0792c187ba..6a5d0436e89e 100644 --- a/drivers/net/ewrk3.c +++ b/drivers/net/ewrk3.c @@ -356,7 +356,6 @@ struct net_device * __init ewrk3_probe(int unit) sprintf(dev->name, "eth%d", unit); netdev_boot_setup_check(dev); } - SET_MODULE_OWNER(dev); err = ewrk3_probe1(dev, dev->base_addr, dev->irq); if (err) diff --git a/drivers/net/fealnx.c b/drivers/net/fealnx.c index ff9f177d7157..e9353072a96d 100644 --- a/drivers/net/fealnx.c +++ b/drivers/net/fealnx.c @@ -527,7 +527,6 @@ static int __devinit fealnx_init_one(struct pci_dev *pdev, err = -ENOMEM; goto err_out_unmap; } - SET_MODULE_OWNER(dev); SET_NETDEV_DEV(dev, &pdev->dev); /* read ethernet id */ diff --git a/drivers/net/fec_8xx/fec_main.c b/drivers/net/fec_8xx/fec_main.c index 6348fb93ca9c..6f214ab12fff 100644 --- a/drivers/net/fec_8xx/fec_main.c +++ b/drivers/net/fec_8xx/fec_main.c @@ -1103,7 +1103,6 @@ int fec_8xx_init_one(const struct fec_platform_info *fpi, err = -ENOMEM; goto err; } - SET_MODULE_OWNER(dev); fep = netdev_priv(dev); fep->dev = dev; diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c index 24c1294614f2..050a8f14eda8 100644 --- a/drivers/net/forcedeth.c +++ b/drivers/net/forcedeth.c @@ -5004,7 +5004,6 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i np->dev = dev; np->pci_dev = pci_dev; spin_lock_init(&np->lock); - SET_MODULE_OWNER(dev); SET_NETDEV_DEV(dev, &pci_dev->dev); init_timer(&np->oom_kick); diff --git a/drivers/net/fs_enet/fs_enet-main.c b/drivers/net/fs_enet/fs_enet-main.c index 2812b524edae..f6789a8db8cd 100644 --- a/drivers/net/fs_enet/fs_enet-main.c +++ b/drivers/net/fs_enet/fs_enet-main.c @@ -953,7 +953,6 @@ static struct net_device *fs_init_instance(struct device *dev, err = -ENOMEM; goto err; } - SET_MODULE_OWNER(ndev); fep = netdev_priv(ndev); diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c index bd2de325bbdd..002f8baaab2d 100644 --- a/drivers/net/gianfar.c +++ b/drivers/net/gianfar.c @@ -254,7 +254,6 @@ static int gfar_probe(struct platform_device *pdev) /* Set the dev->base_addr to the gfar reg region */ dev->base_addr = (unsigned long) (priv->regs); - SET_MODULE_OWNER(dev); SET_NETDEV_DEV(dev, &pdev->dev); /* Fill in the dev structure */ diff --git a/drivers/net/hamachi.c b/drivers/net/hamachi.c index 15254dc7876a..da12b3db023f 100644 --- a/drivers/net/hamachi.c +++ b/drivers/net/hamachi.c @@ -613,7 +613,6 @@ static int __devinit hamachi_init_one (struct pci_dev *pdev, if (!dev) goto err_out_iounmap; - SET_MODULE_OWNER(dev); SET_NETDEV_DEV(dev, &pdev->dev); #ifdef TX_CHECKSUM diff --git a/drivers/net/hamradio/6pack.c b/drivers/net/hamradio/6pack.c index 760d04a671f9..0a847326a5e4 100644 --- a/drivers/net/hamradio/6pack.c +++ b/drivers/net/hamradio/6pack.c @@ -345,8 +345,6 @@ static void sp_setup(struct net_device *dev) memcpy(dev->broadcast, &ax25_bcast, AX25_ADDR_LEN); memcpy(dev->dev_addr, &ax25_defaddr, AX25_ADDR_LEN); - SET_MODULE_OWNER(dev); - dev->flags = 0; } diff --git a/drivers/net/hp-plus.c b/drivers/net/hp-plus.c index 99a36cc3f8df..8d4f810fa288 100644 --- a/drivers/net/hp-plus.c +++ b/drivers/net/hp-plus.c @@ -122,8 +122,6 @@ static int __init do_hpp_probe(struct net_device *dev) int base_addr = dev->base_addr; int irq = dev->irq; - SET_MODULE_OWNER(dev); - if (base_addr > 0x1ff) /* Check a single specified location. */ return hpp_probe1(dev, base_addr); else if (base_addr != 0) /* Don't probe at all. */ diff --git a/drivers/net/hp.c b/drivers/net/hp.c index 635b13c2e2aa..1f11126de354 100644 --- a/drivers/net/hp.c +++ b/drivers/net/hp.c @@ -86,8 +86,6 @@ static int __init do_hp_probe(struct net_device *dev) int base_addr = dev->base_addr; int irq = dev->irq; - SET_MODULE_OWNER(dev); - if (base_addr > 0x1ff) /* Check a single specified location. */ return hp_probe1(dev, base_addr); else if (base_addr != 0) /* Don't probe at all. */ diff --git a/drivers/net/hp100.c b/drivers/net/hp100.c index 8caa591c5649..406d6525e222 100644 --- a/drivers/net/hp100.c +++ b/drivers/net/hp100.c @@ -404,8 +404,6 @@ struct net_device * __init hp100_probe(int unit) if (!dev) return ERR_PTR(-ENODEV); - SET_MODULE_OWNER(dev); - #ifdef HP100_DEBUG_B hp100_outw(0x4200, TRACE); printk("hp100: %s: probe\n", dev->name); @@ -2843,7 +2841,6 @@ static int __init hp100_eisa_probe (struct device *gendev) if (!dev) return -ENOMEM; - SET_MODULE_OWNER(dev); SET_NETDEV_DEV(dev, &edev->dev); err = hp100_probe1(dev, edev->base_addr + 0xC38, HP100_BUS_EISA, NULL); @@ -2896,7 +2893,6 @@ static int __devinit hp100_pci_probe (struct pci_dev *pdev, goto out0; } - SET_MODULE_OWNER(dev); SET_NETDEV_DEV(dev, &pdev->dev); pci_read_config_word(pdev, PCI_COMMAND, &pci_command); @@ -2993,7 +2989,6 @@ static int __init hp100_isa_init(void) return -ENOMEM; } - SET_MODULE_OWNER(dev); err = hp100_isa_probe(dev, hp100_port[i]); if (!err) diff --git a/drivers/net/hydra.c b/drivers/net/hydra.c index f970bfbb9db2..31300a9dd965 100644 --- a/drivers/net/hydra.c +++ b/drivers/net/hydra.c @@ -112,7 +112,6 @@ static int __devinit hydra_init(struct zorro_dev *z) dev = ____alloc_ei_netdev(0); if (!dev) return -ENOMEM; - SET_MODULE_OWNER(dev); for(j = 0; j < ETHER_ADDR_LEN; j++) dev->dev_addr[j] = *((u8 *)(board + HYDRA_ADDRPROM + 2*j)); diff --git a/drivers/net/ibm_emac/ibm_emac_core.c b/drivers/net/ibm_emac/ibm_emac_core.c index f752e5fc65ba..354616b0b57b 100644 --- a/drivers/net/ibm_emac/ibm_emac_core.c +++ b/drivers/net/ibm_emac/ibm_emac_core.c @@ -1962,7 +1962,6 @@ static int __init emac_probe(struct ocp_device *ocpdev) dev->ndev = ndev; dev->ldev = &ocpdev->dev; dev->def = ocpdev->def; - SET_MODULE_OWNER(ndev); /* Find MAL device we are connected to */ maldev = diff --git a/drivers/net/ibmlana.c b/drivers/net/ibmlana.c index fe85d6fcba33..67d82fa7659d 100644 --- a/drivers/net/ibmlana.c +++ b/drivers/net/ibmlana.c @@ -907,8 +907,6 @@ static int ibmlana_probe(struct net_device *dev) ibmlana_priv *priv; ibmlana_medium medium; - SET_MODULE_OWNER(dev); - /* can't work without an MCA bus ;-) */ if (MCA_bus == 0) return -ENODEV; diff --git a/drivers/net/ibmveth.c b/drivers/net/ibmveth.c index 2dff9f2800cd..db908c40dbe1 100644 --- a/drivers/net/ibmveth.c +++ b/drivers/net/ibmveth.c @@ -1142,8 +1142,6 @@ static int __devinit ibmveth_probe(struct vio_dev *dev, const struct vio_device_ if(!netdev) return -ENOMEM; - SET_MODULE_OWNER(netdev); - adapter = netdev->priv; dev->dev.driver_data = netdev; @@ -1258,7 +1256,6 @@ static void ibmveth_proc_register_driver(void) { ibmveth_proc_dir = proc_mkdir(IBMVETH_PROC_DIR, init_net.proc_net); if (ibmveth_proc_dir) { - SET_MODULE_OWNER(ibmveth_proc_dir); } } @@ -1356,7 +1353,6 @@ static void ibmveth_proc_register_adapter(struct ibmveth_adapter *adapter) } else { entry->data = (void *) adapter; entry->proc_fops = &ibmveth_proc_fops; - SET_MODULE_OWNER(entry); } } return; diff --git a/drivers/net/ifb.c b/drivers/net/ifb.c index b06c6db4383a..448e618b6974 100644 --- a/drivers/net/ifb.c +++ b/drivers/net/ifb.c @@ -152,7 +152,6 @@ static void ifb_setup(struct net_device *dev) dev->change_mtu = NULL; dev->flags |= IFF_NOARP; dev->flags &= ~IFF_MULTICAST; - SET_MODULE_OWNER(dev); random_ether_addr(dev->dev_addr); } diff --git a/drivers/net/ioc3-eth.c b/drivers/net/ioc3-eth.c index c030030e5863..05d2bc15144e 100644 --- a/drivers/net/ioc3-eth.c +++ b/drivers/net/ioc3-eth.c @@ -1273,7 +1273,6 @@ static int ioc3_probe(struct pci_dev *pdev, const struct pci_device_id *ent) if (err) goto out_free; - SET_MODULE_OWNER(dev); SET_NETDEV_DEV(dev, &pdev->dev); ip = netdev_priv(dev); diff --git a/drivers/net/irda/ali-ircc.c b/drivers/net/irda/ali-ircc.c index f9c889c0dd07..9f584521304a 100644 --- a/drivers/net/irda/ali-ircc.c +++ b/drivers/net/irda/ali-ircc.c @@ -360,10 +360,6 @@ static int ali_ircc_open(int i, chipio_t *info) self->tx_fifo.len = self->tx_fifo.ptr = self->tx_fifo.free = 0; self->tx_fifo.tail = self->tx_buff.head; - - /* Keep track of module usage */ - SET_MODULE_OWNER(dev); - /* Override the network functions we need to use */ dev->hard_start_xmit = ali_ircc_sir_hard_xmit; dev->open = ali_ircc_net_open; diff --git a/drivers/net/irda/donauboe.c b/drivers/net/irda/donauboe.c index 3ca47bf6dfec..3e5eca1aa987 100644 --- a/drivers/net/irda/donauboe.c +++ b/drivers/net/irda/donauboe.c @@ -1660,7 +1660,6 @@ toshoboe_open (struct pci_dev *pci_dev, const struct pci_device_id *pdid) } #endif - SET_MODULE_OWNER(dev); SET_NETDEV_DEV(dev, &pci_dev->dev); dev->hard_start_xmit = toshoboe_hard_xmit; dev->open = toshoboe_net_open; diff --git a/drivers/net/irda/irda-usb.c b/drivers/net/irda/irda-usb.c index 3b0fd83fa266..c6355c00fd7a 100644 --- a/drivers/net/irda/irda-usb.c +++ b/drivers/net/irda/irda-usb.c @@ -1635,7 +1635,6 @@ static int irda_usb_probe(struct usb_interface *intf, if (!net) goto err_out; - SET_MODULE_OWNER(net); SET_NETDEV_DEV(net, &intf->dev); self = net->priv; self->netdev = net; diff --git a/drivers/net/irda/irport.c b/drivers/net/irda/irport.c index 20732458f5ac..c79caa5d3d71 100644 --- a/drivers/net/irda/irport.c +++ b/drivers/net/irda/irport.c @@ -175,8 +175,6 @@ irport_open(int i, unsigned int iobase, unsigned int irq) self->tx_buff.data = self->tx_buff.head; self->netdev = dev; - /* Keep track of module usage */ - SET_MODULE_OWNER(dev); /* May be overridden by piggyback drivers */ self->interrupt = irport_interrupt; diff --git a/drivers/net/irda/kingsun-sir.c b/drivers/net/irda/kingsun-sir.c index a4adb74cccd2..648e54b3f00e 100644 --- a/drivers/net/irda/kingsun-sir.c +++ b/drivers/net/irda/kingsun-sir.c @@ -487,7 +487,6 @@ static int kingsun_probe(struct usb_interface *intf, if(!net) goto err_out1; - SET_MODULE_OWNER(net); SET_NETDEV_DEV(net, &intf->dev); kingsun = netdev_priv(net); kingsun->irlap = NULL; diff --git a/drivers/net/irda/ks959-sir.c b/drivers/net/irda/ks959-sir.c index 407afba1a597..8c257a51341a 100644 --- a/drivers/net/irda/ks959-sir.c +++ b/drivers/net/irda/ks959-sir.c @@ -697,7 +697,6 @@ static int ks959_probe(struct usb_interface *intf, if (!net) goto err_out1; - SET_MODULE_OWNER(net); SET_NETDEV_DEV(net, &intf->dev); kingsun = netdev_priv(net); kingsun->netdev = net; diff --git a/drivers/net/irda/ksdazzle-sir.c b/drivers/net/irda/ksdazzle-sir.c index 12b0e7a15bef..af60f2435a38 100644 --- a/drivers/net/irda/ksdazzle-sir.c +++ b/drivers/net/irda/ksdazzle-sir.c @@ -628,7 +628,6 @@ static int ksdazzle_probe(struct usb_interface *intf, if (!net) goto err_out1; - SET_MODULE_OWNER(net); SET_NETDEV_DEV(net, &intf->dev); kingsun = netdev_priv(net); kingsun->netdev = net; diff --git a/drivers/net/irda/mcs7780.c b/drivers/net/irda/mcs7780.c index bfc57525bd6a..808939b9f8fb 100644 --- a/drivers/net/irda/mcs7780.c +++ b/drivers/net/irda/mcs7780.c @@ -898,8 +898,6 @@ static int mcs_probe(struct usb_interface *intf, IRDA_DEBUG(1, "MCS7780 USB-IrDA bridge found at %d.\n", udev->devnum); - /* what is it realy for? */ - SET_MODULE_OWNER(ndev); SET_NETDEV_DEV(ndev, &intf->dev); ret = usb_reset_configuration(udev); diff --git a/drivers/net/irda/nsc-ircc.c b/drivers/net/irda/nsc-ircc.c index d96c89751a71..12b9378c587f 100644 --- a/drivers/net/irda/nsc-ircc.c +++ b/drivers/net/irda/nsc-ircc.c @@ -437,7 +437,6 @@ static int __init nsc_ircc_open(chipio_t *info) self->tx_fifo.tail = self->tx_buff.head; /* Override the network functions we need to use */ - SET_MODULE_OWNER(dev); dev->hard_start_xmit = nsc_ircc_hard_xmit_sir; dev->open = nsc_ircc_net_open; dev->stop = nsc_ircc_net_close; diff --git a/drivers/net/irda/sir_dev.c b/drivers/net/irda/sir_dev.c index 9d6c8f391b2d..bbe4e094c424 100644 --- a/drivers/net/irda/sir_dev.c +++ b/drivers/net/irda/sir_dev.c @@ -913,8 +913,6 @@ struct sir_dev * sirdev_get_instance(const struct sir_driver *drv, const char *n dev->drv = drv; dev->netdev = ndev; - SET_MODULE_OWNER(ndev); - /* Override the network functions we need to use */ ndev->hard_start_xmit = sirdev_hard_xmit; ndev->open = sirdev_open; diff --git a/drivers/net/irda/smsc-ircc2.c b/drivers/net/irda/smsc-ircc2.c index 36ab98386be0..029fdde2a4d3 100644 --- a/drivers/net/irda/smsc-ircc2.c +++ b/drivers/net/irda/smsc-ircc2.c @@ -519,8 +519,6 @@ static int __init smsc_ircc_open(unsigned int fir_base, unsigned int sir_base, u goto err_out1; } - SET_MODULE_OWNER(dev); - dev->hard_start_xmit = smsc_ircc_hard_xmit_sir; #if SMSC_IRCC2_C_NET_TIMEOUT dev->tx_timeout = smsc_ircc_timeout; diff --git a/drivers/net/irda/stir4200.c b/drivers/net/irda/stir4200.c index 755aa444a4dd..1afaee0fa7e0 100644 --- a/drivers/net/irda/stir4200.c +++ b/drivers/net/irda/stir4200.c @@ -1034,7 +1034,6 @@ static int stir_probe(struct usb_interface *intf, if(!net) goto err_out1; - SET_MODULE_OWNER(net); SET_NETDEV_DEV(net, &intf->dev); stir = netdev_priv(net); stir->netdev = net; diff --git a/drivers/net/irda/via-ircc.c b/drivers/net/irda/via-ircc.c index ff5358574d0a..126ec7c8680e 100644 --- a/drivers/net/irda/via-ircc.c +++ b/drivers/net/irda/via-ircc.c @@ -429,9 +429,6 @@ static __devinit int via_ircc_open(int i, chipio_t * info, unsigned int id) self->tx_fifo.len = self->tx_fifo.ptr = self->tx_fifo.free = 0; self->tx_fifo.tail = self->tx_buff.head; - /* Keep track of module usage */ - SET_MODULE_OWNER(dev); - /* Override the network functions we need to use */ dev->hard_start_xmit = via_ircc_hard_xmit_sir; dev->open = via_ircc_net_open; diff --git a/drivers/net/irda/vlsi_ir.c b/drivers/net/irda/vlsi_ir.c index 0538ca9ce058..acd082a96a4f 100644 --- a/drivers/net/irda/vlsi_ir.c +++ b/drivers/net/irda/vlsi_ir.c @@ -1584,8 +1584,6 @@ static int vlsi_irda_init(struct net_device *ndev) vlsi_irda_dev_t *idev = ndev->priv; struct pci_dev *pdev = idev->pdev; - SET_MODULE_OWNER(ndev); - ndev->irq = pdev->irq; ndev->base_addr = pci_resource_start(pdev,0); diff --git a/drivers/net/irda/w83977af_ir.c b/drivers/net/irda/w83977af_ir.c index 5182e800cc18..9fd2451b0fb2 100644 --- a/drivers/net/irda/w83977af_ir.c +++ b/drivers/net/irda/w83977af_ir.c @@ -232,9 +232,6 @@ int w83977af_open(int i, unsigned int iobase, unsigned int irq, self->rx_buff.data = self->rx_buff.head; self->netdev = dev; - /* Keep track of module usage */ - SET_MODULE_OWNER(dev); - /* Override the network functions we need to use */ dev->hard_start_xmit = w83977af_hard_xmit; dev->open = w83977af_net_open; diff --git a/drivers/net/isa-skeleton.c b/drivers/net/isa-skeleton.c index 0343f12d2ffb..54178111eec5 100644 --- a/drivers/net/isa-skeleton.c +++ b/drivers/net/isa-skeleton.c @@ -133,8 +133,6 @@ static int __init do_netcard_probe(struct net_device *dev) int base_addr = dev->base_addr; int irq = dev->irq; - SET_MODULE_OWNER(dev); - if (base_addr > 0x1ff) /* Check a single specified location. */ return netcard_probe1(dev, base_addr); else if (base_addr != 0) /* Don't probe at all. */ diff --git a/drivers/net/ixgb/ixgb_main.c b/drivers/net/ixgb/ixgb_main.c index e3f27c67fb28..d444de58ba34 100644 --- a/drivers/net/ixgb/ixgb_main.c +++ b/drivers/net/ixgb/ixgb_main.c @@ -382,7 +382,6 @@ ixgb_probe(struct pci_dev *pdev, goto err_alloc_etherdev; } - SET_MODULE_OWNER(netdev); SET_NETDEV_DEV(netdev, &pdev->dev); pci_set_drvdata(pdev, netdev); diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index a08a46224c28..b75f1c6efc42 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -2548,7 +2548,6 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev, goto err_alloc_etherdev; } - SET_MODULE_OWNER(netdev); SET_NETDEV_DEV(netdev, &pdev->dev); pci_set_drvdata(pdev, netdev); diff --git a/drivers/net/ixp2000/enp2611.c b/drivers/net/ixp2000/enp2611.c index d3f4235c585d..b02a981c87a8 100644 --- a/drivers/net/ixp2000/enp2611.c +++ b/drivers/net/ixp2000/enp2611.c @@ -210,7 +210,6 @@ static int __init enp2611_init_module(void) return -ENOMEM; } - SET_MODULE_OWNER(nds[i]); nds[i]->get_stats = enp2611_get_stats; pm3386_init_port(i); pm3386_get_mac(i, nds[i]->dev_addr); diff --git a/drivers/net/jazzsonic.c b/drivers/net/jazzsonic.c index b71e6633f42d..13847a3e43e5 100644 --- a/drivers/net/jazzsonic.c +++ b/drivers/net/jazzsonic.c @@ -221,7 +221,6 @@ static int __init jazz_sonic_probe(struct platform_device *pdev) lp = netdev_priv(dev); lp->device = &pdev->dev; SET_NETDEV_DEV(dev, &pdev->dev); - SET_MODULE_OWNER(dev); netdev_boot_setup_check(dev); diff --git a/drivers/net/lance.c b/drivers/net/lance.c index a4e5fab12628..7b17212d687e 100644 --- a/drivers/net/lance.c +++ b/drivers/net/lance.c @@ -521,7 +521,6 @@ static int __init lance_probe1(struct net_device *dev, int ioaddr, int irq, int /* We can't allocate dev->priv from alloc_etherdev() because it must a ISA DMA-able region. */ - SET_MODULE_OWNER(dev); chipname = chip_table[lance_version].name; printk("%s: %s at %#3x,", dev->name, chipname, ioaddr); diff --git a/drivers/net/lguest_net.c b/drivers/net/lguest_net.c index cab57911a80e..7f34c92bcd86 100644 --- a/drivers/net/lguest_net.c +++ b/drivers/net/lguest_net.c @@ -460,8 +460,6 @@ static int lguestnet_probe(struct lguest_device *lgdev) if (!dev) return -ENOMEM; - SET_MODULE_OWNER(dev); - /* Ethernet defaults with some changes */ ether_setup(dev); dev->set_mac_address = NULL; diff --git a/drivers/net/lne390.c b/drivers/net/lne390.c index 0a08d0c4e7b4..2dd396983213 100644 --- a/drivers/net/lne390.c +++ b/drivers/net/lne390.c @@ -111,8 +111,6 @@ static int __init do_lne390_probe(struct net_device *dev) int mem_start = dev->mem_start; int ret; - SET_MODULE_OWNER(dev); - if (ioaddr > 0x1ff) { /* Check a single specified location. */ if (!request_region(ioaddr, LNE390_IO_EXTENT, DRV_NAME)) return -EBUSY; diff --git a/drivers/net/mac8390.c b/drivers/net/mac8390.c index 90b0c3ed4bb6..9e700749bb31 100644 --- a/drivers/net/mac8390.c +++ b/drivers/net/mac8390.c @@ -313,8 +313,6 @@ struct net_device * __init mac8390_probe(int unit) if (unit >= 0) sprintf(dev->name, "eth%d", unit); - SET_MODULE_OWNER(dev); - while ((ndev = nubus_find_type(NUBUS_CAT_NETWORK, NUBUS_TYPE_ETHERNET, ndev))) { /* Have we seen it already? */ if (slots & (1<board->slot)) diff --git a/drivers/net/mac89x0.c b/drivers/net/mac89x0.c index 62c1c6262feb..f6f3fdfe41db 100644 --- a/drivers/net/mac89x0.c +++ b/drivers/net/mac89x0.c @@ -191,8 +191,6 @@ struct net_device * __init mac89x0_probe(int unit) netdev_boot_setup_check(dev); } - SET_MODULE_OWNER(dev); - if (once_is_enough) goto out; once_is_enough = 1; diff --git a/drivers/net/macb.c b/drivers/net/macb.c index 74c3f7a7ae4a..c6707580c305 100644 --- a/drivers/net/macb.c +++ b/drivers/net/macb.c @@ -1085,7 +1085,6 @@ static int __devinit macb_probe(struct platform_device *pdev) goto err_out; } - SET_MODULE_OWNER(dev); SET_NETDEV_DEV(dev, &pdev->dev); /* TODO: Actually, we have some interesting features... */ diff --git a/drivers/net/mace.c b/drivers/net/mace.c index 52b9332810c5..de3b002e9a4c 100644 --- a/drivers/net/mace.c +++ b/drivers/net/mace.c @@ -143,7 +143,6 @@ static int __devinit mace_probe(struct macio_dev *mdev, const struct of_device_i rc = -ENOMEM; goto err_release; } - SET_MODULE_OWNER(dev); SET_NETDEV_DEV(dev, &mdev->ofdev.dev); mp = dev->priv; diff --git a/drivers/net/macmace.c b/drivers/net/macmace.c index 9a343b965975..5d2daa248873 100644 --- a/drivers/net/macmace.c +++ b/drivers/net/macmace.c @@ -210,7 +210,6 @@ static int __devinit mace_probe(struct platform_device *pdev) mp->device = &pdev->dev; SET_NETDEV_DEV(dev, &pdev->dev); - SET_MODULE_OWNER(dev); dev->base_addr = (u32)MACE_BASE; mp->mace = (volatile struct mace *) MACE_BASE; diff --git a/drivers/net/macsonic.c b/drivers/net/macsonic.c index e9ecdbf352ae..a55a8399344c 100644 --- a/drivers/net/macsonic.c +++ b/drivers/net/macsonic.c @@ -576,7 +576,6 @@ static int __init mac_sonic_probe(struct platform_device *pdev) lp = netdev_priv(dev); lp->device = &pdev->dev; SET_NETDEV_DEV(dev, &pdev->dev); - SET_MODULE_OWNER(dev); /* This will catch fatal stuff like -ENOMEM as well as success */ err = mac_onboard_sonic_probe(dev); diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c index 702eba549161..6317bba9587c 100644 --- a/drivers/net/mv643xx_eth.c +++ b/drivers/net/mv643xx_eth.c @@ -1425,7 +1425,6 @@ static int mv643xx_eth_probe(struct platform_device *pdev) mv643xx_eth_update_pscr(dev, &cmd); mv643xx_set_settings(dev, &cmd); - SET_MODULE_OWNER(dev); SET_NETDEV_DEV(dev, &pdev->dev); err = register_netdev(dev); if (err) diff --git a/drivers/net/mvme147.c b/drivers/net/mvme147.c index e246d00bba6d..837ad0f2b05d 100644 --- a/drivers/net/mvme147.c +++ b/drivers/net/mvme147.c @@ -79,8 +79,6 @@ struct net_device * __init mvme147lance_probe(int unit) if (unit >= 0) sprintf(dev->name, "eth%d", unit); - SET_MODULE_OWNER(dev); - /* Fill the dev fields */ dev->base_addr = (unsigned long)MVME147_LANCE_BASE; dev->open = &m147lance_open; diff --git a/drivers/net/myri_sbus.c b/drivers/net/myri_sbus.c index 13444da93273..331b76c49561 100644 --- a/drivers/net/myri_sbus.c +++ b/drivers/net/myri_sbus.c @@ -908,7 +908,6 @@ static int __devinit myri_ether_init(struct sbus_dev *sdev) if (version_printed++ == 0) printk(version); - SET_MODULE_OWNER(dev); SET_NETDEV_DEV(dev, &sdev->ofdev.dev); mp = (struct myri_eth *) dev->priv; diff --git a/drivers/net/natsemi.c b/drivers/net/natsemi.c index 43cfa4b3e294..5ee4e8795d23 100644 --- a/drivers/net/natsemi.c +++ b/drivers/net/natsemi.c @@ -837,7 +837,6 @@ static int __devinit natsemi_probe1 (struct pci_dev *pdev, dev = alloc_etherdev(sizeof (struct netdev_private)); if (!dev) return -ENOMEM; - SET_MODULE_OWNER(dev); SET_NETDEV_DEV(dev, &pdev->dev); i = pci_request_regions(pdev, DRV_NAME); diff --git a/drivers/net/ne-h8300.c b/drivers/net/ne-h8300.c index 38fd525f0f13..a0f35361fbec 100644 --- a/drivers/net/ne-h8300.c +++ b/drivers/net/ne-h8300.c @@ -149,8 +149,6 @@ static int __init do_ne_probe(struct net_device *dev) { unsigned int base_addr = dev->base_addr; - SET_MODULE_OWNER(dev); - /* First check any supplied i/o locations. User knows best. */ if (base_addr > 0x1ff) /* Check a single specified location. */ return ne_probe1(dev, base_addr); diff --git a/drivers/net/ne.c b/drivers/net/ne.c index c9f74bf5f491..c81befc3a7ae 100644 --- a/drivers/net/ne.c +++ b/drivers/net/ne.c @@ -191,8 +191,6 @@ static int __init do_ne_probe(struct net_device *dev) int orig_irq = dev->irq; #endif - SET_MODULE_OWNER(dev); - /* First check any supplied i/o locations. User knows best. */ if (base_addr > 0x1ff) /* Check a single specified location. */ return ne_probe1(dev, base_addr); diff --git a/drivers/net/ne2.c b/drivers/net/ne2.c index 089b5bb702fc..d1a4b8d7122a 100644 --- a/drivers/net/ne2.c +++ b/drivers/net/ne2.c @@ -251,8 +251,6 @@ static int __init do_ne2_probe(struct net_device *dev) int i; int adapter_found = 0; - SET_MODULE_OWNER(dev); - /* Do not check any supplied i/o locations. POS registers usually don't fail :) */ diff --git a/drivers/net/ne2k-pci.c b/drivers/net/ne2k-pci.c index f81d9398d605..230a0f1e03fb 100644 --- a/drivers/net/ne2k-pci.c +++ b/drivers/net/ne2k-pci.c @@ -265,7 +265,6 @@ static int __devinit ne2k_pci_init_one (struct pci_dev *pdev, dev_err(&pdev->dev, "cannot allocate ethernet device\n"); goto err_out_free_res; } - SET_MODULE_OWNER(dev); SET_NETDEV_DEV(dev, &pdev->dev); /* Reset card. Who knows what dain-bramaged state it was left in. */ diff --git a/drivers/net/ne3210.c b/drivers/net/ne3210.c index 1a6fed76d4cc..b1bf8331e872 100644 --- a/drivers/net/ne3210.c +++ b/drivers/net/ne3210.c @@ -106,7 +106,6 @@ static int __init ne3210_eisa_probe (struct device *device) return -ENOMEM; } - SET_MODULE_OWNER(dev); SET_NETDEV_DEV(dev, device); device->driver_data = dev; ioaddr = edev->base_addr; diff --git a/drivers/net/netx-eth.c b/drivers/net/netx-eth.c index 2b8da0a54998..6fee405d8403 100644 --- a/drivers/net/netx-eth.c +++ b/drivers/net/netx-eth.c @@ -390,7 +390,6 @@ static int netx_eth_drv_probe(struct platform_device *pdev) ret = -ENOMEM; goto exit; } - SET_MODULE_OWNER(ndev); SET_NETDEV_DEV(ndev, &pdev->dev); platform_set_drvdata(pdev, ndev); diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c index dcd66a6b4904..1b165a8c74f3 100644 --- a/drivers/net/netxen/netxen_nic_main.c +++ b/drivers/net/netxen/netxen_nic_main.c @@ -325,7 +325,6 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) goto err_out_free_res; } - SET_MODULE_OWNER(netdev); SET_NETDEV_DEV(netdev, &pdev->dev); adapter = netdev->priv; diff --git a/drivers/net/ni5010.c b/drivers/net/ni5010.c index 22a3b3dc7d89..cc1d09a21c0c 100644 --- a/drivers/net/ni5010.c +++ b/drivers/net/ni5010.c @@ -135,8 +135,6 @@ struct net_device * __init ni5010_probe(int unit) PRINTK2((KERN_DEBUG "%s: Entering ni5010_probe\n", dev->name)); - SET_MODULE_OWNER(dev); - if (io > 0x1ff) { /* Check a single specified location. */ err = ni5010_probe1(dev, io); } else if (io != 0) { /* Don't probe at all. */ diff --git a/drivers/net/ni52.c b/drivers/net/ni52.c index 5e7999db2096..6b3384a24f07 100644 --- a/drivers/net/ni52.c +++ b/drivers/net/ni52.c @@ -382,8 +382,6 @@ struct net_device * __init ni52_probe(int unit) memend = dev->mem_end; } - SET_MODULE_OWNER(dev); - if (io > 0x1ff) { /* Check a single specified location. */ err = ni52_probe1(dev, io); } else if (io > 0) { /* Don't probe at all. */ diff --git a/drivers/net/ni65.c b/drivers/net/ni65.c index 4ef5fe345191..097685245112 100644 --- a/drivers/net/ni65.c +++ b/drivers/net/ni65.c @@ -550,7 +550,6 @@ static int __init ni65_probe1(struct net_device *dev,int ioaddr) } dev->base_addr = ioaddr; - SET_MODULE_OWNER(dev); dev->open = ni65_open; dev->stop = ni65_close; dev->hard_start_xmit = ni65_send_packet; diff --git a/drivers/net/ns83820.c b/drivers/net/ns83820.c index 6e65d61a3fe0..de495b697294 100644 --- a/drivers/net/ns83820.c +++ b/drivers/net/ns83820.c @@ -1988,7 +1988,6 @@ static int __devinit ns83820_init_one(struct pci_dev *pci_dev, const struct pci_ spin_lock_init(&dev->misc_lock); dev->pci_dev = pci_dev; - SET_MODULE_OWNER(ndev); SET_NETDEV_DEV(ndev, &pci_dev->dev); INIT_WORK(&dev->tq_refill, queue_refill); diff --git a/drivers/net/pasemi_mac.c b/drivers/net/pasemi_mac.c index 48c117038fef..723685ee57aa 100644 --- a/drivers/net/pasemi_mac.c +++ b/drivers/net/pasemi_mac.c @@ -1176,7 +1176,6 @@ pasemi_mac_probe(struct pci_dev *pdev, const struct pci_device_id *ent) goto out_disable_device; } - SET_MODULE_OWNER(dev); pci_set_drvdata(pdev, dev); SET_NETDEV_DEV(dev, &pdev->dev); diff --git a/drivers/net/pci-skeleton.c b/drivers/net/pci-skeleton.c index 3cdbe118200b..a4b16484a5f7 100644 --- a/drivers/net/pci-skeleton.c +++ b/drivers/net/pci-skeleton.c @@ -604,7 +604,6 @@ static int __devinit netdrv_init_board (struct pci_dev *pdev, DPRINTK ("EXIT, returning -ENOMEM\n"); return -ENOMEM; } - SET_MODULE_OWNER(dev); SET_NETDEV_DEV(dev, &pdev->dev); tp = dev->priv; diff --git a/drivers/net/pcmcia/3c589_cs.c b/drivers/net/pcmcia/3c589_cs.c index 503f2685fb73..2136c80c0581 100644 --- a/drivers/net/pcmcia/3c589_cs.c +++ b/drivers/net/pcmcia/3c589_cs.c @@ -197,7 +197,6 @@ static int tc589_probe(struct pcmcia_device *link) link->conf.ConfigIndex = 1; /* The EL3-specific entries in the device structure. */ - SET_MODULE_OWNER(dev); dev->hard_start_xmit = &el3_start_xmit; dev->set_config = &el3_config; dev->get_stats = &el3_get_stats; diff --git a/drivers/net/pcmcia/axnet_cs.c b/drivers/net/pcmcia/axnet_cs.c index 50dff1b81d34..a9db59d2a2f1 100644 --- a/drivers/net/pcmcia/axnet_cs.c +++ b/drivers/net/pcmcia/axnet_cs.c @@ -1728,9 +1728,6 @@ static void axdev_setup(struct net_device *dev) if (ei_debug > 1) printk(version_8390); - SET_MODULE_OWNER(dev); - - ei_local = (struct ei_device *)netdev_priv(dev); spin_lock_init(&ei_local->page_lock); diff --git a/drivers/net/pcmcia/fmvj18x_cs.c b/drivers/net/pcmcia/fmvj18x_cs.c index 85d5f2ca4bb5..7f29e95a0644 100644 --- a/drivers/net/pcmcia/fmvj18x_cs.c +++ b/drivers/net/pcmcia/fmvj18x_cs.c @@ -259,7 +259,6 @@ static int fmvj18x_probe(struct pcmcia_device *link) link->conf.IntType = INT_MEMORY_AND_IO; /* The FMVJ18x specific entries in the device structure. */ - SET_MODULE_OWNER(dev); dev->hard_start_xmit = &fjn_start_xmit; dev->set_config = &fjn_config; dev->get_stats = &fjn_get_stats; diff --git a/drivers/net/pcmcia/nmclan_cs.c b/drivers/net/pcmcia/nmclan_cs.c index 997c2d0c83bb..1bb2ffa294de 100644 --- a/drivers/net/pcmcia/nmclan_cs.c +++ b/drivers/net/pcmcia/nmclan_cs.c @@ -474,7 +474,6 @@ static int nmclan_probe(struct pcmcia_device *link) lp->tx_free_frames=AM2150_MAX_TX_FRAMES; - SET_MODULE_OWNER(dev); dev->hard_start_xmit = &mace_start_xmit; dev->set_config = &mace_config; dev->get_stats = &mace_get_stats; diff --git a/drivers/net/pcmcia/pcnet_cs.c b/drivers/net/pcmcia/pcnet_cs.c index 63de89e93b70..49857c1b5067 100644 --- a/drivers/net/pcmcia/pcnet_cs.c +++ b/drivers/net/pcmcia/pcnet_cs.c @@ -259,7 +259,6 @@ static int pcnet_probe(struct pcmcia_device *link) link->conf.Attributes = CONF_ENABLE_IRQ; link->conf.IntType = INT_MEMORY_AND_IO; - SET_MODULE_OWNER(dev); dev->open = &pcnet_open; dev->stop = &pcnet_close; dev->set_config = &set_config; diff --git a/drivers/net/pcmcia/smc91c92_cs.c b/drivers/net/pcmcia/smc91c92_cs.c index af6728cb49c3..b25f1985d03e 100644 --- a/drivers/net/pcmcia/smc91c92_cs.c +++ b/drivers/net/pcmcia/smc91c92_cs.c @@ -336,7 +336,6 @@ static int smc91c92_probe(struct pcmcia_device *link) link->conf.IntType = INT_MEMORY_AND_IO; /* The SMC91c92-specific entries in the device structure. */ - SET_MODULE_OWNER(dev); dev->hard_start_xmit = &smc_start_xmit; dev->get_stats = &smc_get_stats; dev->set_config = &s9k_config; diff --git a/drivers/net/pcmcia/xirc2ps_cs.c b/drivers/net/pcmcia/xirc2ps_cs.c index 258d6f396186..d5c2d2c8c852 100644 --- a/drivers/net/pcmcia/xirc2ps_cs.c +++ b/drivers/net/pcmcia/xirc2ps_cs.c @@ -580,7 +580,6 @@ xirc2ps_probe(struct pcmcia_device *link) link->irq.Instance = dev; /* Fill in card specific entries */ - SET_MODULE_OWNER(dev); dev->hard_start_xmit = &do_start_xmit; dev->set_config = &do_config; dev->get_stats = &do_get_stats; diff --git a/drivers/net/pcnet32.c b/drivers/net/pcnet32.c index db87429b956f..724d90bd1feb 100644 --- a/drivers/net/pcnet32.c +++ b/drivers/net/pcnet32.c @@ -1822,7 +1822,6 @@ pcnet32_probe1(unsigned long ioaddr, int shared, struct pci_dev *pdev) spin_lock_init(&lp->lock); - SET_MODULE_OWNER(dev); SET_NETDEV_DEV(dev, &pdev->dev); lp->name = chipname; lp->shared_irq = shared; diff --git a/drivers/net/plip.c b/drivers/net/plip.c index 8754cf3356b0..2cfab4b36654 100644 --- a/drivers/net/plip.c +++ b/drivers/net/plip.c @@ -1278,7 +1278,6 @@ static void plip_attach (struct parport *port) strcpy(dev->name, name); - SET_MODULE_OWNER(dev); dev->irq = port->irq; dev->base_addr = port->base; if (port->irq == -1) { diff --git a/drivers/net/ps3_gelic_net.c b/drivers/net/ps3_gelic_net.c index 93c2c39a4a49..f375bbbd6604 100644 --- a/drivers/net/ps3_gelic_net.c +++ b/drivers/net/ps3_gelic_net.c @@ -1349,7 +1349,6 @@ static int gelic_net_setup_netdev(struct gelic_net_card *card) int status; u64 v1, v2; - SET_MODULE_OWNER(netdev); SET_NETDEV_DEV(netdev, &card->dev->core); spin_lock_init(&card->tx_dma_lock); diff --git a/drivers/net/qla3xxx.c b/drivers/net/qla3xxx.c index e39232320e34..309199bb7d12 100755 --- a/drivers/net/qla3xxx.c +++ b/drivers/net/qla3xxx.c @@ -4011,7 +4011,6 @@ static int __devinit ql3xxx_probe(struct pci_dev *pdev, goto err_out_free_regions; } - SET_MODULE_OWNER(ndev); SET_NETDEV_DEV(ndev, &pdev->dev); pci_set_drvdata(pdev, ndev); diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index 3f2306e3f517..b8809a8ef204 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c @@ -1506,7 +1506,6 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) goto out; } - SET_MODULE_OWNER(dev); SET_NETDEV_DEV(dev, &pdev->dev); tp = netdev_priv(dev); tp->dev = dev; diff --git a/drivers/net/rionet.c b/drivers/net/rionet.c index df6b73872fdb..25a9dd821aa2 100644 --- a/drivers/net/rionet.c +++ b/drivers/net/rionet.c @@ -471,8 +471,6 @@ static int rionet_setup_netdev(struct rio_mport *mport) ndev->features = NETIF_F_LLTX; SET_ETHTOOL_OPS(ndev, &rionet_ethtool_ops); - SET_MODULE_OWNER(ndev); - spin_lock_init(&rnet->lock); spin_lock_init(&rnet->tx_lock); diff --git a/drivers/net/rrunner.c b/drivers/net/rrunner.c index 5c2e41fac6d2..41f877d482c7 100644 --- a/drivers/net/rrunner.c +++ b/drivers/net/rrunner.c @@ -109,7 +109,6 @@ static int __devinit rr_init_one(struct pci_dev *pdev, rrpriv = netdev_priv(dev); - SET_MODULE_OWNER(dev); SET_NETDEV_DEV(dev, &pdev->dev); if (pci_request_regions(pdev, "rrunner")) { diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c index ac6b9b93c025..f77049b34e16 100644 --- a/drivers/net/s2io.c +++ b/drivers/net/s2io.c @@ -7463,7 +7463,6 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) pci_set_master(pdev); pci_set_drvdata(pdev, dev); - SET_MODULE_OWNER(dev); SET_NETDEV_DEV(dev, &pdev->dev); /* Private member variable initialized to s2io NIC structure */ diff --git a/drivers/net/sb1000.c b/drivers/net/sb1000.c index 1de3eec1a792..aeaa75f549e6 100644 --- a/drivers/net/sb1000.c +++ b/drivers/net/sb1000.c @@ -189,7 +189,6 @@ sb1000_probe_one(struct pnp_dev *pdev, const struct pnp_device_id *id) */ dev->flags = IFF_POINTOPOINT|IFF_NOARP; - SET_MODULE_OWNER(dev); SET_NETDEV_DEV(dev, &pdev->dev); if (sb1000_debug > 0) diff --git a/drivers/net/shaper.c b/drivers/net/shaper.c index 3773b3858bd4..b56721a68a85 100644 --- a/drivers/net/shaper.c +++ b/drivers/net/shaper.c @@ -533,8 +533,6 @@ static void __init shaper_setup(struct net_device *dev) * Set up the shaper. */ - SET_MODULE_OWNER(dev); - shaper_init_priv(dev); dev->open = shaper_open; diff --git a/drivers/net/sis190.c b/drivers/net/sis190.c index 038ccfbafdd1..e810ae942cd6 100644 --- a/drivers/net/sis190.c +++ b/drivers/net/sis190.c @@ -1421,7 +1421,6 @@ static struct net_device * __devinit sis190_init_board(struct pci_dev *pdev) goto err_out_0; } - SET_MODULE_OWNER(dev); SET_NETDEV_DEV(dev, &pdev->dev); tp = netdev_priv(dev); diff --git a/drivers/net/sis900.c b/drivers/net/sis900.c index 7c6e4808399a..e1930c3ee75d 100644 --- a/drivers/net/sis900.c +++ b/drivers/net/sis900.c @@ -430,7 +430,6 @@ static int __devinit sis900_probe(struct pci_dev *pci_dev, net_dev = alloc_etherdev(sizeof(struct sis900_private)); if (!net_dev) return -ENOMEM; - SET_MODULE_OWNER(net_dev); SET_NETDEV_DEV(net_dev, &pci_dev->dev); /* We do a request_region() to register /proc/ioports info. */ diff --git a/drivers/net/sk98lin/skge.c b/drivers/net/sk98lin/skge.c index 7dc9c9ebf5e7..20890e44f99a 100644 --- a/drivers/net/sk98lin/skge.c +++ b/drivers/net/sk98lin/skge.c @@ -4877,7 +4877,6 @@ static int __devinit skge_probe_one(struct pci_dev *pdev, goto out_free_netdev; } - SET_MODULE_OWNER(dev); dev->open = &SkGeOpen; dev->stop = &SkGeClose; dev->hard_start_xmit = &SkGeXmit; diff --git a/drivers/net/skfp/skfddi.c b/drivers/net/skfp/skfddi.c index a7ef6c8b7721..ca508708229d 100644 --- a/drivers/net/skfp/skfddi.c +++ b/drivers/net/skfp/skfddi.c @@ -262,7 +262,6 @@ static int skfp_init_one(struct pci_dev *pdev, dev->do_ioctl = &skfp_ioctl; dev->header_cache_update = NULL; /* not supported */ - SET_MODULE_OWNER(dev); SET_NETDEV_DEV(dev, &pdev->dev); /* Initialize board structure with bus-specific info */ diff --git a/drivers/net/skge.c b/drivers/net/skge.c index 0bf46ed4e684..47a144d000d5 100644 --- a/drivers/net/skge.c +++ b/drivers/net/skge.c @@ -3549,7 +3549,6 @@ static struct net_device *skge_devinit(struct skge_hw *hw, int port, return NULL; } - SET_MODULE_OWNER(dev); SET_NETDEV_DEV(dev, &hw->pdev->dev); dev->open = skge_up; dev->stop = skge_down; diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index 941a60882526..1b9e5f40ddee 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c @@ -3924,7 +3924,6 @@ static __devinit struct net_device *sky2_init_netdev(struct sky2_hw *hw, return NULL; } - SET_MODULE_OWNER(dev); SET_NETDEV_DEV(dev, &hw->pdev->dev); dev->irq = hw->pdev->irq; dev->open = sky2_up; diff --git a/drivers/net/slip.c b/drivers/net/slip.c index 3fd4735006f5..335b7cc80eba 100644 --- a/drivers/net/slip.c +++ b/drivers/net/slip.c @@ -639,8 +639,6 @@ static void sl_setup(struct net_device *dev) dev->addr_len = 0; dev->tx_queue_len = 10; - SET_MODULE_OWNER(dev); - /* New-style flags. */ dev->flags = IFF_NOARP|IFF_POINTOPOINT|IFF_MULTICAST; } diff --git a/drivers/net/smc-mca.c b/drivers/net/smc-mca.c index ae1ae343beed..3b43fa8fd088 100644 --- a/drivers/net/smc-mca.c +++ b/drivers/net/smc-mca.c @@ -264,7 +264,6 @@ static int __init ultramca_probe(struct device *gen_dev) if(!dev) return -ENODEV; - SET_MODULE_OWNER(dev); SET_NETDEV_DEV(dev, gen_dev); mca_device_set_name(mca_dev, smc_mca_adapter_names[adapter]); mca_device_set_claim(mca_dev, 1); diff --git a/drivers/net/smc-ultra.c b/drivers/net/smc-ultra.c index a52b22d7db65..d02bd7bc1bae 100644 --- a/drivers/net/smc-ultra.c +++ b/drivers/net/smc-ultra.c @@ -142,8 +142,6 @@ static int __init do_ultra_probe(struct net_device *dev) int base_addr = dev->base_addr; int irq = dev->irq; - SET_MODULE_OWNER(dev); - #ifdef CONFIG_NET_POLL_CONTROLLER dev->poll_controller = &ultra_poll; #endif diff --git a/drivers/net/smc-ultra32.c b/drivers/net/smc-ultra32.c index 88a30e56c64c..043a5002029c 100644 --- a/drivers/net/smc-ultra32.c +++ b/drivers/net/smc-ultra32.c @@ -132,8 +132,6 @@ struct net_device * __init ultra32_probe(int unit) netdev_boot_setup_check(dev); } - SET_MODULE_OWNER(dev); - irq = dev->irq; /* EISA spec allows for up to 16 slots, but 8 is typical. */ diff --git a/drivers/net/smc911x.c b/drivers/net/smc911x.c index db43e42bee35..5f03e44ad135 100644 --- a/drivers/net/smc911x.c +++ b/drivers/net/smc911x.c @@ -2181,7 +2181,6 @@ static int smc911x_drv_probe(struct platform_device *pdev) ret = -ENOMEM; goto release_1; } - SET_MODULE_OWNER(ndev); SET_NETDEV_DEV(ndev, &pdev->dev); ndev->dma = (unsigned char)-1; diff --git a/drivers/net/smc9194.c b/drivers/net/smc9194.c index 36c1ebadbf20..0a79516d196e 100644 --- a/drivers/net/smc9194.c +++ b/drivers/net/smc9194.c @@ -744,8 +744,6 @@ struct net_device * __init smc_init(int unit) irq = dev->irq; } - SET_MODULE_OWNER(dev); - if (io > 0x1ff) { /* Check a single specified location. */ err = smc_probe(dev, io); } else if (io != 0) { /* Don't probe at all. */ diff --git a/drivers/net/smc91x.c b/drivers/net/smc91x.c index 01cc3c742c38..c5837ab5c96b 100644 --- a/drivers/net/smc91x.c +++ b/drivers/net/smc91x.c @@ -2212,7 +2212,6 @@ static int smc_drv_probe(struct platform_device *pdev) ret = -ENOMEM; goto out_release_io; } - SET_MODULE_OWNER(ndev); SET_NETDEV_DEV(ndev, &pdev->dev); ndev->dma = (unsigned char)-1; diff --git a/drivers/net/spider_net.c b/drivers/net/spider_net.c index 6d8f2bb7e0f9..edc736eb3b86 100644 --- a/drivers/net/spider_net.c +++ b/drivers/net/spider_net.c @@ -2324,7 +2324,6 @@ spider_net_setup_netdev(struct spider_net_card *card) struct sockaddr addr; const u8 *mac; - SET_MODULE_OWNER(netdev); SET_NETDEV_DEV(netdev, &card->pdev->dev); pci_set_drvdata(card->pdev, netdev); diff --git a/drivers/net/starfire.c b/drivers/net/starfire.c index 3b9336c34206..5785429ca0e2 100644 --- a/drivers/net/starfire.c +++ b/drivers/net/starfire.c @@ -719,7 +719,6 @@ static int __devinit starfire_init_one(struct pci_dev *pdev, printk(KERN_ERR DRV_NAME " %d: cannot alloc etherdev, aborting\n", card_idx); return -ENOMEM; } - SET_MODULE_OWNER(dev); SET_NETDEV_DEV(dev, &pdev->dev); irq = pdev->irq; diff --git a/drivers/net/stnic.c b/drivers/net/stnic.c index e6f90427160c..b65be5d70fec 100644 --- a/drivers/net/stnic.c +++ b/drivers/net/stnic.c @@ -112,7 +112,6 @@ static int __init stnic_probe(void) dev = alloc_ei_netdev(); if (!dev) return -ENOMEM; - SET_MODULE_OWNER(dev); #ifdef CONFIG_SH_STANDARD_BIOS sh_bios_get_node_addr (stnic_eadr); diff --git a/drivers/net/sun3_82586.c b/drivers/net/sun3_82586.c index b77ab6e8fd35..9b2a7f7bb258 100644 --- a/drivers/net/sun3_82586.c +++ b/drivers/net/sun3_82586.c @@ -311,7 +311,6 @@ struct net_device * __init sun3_82586_probe(int unit) sprintf(dev->name, "eth%d", unit); netdev_boot_setup_check(dev); } - SET_MODULE_OWNER(dev); dev->irq = IE_IRQ; dev->base_addr = ioaddr; diff --git a/drivers/net/sun3lance.c b/drivers/net/sun3lance.c index f1548c033327..c67632dcac49 100644 --- a/drivers/net/sun3lance.c +++ b/drivers/net/sun3lance.c @@ -274,7 +274,6 @@ struct net_device * __init sun3lance_probe(int unit) sprintf(dev->name, "eth%d", unit); netdev_boot_setup_check(dev); } - SET_MODULE_OWNER(dev); if (!lance_probe(dev)) goto out; diff --git a/drivers/net/sunbmac.c b/drivers/net/sunbmac.c index b3e0158def4f..4ba3e4857e90 100644 --- a/drivers/net/sunbmac.c +++ b/drivers/net/sunbmac.c @@ -1087,7 +1087,6 @@ static int __init bigmac_ether_init(struct sbus_dev *qec_sdev) dev = alloc_etherdev(sizeof(struct bigmac)); if (!dev) return -ENOMEM; - SET_MODULE_OWNER(dev); if (version_printed++ == 0) printk(KERN_INFO "%s", version); diff --git a/drivers/net/sundance.c b/drivers/net/sundance.c index a8f2af8f778a..3c553dcc2b9d 100644 --- a/drivers/net/sundance.c +++ b/drivers/net/sundance.c @@ -485,7 +485,6 @@ static int __devinit sundance_probe1 (struct pci_dev *pdev, dev = alloc_etherdev(sizeof(*np)); if (!dev) return -ENOMEM; - SET_MODULE_OWNER(dev); SET_NETDEV_DEV(dev, &pdev->dev); if (pci_request_regions(pdev, DRV_NAME)) diff --git a/drivers/net/sungem.c b/drivers/net/sungem.c index bf821e96f7b2..869ac44c51f3 100644 --- a/drivers/net/sungem.c +++ b/drivers/net/sungem.c @@ -3023,7 +3023,6 @@ static int __devinit gem_init_one(struct pci_dev *pdev, err = -ENOMEM; goto err_disable_device; } - SET_MODULE_OWNER(dev); SET_NETDEV_DEV(dev, &pdev->dev); gp = dev->priv; diff --git a/drivers/net/sunhme.c b/drivers/net/sunhme.c index 8b35f13318ea..170580c13127 100644 --- a/drivers/net/sunhme.c +++ b/drivers/net/sunhme.c @@ -2680,7 +2680,6 @@ static int __devinit happy_meal_sbus_probe_one(struct sbus_dev *sdev, int is_qfe dev = alloc_etherdev(sizeof(struct happy_meal)); if (!dev) goto err_out; - SET_MODULE_OWNER(dev); SET_NETDEV_DEV(dev, &sdev->ofdev.dev); if (hme_version_printed++ == 0) @@ -3022,7 +3021,6 @@ static int __devinit happy_meal_pci_probe(struct pci_dev *pdev, err = -ENOMEM; if (!dev) goto err_out; - SET_MODULE_OWNER(dev); SET_NETDEV_DEV(dev, &pdev->dev); if (hme_version_printed++ == 0) diff --git a/drivers/net/sunlance.c b/drivers/net/sunlance.c index e94b752f9f34..17d66c1185cd 100644 --- a/drivers/net/sunlance.c +++ b/drivers/net/sunlance.c @@ -1457,7 +1457,6 @@ no_link_test: lp->dregs = NULL; lp->dev = dev; - SET_MODULE_OWNER(dev); SET_NETDEV_DEV(dev, &sdev->ofdev.dev); dev->open = &lance_open; dev->stop = &lance_close; diff --git a/drivers/net/sunqe.c b/drivers/net/sunqe.c index 1b65ae8a1c7c..b5c2974fd625 100644 --- a/drivers/net/sunqe.c +++ b/drivers/net/sunqe.c @@ -898,7 +898,6 @@ static int __init qec_ether_init(struct sbus_dev *sdev) /* Stop this QE. */ qe_stop(qe); - SET_MODULE_OWNER(dev); SET_NETDEV_DEV(dev, &sdev->ofdev.dev); dev->open = qe_open; diff --git a/drivers/net/tc35815.c b/drivers/net/tc35815.c index b5e0dff67230..df8237360f58 100644 --- a/drivers/net/tc35815.c +++ b/drivers/net/tc35815.c @@ -685,7 +685,6 @@ static int __devinit tc35815_init_one (struct pci_dev *pdev, dev_err(&pdev->dev, "unable to alloc new ethernet\n"); return -ENOMEM; } - SET_MODULE_OWNER(dev); SET_NETDEV_DEV(dev, &pdev->dev); lp = dev->priv; lp->dev = dev; diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index cbfa4df09592..369a172a04aa 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -11826,7 +11826,6 @@ static int __devinit tg3_init_one(struct pci_dev *pdev, goto err_out_free_res; } - SET_MODULE_OWNER(dev); SET_NETDEV_DEV(dev, &pdev->dev); #if TG3_VLAN_TAG_USED diff --git a/drivers/net/tlan.c b/drivers/net/tlan.c index 74eb12107e68..c99ce74a7aff 100644 --- a/drivers/net/tlan.c +++ b/drivers/net/tlan.c @@ -556,7 +556,6 @@ static int __devinit TLan_probe1(struct pci_dev *pdev, rc = -ENOMEM; goto err_out_regions; } - SET_MODULE_OWNER(dev); SET_NETDEV_DEV(dev, &pdev->dev); priv = netdev_priv(dev); diff --git a/drivers/net/tokenring/3c359.c b/drivers/net/tokenring/3c359.c index f4251d35599d..88d03c085d54 100644 --- a/drivers/net/tokenring/3c359.c +++ b/drivers/net/tokenring/3c359.c @@ -344,7 +344,6 @@ static int __devinit xl_probe(struct pci_dev *pdev, dev->set_multicast_list=&xl_set_rx_mode; dev->get_stats=&xl_get_stats ; dev->set_mac_address=&xl_set_mac_address ; - SET_MODULE_OWNER(dev); SET_NETDEV_DEV(dev, &pdev->dev); pci_set_drvdata(pdev,dev) ; diff --git a/drivers/net/tokenring/abyss.c b/drivers/net/tokenring/abyss.c index 1bdd3beefbe5..22fad5112406 100644 --- a/drivers/net/tokenring/abyss.c +++ b/drivers/net/tokenring/abyss.c @@ -116,8 +116,6 @@ static int __devinit abyss_attach(struct pci_dev *pdev, const struct pci_device_ if (!dev) return -ENOMEM; - SET_MODULE_OWNER(dev); - if (!request_region(pci_ioaddr, ABYSS_IO_EXTENT, dev->name)) { ret = -EBUSY; goto err_out_trdev; diff --git a/drivers/net/tokenring/lanstreamer.c b/drivers/net/tokenring/lanstreamer.c index 49c4270ef5f7..f114fb729f54 100644 --- a/drivers/net/tokenring/lanstreamer.c +++ b/drivers/net/tokenring/lanstreamer.c @@ -245,7 +245,6 @@ static int __devinit streamer_init_one(struct pci_dev *pdev, return -ENOMEM; } - SET_MODULE_OWNER(dev); streamer_priv = netdev_priv(dev); #if STREAMER_NETWORK_MONITOR diff --git a/drivers/net/tokenring/madgemc.c b/drivers/net/tokenring/madgemc.c index 9eafc2e25abc..d0ce2ce675d5 100644 --- a/drivers/net/tokenring/madgemc.c +++ b/drivers/net/tokenring/madgemc.c @@ -168,7 +168,6 @@ static int __devinit madgemc_probe(struct device *device) goto getout; } - SET_MODULE_OWNER(dev); dev->dma = 0; card = kmalloc(sizeof(struct card_info), GFP_KERNEL); diff --git a/drivers/net/tokenring/olympic.c b/drivers/net/tokenring/olympic.c index b57f65b2591a..a149d5e2965c 100644 --- a/drivers/net/tokenring/olympic.c +++ b/drivers/net/tokenring/olympic.c @@ -261,7 +261,6 @@ static int __devinit olympic_probe(struct pci_dev *pdev, const struct pci_device dev->set_multicast_list=&olympic_set_rx_mode; dev->get_stats=&olympic_get_stats ; dev->set_mac_address=&olympic_set_mac_address ; - SET_MODULE_OWNER(dev) ; SET_NETDEV_DEV(dev, &pdev->dev); pci_set_drvdata(pdev,dev) ; diff --git a/drivers/net/tokenring/proteon.c b/drivers/net/tokenring/proteon.c index cb7dbb63c9d9..85d156dea033 100644 --- a/drivers/net/tokenring/proteon.c +++ b/drivers/net/tokenring/proteon.c @@ -126,7 +126,6 @@ static int __init setup_card(struct net_device *dev, struct device *pdev) if (!dev) return -ENOMEM; - SET_MODULE_OWNER(dev); if (dev->base_addr) /* probe specific location */ err = proteon_probe1(dev, dev->base_addr); else { diff --git a/drivers/net/tokenring/skisa.c b/drivers/net/tokenring/skisa.c index 33afea31d87b..ecbddc80a2a5 100644 --- a/drivers/net/tokenring/skisa.c +++ b/drivers/net/tokenring/skisa.c @@ -143,7 +143,6 @@ static int __init setup_card(struct net_device *dev, struct device *pdev) if (!dev) return -ENOMEM; - SET_MODULE_OWNER(dev); if (dev->base_addr) /* probe specific location */ err = sk_isa_probe1(dev, dev->base_addr); else { diff --git a/drivers/net/tokenring/smctr.c b/drivers/net/tokenring/smctr.c index f83bb5cb0d3d..93da3a36cde8 100644 --- a/drivers/net/tokenring/smctr.c +++ b/drivers/net/tokenring/smctr.c @@ -3583,8 +3583,6 @@ struct net_device __init *smctr_probe(int unit) if (!dev) return ERR_PTR(-ENOMEM); - SET_MODULE_OWNER(dev); - if (unit >= 0) { sprintf(dev->name, "tr%d", unit); netdev_boot_setup_check(dev); diff --git a/drivers/net/tokenring/tmspci.c b/drivers/net/tokenring/tmspci.c index aec75c930c21..ecdd8511a67b 100644 --- a/drivers/net/tokenring/tmspci.c +++ b/drivers/net/tokenring/tmspci.c @@ -115,7 +115,6 @@ static int __devinit tms_pci_attach(struct pci_dev *pdev, const struct pci_devic dev = alloc_trdev(sizeof(struct net_local)); if (!dev) return -ENOMEM; - SET_MODULE_OWNER(dev); if (!request_region(pci_ioaddr, TMS_PCI_IO_EXTENT, dev->name)) { ret = -EBUSY; diff --git a/drivers/net/tsi108_eth.c b/drivers/net/tsi108_eth.c index a1d305b9b12a..fe3225df0d32 100644 --- a/drivers/net/tsi108_eth.c +++ b/drivers/net/tsi108_eth.c @@ -1607,7 +1607,6 @@ tsi108_init_one(struct platform_device *pdev) */ dev->features = NETIF_F_HIGHDMA; - SET_MODULE_OWNER(dev); spin_lock_init(&data->txlock); spin_lock_init(&data->misclock); diff --git a/drivers/net/tulip/de2104x.c b/drivers/net/tulip/de2104x.c index d380e0b3f05a..bd04e93908ef 100644 --- a/drivers/net/tulip/de2104x.c +++ b/drivers/net/tulip/de2104x.c @@ -1944,7 +1944,6 @@ static int __devinit de_init_one (struct pci_dev *pdev, if (!dev) return -ENOMEM; - SET_MODULE_OWNER(dev); SET_NETDEV_DEV(dev, &pdev->dev); dev->open = de_open; dev->stop = de_close; diff --git a/drivers/net/tulip/de4x5.c b/drivers/net/tulip/de4x5.c index 09902891a6e6..ba7f47c2dcff 100644 --- a/drivers/net/tulip/de4x5.c +++ b/drivers/net/tulip/de4x5.c @@ -1261,7 +1261,6 @@ de4x5_hw_init(struct net_device *dev, u_long iobase, struct device *gendev) } /* The DE4X5-specific entries in the device structure. */ - SET_MODULE_OWNER(dev); SET_NETDEV_DEV(dev, gendev); dev->open = &de4x5_open; dev->hard_start_xmit = &de4x5_queue_pkt; diff --git a/drivers/net/tulip/dmfe.c b/drivers/net/tulip/dmfe.c index dab74feb44bc..e2596e9ab1d7 100644 --- a/drivers/net/tulip/dmfe.c +++ b/drivers/net/tulip/dmfe.c @@ -372,7 +372,6 @@ static int __devinit dmfe_init_one (struct pci_dev *pdev, dev = alloc_etherdev(sizeof(*db)); if (dev == NULL) return -ENOMEM; - SET_MODULE_OWNER(dev); SET_NETDEV_DEV(dev, &pdev->dev); if (pci_set_dma_mask(pdev, DMA_32BIT_MASK)) { diff --git a/drivers/net/tulip/tulip_core.c b/drivers/net/tulip/tulip_core.c index 7040a59fa3c9..66977aaa7176 100644 --- a/drivers/net/tulip/tulip_core.c +++ b/drivers/net/tulip/tulip_core.c @@ -1345,7 +1345,6 @@ static int __devinit tulip_init_one (struct pci_dev *pdev, return -ENOMEM; } - SET_MODULE_OWNER(dev); SET_NETDEV_DEV(dev, &pdev->dev); if (pci_resource_len (pdev, 0) < tulip_tbl[chip_idx].io_size) { printk (KERN_ERR PFX "%s: I/O region (0x%llx@0x%llx) too small, " diff --git a/drivers/net/tulip/uli526x.c b/drivers/net/tulip/uli526x.c index e26ce44561c4..2b7257d97c32 100644 --- a/drivers/net/tulip/uli526x.c +++ b/drivers/net/tulip/uli526x.c @@ -268,7 +268,6 @@ static int __devinit uli526x_init_one (struct pci_dev *pdev, dev = alloc_etherdev(sizeof(*db)); if (dev == NULL) return -ENOMEM; - SET_MODULE_OWNER(dev); SET_NETDEV_DEV(dev, &pdev->dev); if (pci_set_dma_mask(pdev, DMA_32BIT_MASK)) { diff --git a/drivers/net/tulip/winbond-840.c b/drivers/net/tulip/winbond-840.c index 5824f6a35495..396f8455cd32 100644 --- a/drivers/net/tulip/winbond-840.c +++ b/drivers/net/tulip/winbond-840.c @@ -370,7 +370,6 @@ static int __devinit w840_probe1 (struct pci_dev *pdev, dev = alloc_etherdev(sizeof(*np)); if (!dev) return -ENOMEM; - SET_MODULE_OWNER(dev); SET_NETDEV_DEV(dev, &pdev->dev); if (pci_request_regions(pdev, DRV_NAME)) diff --git a/drivers/net/tulip/xircom_cb.c b/drivers/net/tulip/xircom_cb.c index 4b239dcbef74..de8c92083e92 100644 --- a/drivers/net/tulip/xircom_cb.c +++ b/drivers/net/tulip/xircom_cb.c @@ -252,7 +252,6 @@ static int __devinit xircom_probe(struct pci_dev *pdev, const struct pci_device_ goto tx_buf_fail; } - SET_MODULE_OWNER(dev); SET_NETDEV_DEV(dev, &pdev->dev); diff --git a/drivers/net/tulip/xircom_tulip_cb.c b/drivers/net/tulip/xircom_tulip_cb.c index fc439f333350..c3f8e303c6c7 100644 --- a/drivers/net/tulip/xircom_tulip_cb.c +++ b/drivers/net/tulip/xircom_tulip_cb.c @@ -547,7 +547,6 @@ static int __devinit xircom_init_one(struct pci_dev *pdev, const struct pci_devi printk (KERN_ERR DRV_NAME "%d: cannot alloc etherdev, aborting\n", board_idx); return -ENOMEM; } - SET_MODULE_OWNER(dev); SET_NETDEV_DEV(dev, &pdev->dev); dev->base_addr = ioaddr; diff --git a/drivers/net/tun.c b/drivers/net/tun.c index 691d264fbb6f..8b3ec335385c 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c @@ -435,7 +435,6 @@ static void tun_setup(struct net_device *dev) tun->owner = -1; tun->group = -1; - SET_MODULE_OWNER(dev); dev->open = tun_net_open; dev->hard_start_xmit = tun_net_xmit; dev->stop = tun_net_close; diff --git a/drivers/net/typhoon.c b/drivers/net/typhoon.c index 0377b8b64c78..84d99fc77891 100644 --- a/drivers/net/typhoon.c +++ b/drivers/net/typhoon.c @@ -2332,7 +2332,6 @@ typhoon_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) err = -ENOMEM; goto error_out; } - SET_MODULE_OWNER(dev); SET_NETDEV_DEV(dev, &pdev->dev); err = pci_enable_device(pdev); diff --git a/drivers/net/ucc_geth.c b/drivers/net/ucc_geth.c index 72f617bf2520..8da41229594a 100644 --- a/drivers/net/ucc_geth.c +++ b/drivers/net/ucc_geth.c @@ -3957,7 +3957,6 @@ static int ucc_geth_probe(struct of_device* ofdev, const struct of_device_id *ma /* Set the dev->base_addr to the gfar reg region */ dev->base_addr = (unsigned long)(ug_info->uf_info.regs); - SET_MODULE_OWNER(dev); SET_NETDEV_DEV(dev, device); /* Fill in the dev structure */ diff --git a/drivers/net/usb/kaweth.c b/drivers/net/usb/kaweth.c index 524dc5f5e46d..58a53a641754 100644 --- a/drivers/net/usb/kaweth.c +++ b/drivers/net/usb/kaweth.c @@ -1152,8 +1152,6 @@ err_fw: INIT_DELAYED_WORK(&kaweth->lowmem_work, kaweth_resubmit_tl); - SET_MODULE_OWNER(netdev); - usb_set_intfdata(intf, kaweth); #if 0 diff --git a/drivers/net/usb/pegasus.c b/drivers/net/usb/pegasus.c index 06838928ef47..432a2f054468 100644 --- a/drivers/net/usb/pegasus.c +++ b/drivers/net/usb/pegasus.c @@ -1321,7 +1321,6 @@ static int pegasus_probe(struct usb_interface *intf, pegasus->intf = intf; pegasus->usb = dev; pegasus->net = net; - SET_MODULE_OWNER(net); net->open = pegasus_open; net->stop = pegasus_close; net->watchdog_timeo = PEGASUS_TX_TIMEOUT; diff --git a/drivers/net/usb/rtl8150.c b/drivers/net/usb/rtl8150.c index 3b3a57ea2676..33cbc306226c 100644 --- a/drivers/net/usb/rtl8150.c +++ b/drivers/net/usb/rtl8150.c @@ -917,7 +917,6 @@ static int rtl8150_probe(struct usb_interface *intf, dev->udev = udev; dev->netdev = netdev; - SET_MODULE_OWNER(netdev); netdev->open = rtl8150_open; netdev->stop = rtl8150_close; netdev->do_ioctl = rtl8150_ioctl; diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c index 3034d1aea376..3542ca5fb0fa 100644 --- a/drivers/net/usb/usbnet.c +++ b/drivers/net/usb/usbnet.c @@ -1173,7 +1173,6 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod) init_timer (&dev->delay); mutex_init (&dev->phy_mutex); - SET_MODULE_OWNER (net); dev->net = net; strcpy (net->name, "usb%d"); memcpy (net->dev_addr, node_id, sizeof node_id); diff --git a/drivers/net/via-rhine.c b/drivers/net/via-rhine.c index 7a5899059c44..987f5b937e3c 100644 --- a/drivers/net/via-rhine.c +++ b/drivers/net/via-rhine.c @@ -702,7 +702,6 @@ static int __devinit rhine_init_one(struct pci_dev *pdev, printk(KERN_ERR "alloc_etherdev failed\n"); goto err_out; } - SET_MODULE_OWNER(dev); SET_NETDEV_DEV(dev, &pdev->dev); rp = netdev_priv(dev); diff --git a/drivers/net/via-velocity.c b/drivers/net/via-velocity.c index a4729bc385f4..511a74c6e78b 100644 --- a/drivers/net/via-velocity.c +++ b/drivers/net/via-velocity.c @@ -712,7 +712,6 @@ static int __devinit velocity_found1(struct pci_dev *pdev, const struct pci_devi /* Chain it all together */ - SET_MODULE_OWNER(dev); SET_NETDEV_DEV(dev, &pdev->dev); vptr = netdev_priv(dev); diff --git a/drivers/net/wan/c101.c b/drivers/net/wan/c101.c index 8ead774d14c8..c4c8eab8574f 100644 --- a/drivers/net/wan/c101.c +++ b/drivers/net/wan/c101.c @@ -363,7 +363,6 @@ static int __init c101_run(unsigned long irq, unsigned long winbase) hdlc = dev_to_hdlc(dev); spin_lock_init(&card->lock); - SET_MODULE_OWNER(dev); dev->irq = irq; dev->mem_start = winbase; dev->mem_end = winbase + C101_MAPPED_RAM_SIZE - 1; diff --git a/drivers/net/wan/cycx_x25.c b/drivers/net/wan/cycx_x25.c index a8af28b273d3..46e053106d4d 100644 --- a/drivers/net/wan/cycx_x25.c +++ b/drivers/net/wan/cycx_x25.c @@ -508,7 +508,6 @@ static int cycx_netdevice_init(struct net_device *dev) /* Set transmit buffer queue length */ dev->tx_queue_len = 10; - SET_MODULE_OWNER(dev); /* Initialize socket buffers */ cycx_x25_set_chan_state(dev, WAN_DISCONNECTED); diff --git a/drivers/net/wan/dscc4.c b/drivers/net/wan/dscc4.c index 50d2f9108dca..33dc713b5301 100644 --- a/drivers/net/wan/dscc4.c +++ b/drivers/net/wan/dscc4.c @@ -925,7 +925,6 @@ static int dscc4_found1(struct pci_dev *pdev, void __iomem *ioaddr) d->do_ioctl = dscc4_ioctl; d->tx_timeout = dscc4_tx_timeout; d->watchdog_timeo = TX_TIMEOUT; - SET_MODULE_OWNER(d); SET_NETDEV_DEV(d, &pdev->dev); dpriv->dev_id = i; diff --git a/drivers/net/wan/hostess_sv11.c b/drivers/net/wan/hostess_sv11.c index bf5f8d9b5c83..83dbc924fcb5 100644 --- a/drivers/net/wan/hostess_sv11.c +++ b/drivers/net/wan/hostess_sv11.c @@ -241,8 +241,6 @@ static struct sv11_device *sv11_init(int iobase, int irq) if(!sv->netdev.dev) goto fail2; - SET_MODULE_OWNER(sv->netdev.dev); - dev=&sv->sync; /* diff --git a/drivers/net/wan/lapbether.c b/drivers/net/wan/lapbether.c index 699b93406dfb..36e683ccae5e 100644 --- a/drivers/net/wan/lapbether.c +++ b/drivers/net/wan/lapbether.c @@ -329,7 +329,6 @@ static void lapbeth_setup(struct net_device *dev) dev->hard_header_len = 3; dev->mtu = 1000; dev->addr_len = 0; - SET_MODULE_OWNER(dev); } /* diff --git a/drivers/net/wan/lmc/lmc_main.c b/drivers/net/wan/lmc/lmc_main.c index ae132c1c5459..5ea877221f46 100644 --- a/drivers/net/wan/lmc/lmc_main.c +++ b/drivers/net/wan/lmc/lmc_main.c @@ -883,7 +883,6 @@ static int __devinit lmc_init_one(struct pci_dev *pdev, dev->base_addr = pci_resource_start(pdev, 0); dev->irq = pdev->irq; - SET_MODULE_OWNER(dev); SET_NETDEV_DEV(dev, &pdev->dev); /* diff --git a/drivers/net/wan/n2.c b/drivers/net/wan/n2.c index cbdf0b748bde..0a566b0daacb 100644 --- a/drivers/net/wan/n2.c +++ b/drivers/net/wan/n2.c @@ -459,7 +459,6 @@ static int __init n2_run(unsigned long io, unsigned long irq, port->log_node = 1; spin_lock_init(&port->lock); - SET_MODULE_OWNER(dev); dev->irq = irq; dev->mem_start = winbase; dev->mem_end = winbase + USE_WINDOWSIZE - 1; diff --git a/drivers/net/wan/pc300too.c b/drivers/net/wan/pc300too.c index 6353cb5c658d..bf1b01590429 100644 --- a/drivers/net/wan/pc300too.c +++ b/drivers/net/wan/pc300too.c @@ -468,7 +468,6 @@ static int __devinit pc300_pci_init_one(struct pci_dev *pdev, port->phy_node = i; spin_lock_init(&port->lock); - SET_MODULE_OWNER(dev); dev->irq = card->irq; dev->mem_start = ramphys; dev->mem_end = ramphys + ramsize - 1; diff --git a/drivers/net/wan/pci200syn.c b/drivers/net/wan/pci200syn.c index 092e51d89036..b595b64e7538 100644 --- a/drivers/net/wan/pci200syn.c +++ b/drivers/net/wan/pci200syn.c @@ -415,7 +415,6 @@ static int __devinit pci200_pci_init_one(struct pci_dev *pdev, port->phy_node = i; spin_lock_init(&port->lock); - SET_MODULE_OWNER(dev); dev->irq = card->irq; dev->mem_start = ramphys; dev->mem_end = ramphys + ramsize - 1; diff --git a/drivers/net/wan/sbni.c b/drivers/net/wan/sbni.c index 8d7e01e8f56f..76db40d200d8 100644 --- a/drivers/net/wan/sbni.c +++ b/drivers/net/wan/sbni.c @@ -216,8 +216,6 @@ static void __init sbni_devsetup(struct net_device *dev) dev->get_stats = &sbni_get_stats; dev->set_multicast_list = &set_multicast_list; dev->do_ioctl = &sbni_ioctl; - - SET_MODULE_OWNER( dev ); } int __init sbni_probe(int unit) diff --git a/drivers/net/wan/sdla.c b/drivers/net/wan/sdla.c index 792e588d7d61..b39a541b2509 100644 --- a/drivers/net/wan/sdla.c +++ b/drivers/net/wan/sdla.c @@ -1603,7 +1603,6 @@ static void setup_sdla(struct net_device *dev) netdev_boot_setup_check(dev); - SET_MODULE_OWNER(dev); dev->flags = 0; dev->type = 0xFFFF; dev->hard_header_len = 0; diff --git a/drivers/net/wan/wanxl.c b/drivers/net/wan/wanxl.c index 3c78f9856380..8e320b76ae0e 100644 --- a/drivers/net/wan/wanxl.c +++ b/drivers/net/wan/wanxl.c @@ -779,7 +779,6 @@ static int __devinit wanxl_pci_init_one(struct pci_dev *pdev, port->dev = dev; hdlc = dev_to_hdlc(dev); spin_lock_init(&port->lock); - SET_MODULE_OWNER(dev); dev->tx_queue_len = 50; dev->do_ioctl = wanxl_ioctl; dev->open = wanxl_open; diff --git a/drivers/net/wd.c b/drivers/net/wd.c index a0326818ff2f..cef365881ac2 100644 --- a/drivers/net/wd.c +++ b/drivers/net/wd.c @@ -93,8 +93,6 @@ static int __init do_wd_probe(struct net_device *dev) int mem_start = dev->mem_start; int mem_end = dev->mem_end; - SET_MODULE_OWNER(dev); - if (base_addr > 0x1ff) { /* Check a user specified location. */ r = request_region(base_addr, WD_IO_EXTENT, "wd-probe"); if ( r == NULL) diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c index a152797b951a..80ae75999536 100644 --- a/drivers/net/wireless/airo.c +++ b/drivers/net/wireless/airo.c @@ -2870,7 +2870,6 @@ static struct net_device *_init_airo_card( unsigned short irq, int port, dev->base_addr = port; SET_NETDEV_DEV(dev, dmdev); - SET_MODULE_OWNER(dev); reset_card (dev, 1); msleep(400); diff --git a/drivers/net/wireless/airport.c b/drivers/net/wireless/airport.c index 7d5b8c2cc614..6f7eb9f59223 100644 --- a/drivers/net/wireless/airport.c +++ b/drivers/net/wireless/airport.c @@ -197,7 +197,6 @@ airport_attach(struct macio_dev *mdev, const struct of_device_id *match) return -EBUSY; } - SET_MODULE_OWNER(dev); SET_NETDEV_DEV(dev, &mdev->ofdev.dev); macio_set_drvdata(mdev, dev); diff --git a/drivers/net/wireless/arlan-main.c b/drivers/net/wireless/arlan-main.c index 498e8486d125..3eaaab0ba0cc 100644 --- a/drivers/net/wireless/arlan-main.c +++ b/drivers/net/wireless/arlan-main.c @@ -1792,8 +1792,6 @@ struct net_device * __init arlan_probe(int unit) if (!dev) return ERR_PTR(-ENOMEM); - SET_MODULE_OWNER(dev); - if (unit >= 0) { sprintf(dev->name, "eth%d", unit); netdev_boot_setup_check(dev); diff --git a/drivers/net/wireless/atmel.c b/drivers/net/wireless/atmel.c index 51a7db53afa5..47dbdf95ea6f 100644 --- a/drivers/net/wireless/atmel.c +++ b/drivers/net/wireless/atmel.c @@ -1603,7 +1603,6 @@ struct net_device *init_atmel_card(unsigned short irq, unsigned long port, dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2], dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5] ); - SET_MODULE_OWNER(dev); return dev; err_out_res: diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_main.c b/drivers/net/wireless/bcm43xx/bcm43xx_main.c index dfbd01eaaf34..e038d072398d 100644 --- a/drivers/net/wireless/bcm43xx/bcm43xx_main.c +++ b/drivers/net/wireless/bcm43xx/bcm43xx_main.c @@ -4092,7 +4092,6 @@ static int __devinit bcm43xx_init_one(struct pci_dev *pdev, goto out; } /* initialize the net_device struct */ - SET_MODULE_OWNER(net_dev); SET_NETDEV_DEV(net_dev, &pdev->dev); net_dev->open = bcm43xx_net_open; diff --git a/drivers/net/wireless/ipw2100.c b/drivers/net/wireless/ipw2100.c index 8990585bd228..12a6887cb9f1 100644 --- a/drivers/net/wireless/ipw2100.c +++ b/drivers/net/wireless/ipw2100.c @@ -6239,8 +6239,6 @@ static int ipw2100_pci_init_one(struct pci_dev *pci_dev, IPW_DEBUG_INFO("Attempting to register device...\n"); - SET_MODULE_OWNER(dev); - printk(KERN_INFO DRV_NAME ": Detected Intel PRO/Wireless 2100 Network Connection\n"); diff --git a/drivers/net/wireless/ipw2200.c b/drivers/net/wireless/ipw2200.c index 61497c467467..afad8bb7e334 100644 --- a/drivers/net/wireless/ipw2200.c +++ b/drivers/net/wireless/ipw2200.c @@ -11625,7 +11625,6 @@ static int ipw_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) goto out_destroy_workqueue; } - SET_MODULE_OWNER(net_dev); SET_NETDEV_DEV(net_dev, &pdev->dev); mutex_lock(&priv->mutex); diff --git a/drivers/net/wireless/libertas/main.c b/drivers/net/wireless/libertas/main.c index 3feddcc750ed..cb0359df355e 100644 --- a/drivers/net/wireless/libertas/main.c +++ b/drivers/net/wireless/libertas/main.c @@ -1157,8 +1157,6 @@ wlan_private *libertas_add_card(void *card, struct device *dmdev) priv->infra_open = 0; priv->hotplug_device = dmdev; - SET_MODULE_OWNER(dev); - /* Setup the OS Interface to our functions */ dev->open = libertas_open; dev->hard_start_xmit = libertas_pre_start_xmit; @@ -1340,8 +1338,6 @@ int libertas_add_mesh(wlan_private *priv, struct device *dev) mesh_dev->priv = priv; priv->mesh_dev = mesh_dev; - SET_MODULE_OWNER(mesh_dev); - mesh_dev->open = libertas_mesh_open; mesh_dev->hard_start_xmit = libertas_mesh_pre_start_xmit; mesh_dev->stop = libertas_mesh_close; diff --git a/drivers/net/wireless/netwave_cs.c b/drivers/net/wireless/netwave_cs.c index 45b00e13ab2b..389fdd313c7e 100644 --- a/drivers/net/wireless/netwave_cs.c +++ b/drivers/net/wireless/netwave_cs.c @@ -412,7 +412,6 @@ static int netwave_probe(struct pcmcia_device *link) spin_lock_init(&priv->spinlock); /* Netwave specific entries in the device structure */ - SET_MODULE_OWNER(dev); dev->hard_start_xmit = &netwave_start_xmit; dev->get_stats = &netwave_get_stats; dev->set_multicast_list = &set_multicast_list; diff --git a/drivers/net/wireless/orinoco_cs.c b/drivers/net/wireless/orinoco_cs.c index d1e502236b2a..8b7f5768a103 100644 --- a/drivers/net/wireless/orinoco_cs.c +++ b/drivers/net/wireless/orinoco_cs.c @@ -313,7 +313,6 @@ orinoco_cs_config(struct pcmcia_device *link) /* Ok, we have the configuration, prepare to register the netdev */ dev->base_addr = link->io.BasePort1; dev->irq = link->irq.AssignedIRQ; - SET_MODULE_OWNER(dev); card->node.major = card->node.minor = 0; SET_NETDEV_DEV(dev, &handle_to_dev(link)); diff --git a/drivers/net/wireless/orinoco_nortel.c b/drivers/net/wireless/orinoco_nortel.c index eaf3d13b851c..35ec5fcf81a6 100644 --- a/drivers/net/wireless/orinoco_nortel.c +++ b/drivers/net/wireless/orinoco_nortel.c @@ -193,7 +193,6 @@ static int orinoco_nortel_init_one(struct pci_dev *pdev, card = priv->card; card->bridge_io = bridge_io; card->attr_io = attr_io; - SET_MODULE_OWNER(dev); SET_NETDEV_DEV(dev, &pdev->dev); hermes_struct_init(&priv->hw, hermes_io, HERMES_16BIT_REGSPACING); diff --git a/drivers/net/wireless/orinoco_pci.c b/drivers/net/wireless/orinoco_pci.c index 97a8b4ff32bd..2547d5dac0d3 100644 --- a/drivers/net/wireless/orinoco_pci.c +++ b/drivers/net/wireless/orinoco_pci.c @@ -148,7 +148,6 @@ static int orinoco_pci_init_one(struct pci_dev *pdev, priv = netdev_priv(dev); card = priv->card; - SET_MODULE_OWNER(dev); SET_NETDEV_DEV(dev, &pdev->dev); hermes_struct_init(&priv->hw, hermes_io, HERMES_32BIT_REGSPACING); diff --git a/drivers/net/wireless/orinoco_plx.c b/drivers/net/wireless/orinoco_plx.c index 31162ac25a92..98fe165337d1 100644 --- a/drivers/net/wireless/orinoco_plx.c +++ b/drivers/net/wireless/orinoco_plx.c @@ -232,7 +232,6 @@ static int orinoco_plx_init_one(struct pci_dev *pdev, card = priv->card; card->bridge_io = bridge_io; card->attr_io = attr_io; - SET_MODULE_OWNER(dev); SET_NETDEV_DEV(dev, &pdev->dev); hermes_struct_init(&priv->hw, hermes_io, HERMES_16BIT_REGSPACING); diff --git a/drivers/net/wireless/orinoco_tmd.c b/drivers/net/wireless/orinoco_tmd.c index b9c54d8fceb9..df493185a4af 100644 --- a/drivers/net/wireless/orinoco_tmd.c +++ b/drivers/net/wireless/orinoco_tmd.c @@ -134,7 +134,6 @@ static int orinoco_tmd_init_one(struct pci_dev *pdev, priv = netdev_priv(dev); card = priv->card; card->bridge_io = bridge_io; - SET_MODULE_OWNER(dev); SET_NETDEV_DEV(dev, &pdev->dev); hermes_struct_init(&priv->hw, hermes_io, HERMES_16BIT_REGSPACING); diff --git a/drivers/net/wireless/prism54/islpci_dev.c b/drivers/net/wireless/prism54/islpci_dev.c index 084795355b74..219dd651dc41 100644 --- a/drivers/net/wireless/prism54/islpci_dev.c +++ b/drivers/net/wireless/prism54/islpci_dev.c @@ -808,7 +808,6 @@ islpci_setup(struct pci_dev *pdev) if (!ndev) return ndev; - SET_MODULE_OWNER(ndev); pci_set_drvdata(pdev, ndev); #if defined(SET_NETDEV_DEV) SET_NETDEV_DEV(ndev, &pdev->dev); diff --git a/drivers/net/wireless/ray_cs.c b/drivers/net/wireless/ray_cs.c index 1d9dbf830015..1b0e9707049a 100644 --- a/drivers/net/wireless/ray_cs.c +++ b/drivers/net/wireless/ray_cs.c @@ -356,7 +356,6 @@ static int ray_probe(struct pcmcia_device *p_dev) dev->set_multicast_list = &set_multicast_list; DEBUG(2,"ray_cs ray_attach calling ether_setup.)\n"); - SET_MODULE_OWNER(dev); dev->init = &ray_dev_init; dev->open = &ray_open; dev->stop = &ray_dev_close; diff --git a/drivers/net/wireless/spectrum_cs.c b/drivers/net/wireless/spectrum_cs.c index af70460f008a..98df9bc7836a 100644 --- a/drivers/net/wireless/spectrum_cs.c +++ b/drivers/net/wireless/spectrum_cs.c @@ -782,7 +782,6 @@ spectrum_cs_config(struct pcmcia_device *link) /* Ok, we have the configuration, prepare to register the netdev */ dev->base_addr = link->io.BasePort1; dev->irq = link->irq.AssignedIRQ; - SET_MODULE_OWNER(dev); card->node.major = card->node.minor = 0; /* Reset card and download firmware */ diff --git a/drivers/net/wireless/strip.c b/drivers/net/wireless/strip.c index c49d5a1f94a2..404cd1512312 100644 --- a/drivers/net/wireless/strip.c +++ b/drivers/net/wireless/strip.c @@ -2508,8 +2508,6 @@ static void strip_dev_setup(struct net_device *dev) * Finish setting up the DEVICE info. */ - SET_MODULE_OWNER(dev); - dev->trans_start = 0; dev->last_rx = 0; dev->tx_queue_len = 30; /* Drop after 30 frames queued */ diff --git a/drivers/net/wireless/wavelan.c b/drivers/net/wireless/wavelan.c index 1cf090d60edc..b876bf65935b 100644 --- a/drivers/net/wireless/wavelan.c +++ b/drivers/net/wireless/wavelan.c @@ -4177,7 +4177,6 @@ static int __init wavelan_config(struct net_device *dev, unsigned short ioaddr) /* Init spinlock */ spin_lock_init(&lp->spinlock); - SET_MODULE_OWNER(dev); dev->open = wavelan_open; dev->stop = wavelan_close; dev->hard_start_xmit = wavelan_packet_xmit; diff --git a/drivers/net/wireless/wavelan_cs.c b/drivers/net/wireless/wavelan_cs.c index 5740d4d4267c..1cc5180ab1e7 100644 --- a/drivers/net/wireless/wavelan_cs.c +++ b/drivers/net/wireless/wavelan_cs.c @@ -4577,7 +4577,6 @@ wavelan_probe(struct pcmcia_device *p_dev) lp->dev = dev; /* wavelan NET3 callbacks */ - SET_MODULE_OWNER(dev); dev->open = &wavelan_open; dev->stop = &wavelan_close; dev->hard_start_xmit = &wavelan_packet_xmit; diff --git a/drivers/net/wireless/wl3501_cs.c b/drivers/net/wireless/wl3501_cs.c index 732b59f19892..cfde68cff94c 100644 --- a/drivers/net/wireless/wl3501_cs.c +++ b/drivers/net/wireless/wl3501_cs.c @@ -2003,8 +2003,6 @@ static int wl3501_config(struct pcmcia_device *link) goto failed; } - SET_MODULE_OWNER(dev); - this = netdev_priv(dev); /* * At this point, the dev_node_t structure(s) should be initialized and diff --git a/drivers/net/wireless/zd1211rw/zd_netdev.c b/drivers/net/wireless/zd1211rw/zd_netdev.c index 8bda48de31ef..047cab3d87df 100644 --- a/drivers/net/wireless/zd1211rw/zd_netdev.c +++ b/drivers/net/wireless/zd1211rw/zd_netdev.c @@ -233,7 +233,6 @@ struct net_device *zd_netdev_alloc(struct usb_interface *intf) return NULL; } - SET_MODULE_OWNER(netdev); SET_NETDEV_DEV(netdev, &intf->dev); dev_dbg_f(&intf->dev, "netdev->flags %#06hx\n", netdev->flags); diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c index b4de126825e4..8eeb068dc4a6 100644 --- a/drivers/net/xen-netfront.c +++ b/drivers/net/xen-netfront.c @@ -1176,7 +1176,6 @@ static struct net_device * __devinit xennet_create_dev(struct xenbus_device *dev netdev->features = NETIF_F_IP_CSUM; SET_ETHTOOL_OPS(netdev, &xennet_ethtool_ops); - SET_MODULE_OWNER(netdev); SET_NETDEV_DEV(netdev, &dev->dev); np->netdev = netdev; diff --git a/drivers/net/yellowfin.c b/drivers/net/yellowfin.c index 870c5393c21a..29e96950be65 100644 --- a/drivers/net/yellowfin.c +++ b/drivers/net/yellowfin.c @@ -392,7 +392,6 @@ static int __devinit yellowfin_init_one(struct pci_dev *pdev, printk (KERN_ERR PFX "cannot allocate ethernet device\n"); return -ENOMEM; } - SET_MODULE_OWNER(dev); SET_NETDEV_DEV(dev, &pdev->dev); np = netdev_priv(dev); diff --git a/drivers/net/znet.c b/drivers/net/znet.c index 4032e9f6f9b0..dcd4e1b136b5 100644 --- a/drivers/net/znet.c +++ b/drivers/net/znet.c @@ -388,8 +388,6 @@ static int __init znet_probe (void) if (!dev) return -ENOMEM; - SET_MODULE_OWNER (dev); - znet = dev->priv; netinfo = (struct netidblk *)p; diff --git a/drivers/net/zorro8390.c b/drivers/net/zorro8390.c index d85e2ea0b6af..a45f9952a3f7 100644 --- a/drivers/net/zorro8390.c +++ b/drivers/net/zorro8390.c @@ -125,7 +125,6 @@ static int __devinit zorro8390_init_one(struct zorro_dev *z, dev = ____alloc_ei_netdev(0); if (!dev) return -ENOMEM; - SET_MODULE_OWNER(dev); if (!request_mem_region(ioaddr, NE_IO_EXTENT*2, DRV_NAME)) { free_netdev(dev); return -EBUSY; diff --git a/drivers/s390/net/claw.c b/drivers/s390/net/claw.c index 023455a0b34a..399695f7b1af 100644 --- a/drivers/s390/net/claw.c +++ b/drivers/s390/net/claw.c @@ -3891,7 +3891,6 @@ claw_init_netdevice(struct net_device * dev) dev->type = ARPHRD_SLIP; dev->tx_queue_len = 1300; dev->flags = IFF_POINTOPOINT | IFF_NOARP; - SET_MODULE_OWNER(dev); #ifdef FUNCTRACE printk(KERN_INFO "%s:%s Exit\n",dev->name,__FUNCTION__); #endif diff --git a/drivers/s390/net/ctcmain.c b/drivers/s390/net/ctcmain.c index 92e8a37b5022..449937233732 100644 --- a/drivers/s390/net/ctcmain.c +++ b/drivers/s390/net/ctcmain.c @@ -2823,7 +2823,6 @@ ctc_init_netdevice(struct net_device * dev, int alloc_device, dev->type = ARPHRD_SLIP; dev->tx_queue_len = 100; dev->flags = IFF_POINTOPOINT | IFF_NOARP; - SET_MODULE_OWNER(dev); return dev; } diff --git a/drivers/s390/net/lcs.c b/drivers/s390/net/lcs.c index 08a994fdd1a4..e4b11afbbc9f 100644 --- a/drivers/s390/net/lcs.c +++ b/drivers/s390/net/lcs.c @@ -2145,7 +2145,6 @@ lcs_new_device(struct ccwgroup_device *ccwgdev) card->dev->stop = lcs_stop_device; card->dev->hard_start_xmit = lcs_start_xmit; card->dev->get_stats = lcs_getstats; - SET_MODULE_OWNER(dev); memcpy(card->dev->dev_addr, card->mac, LCS_MAC_LENGTH); #ifdef CONFIG_IP_MULTICAST if (!lcs_check_multicast_support(card)) diff --git a/drivers/s390/net/netiucv.c b/drivers/s390/net/netiucv.c index 268889474339..4d18d6419ddc 100644 --- a/drivers/s390/net/netiucv.c +++ b/drivers/s390/net/netiucv.c @@ -1904,7 +1904,6 @@ static void netiucv_setup_netdevice(struct net_device *dev) dev->type = ARPHRD_SLIP; dev->tx_queue_len = NETIUCV_QUEUELEN_DEFAULT; dev->flags = IFF_POINTOPOINT | IFF_NOARP; - SET_MODULE_OWNER(dev); } /** diff --git a/drivers/s390/net/qeth_main.c b/drivers/s390/net/qeth_main.c index f3e6fbeb2123..8c46978e0afa 100644 --- a/drivers/s390/net/qeth_main.c +++ b/drivers/s390/net/qeth_main.c @@ -6649,7 +6649,6 @@ qeth_netdev_init(struct net_device *dev) dev->mtu = card->info.initial_mtu; if (card->info.type != QETH_CARD_TYPE_OSN) SET_ETHTOOL_OPS(dev, &qeth_ethtool_ops); - SET_MODULE_OWNER(dev); return 0; } diff --git a/drivers/usb/gadget/ether.c b/drivers/usb/gadget/ether.c index 593e23507b1a..f70055473a00 100644 --- a/drivers/usb/gadget/ether.c +++ b/drivers/usb/gadget/ether.c @@ -2484,7 +2484,6 @@ autoconf_fail: /* network device setup */ dev->net = net; - SET_MODULE_OWNER (net); strcpy (net->name, "usb%d"); dev->cdc = cdc; dev->zlp = zlp; diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 625240ce27f1..de387c5400b3 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -702,7 +702,6 @@ static inline void *netdev_priv(const struct net_device *dev) return dev->priv; } -#define SET_MODULE_OWNER(dev) do { } while (0) /* Set the sysfs physical device reference for the network logical device * if set prior to registration will cause a symlink during initialization. */ diff --git a/net/8021q/vlan.c b/net/8021q/vlan.c index a9ced0a6f4c0..4d003e391754 100644 --- a/net/8021q/vlan.c +++ b/net/8021q/vlan.c @@ -350,8 +350,6 @@ static int vlan_dev_init(struct net_device *dev) void vlan_setup(struct net_device *new_dev) { - SET_MODULE_OWNER(new_dev); - ether_setup(new_dev); /* new_dev->ifindex = 0; it will be set when added to diff --git a/net/bridge/br_device.c b/net/bridge/br_device.c index 99292e8e1d0f..f803e39eee28 100644 --- a/net/bridge/br_device.c +++ b/net/bridge/br_device.c @@ -171,7 +171,6 @@ void br_dev_setup(struct net_device *dev) dev->set_multicast_list = br_dev_set_multicast_list; dev->change_mtu = br_change_mtu; dev->destructor = free_netdev; - SET_MODULE_OWNER(dev); SET_ETHTOOL_OPS(dev, &br_ethtool_ops); dev->stop = br_dev_stop; dev->tx_queue_len = 0; diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c index 3106225c5e50..ffa9f1c9dcbb 100644 --- a/net/ipv4/ip_gre.c +++ b/net/ipv4/ip_gre.c @@ -1132,7 +1132,6 @@ static int ipgre_close(struct net_device *dev) static void ipgre_tunnel_setup(struct net_device *dev) { - SET_MODULE_OWNER(dev); dev->uninit = ipgre_tunnel_uninit; dev->destructor = free_netdev; dev->hard_start_xmit = ipgre_tunnel_xmit; diff --git a/net/ipv4/ipip.c b/net/ipv4/ipip.c index 652bd86e33a3..5cd5bbe1379a 100644 --- a/net/ipv4/ipip.c +++ b/net/ipv4/ipip.c @@ -237,7 +237,6 @@ static struct ip_tunnel * ipip_tunnel_locate(struct ip_tunnel_parm *parms, int c return NULL; nt = netdev_priv(dev); - SET_MODULE_OWNER(dev); dev->init = ipip_tunnel_init; nt->parms = *parms; @@ -775,7 +774,6 @@ static int ipip_tunnel_change_mtu(struct net_device *dev, int new_mtu) static void ipip_tunnel_setup(struct net_device *dev) { - SET_MODULE_OWNER(dev); dev->uninit = ipip_tunnel_uninit; dev->hard_start_xmit = ipip_tunnel_xmit; dev->get_stats = ipip_tunnel_get_stats; diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c index 937625e577c1..2320cc27ff9e 100644 --- a/net/ipv6/ip6_tunnel.c +++ b/net/ipv6/ip6_tunnel.c @@ -1313,7 +1313,6 @@ ip6_tnl_change_mtu(struct net_device *dev, int new_mtu) static void ip6_tnl_dev_setup(struct net_device *dev) { - SET_MODULE_OWNER(dev); dev->uninit = ip6_tnl_dev_uninit; dev->destructor = free_netdev; dev->hard_start_xmit = ip6_tnl_xmit; diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c index e79f419b1731..466657a9a8bd 100644 --- a/net/ipv6/sit.c +++ b/net/ipv6/sit.c @@ -714,7 +714,6 @@ static int ipip6_tunnel_change_mtu(struct net_device *dev, int new_mtu) static void ipip6_tunnel_setup(struct net_device *dev) { - SET_MODULE_OWNER(dev); dev->uninit = ipip6_tunnel_uninit; dev->destructor = free_netdev; dev->hard_start_xmit = ipip6_tunnel_xmit; diff --git a/net/irda/irlan/irlan_eth.c b/net/irda/irlan/irlan_eth.c index c421521c0a99..340f04a36b02 100644 --- a/net/irda/irlan/irlan_eth.c +++ b/net/irda/irlan/irlan_eth.c @@ -60,8 +60,6 @@ static void irlan_eth_setup(struct net_device *dev) dev->set_multicast_list = irlan_eth_set_multicast_list; dev->destructor = free_netdev; - SET_MODULE_OWNER(dev); - ether_setup(dev); /* diff --git a/net/sched/sch_teql.c b/net/sched/sch_teql.c index 0968184ea6be..146f453d7378 100644 --- a/net/sched/sch_teql.c +++ b/net/sched/sch_teql.c @@ -432,7 +432,6 @@ static __init void teql_master_setup(struct net_device *dev) dev->tx_queue_len = 100; dev->flags = IFF_NOARP; dev->hard_header_len = LL_MAX_HEADER; - SET_MODULE_OWNER(dev); } static LIST_HEAD(master_dev_list); -- cgit v1.2.3 From 09f75cd7bf13720738e6a196cc0107ce9a5bd5a0 Mon Sep 17 00:00:00 2001 From: Jeff Garzik Date: Wed, 3 Oct 2007 17:41:50 -0700 Subject: [NET] drivers/net: statistics cleanup #1 -- save memory and shrink code We now have struct net_device_stats embedded in struct net_device, and the default ->get_stats() hook does the obvious thing for us. Run through drivers/net/* and remove the driver-local storage of statistics, and driver-local ->get_stats() hook where applicable. This was just the low-hanging fruit in drivers/net; plenty more drivers remain to be updated. [ Resolved conflicts with napi_struct changes and fix sunqe build regression... -DaveM ] Signed-off-by: Jeff Garzik Signed-off-by: David S. Miller --- drivers/net/3c501.c | 41 +++++------------- drivers/net/3c501.h | 2 - drivers/net/3c507.c | 52 ++++++++-------------- drivers/net/7990.c | 47 +++++++++----------- drivers/net/7990.h | 2 - drivers/net/82596.c | 65 ++++++++++++---------------- drivers/net/a2065.c | 51 +++++++++------------- drivers/net/at1700.c | 39 ++++++----------- drivers/net/atarilance.c | 58 +++++++++---------------- drivers/net/atp.c | 49 ++++++++------------- drivers/net/au1000_eth.c | 23 ++-------- drivers/net/au1000_eth.h | 1 - drivers/net/bfin_mac.c | 25 +++-------- drivers/net/bfin_mac.h | 2 - drivers/net/bmac.c | 48 ++++++++------------- drivers/net/de600.c | 15 ++----- drivers/net/de600.h | 1 - drivers/net/de620.c | 26 +++-------- drivers/net/declance.c | 52 +++++++++------------- drivers/net/depca.c | 42 +++++++----------- drivers/net/dgrs.c | 24 ++--------- drivers/net/dm9000.c | 29 +++---------- drivers/net/e100.c | 23 ++++------ drivers/net/eepro.c | 47 ++++++++------------ drivers/net/eexpress.c | 56 +++++++++--------------- drivers/net/eql.c | 12 +----- drivers/net/eth16i.c | 49 ++++++++------------- drivers/net/ewrk3.c | 37 ++++++---------- drivers/net/fec.c | 50 +++++++++------------ drivers/net/gianfar.c | 40 +++++++---------- drivers/net/hplance.c | 1 - drivers/net/ibmlana.c | 37 ++++++---------- drivers/net/ibmlana.h | 1 - drivers/net/ibmveth.c | 18 +++----- drivers/net/ifb.c | 20 +-------- drivers/net/iseries_veth.c | 23 +++------- drivers/net/lib82596.c | 64 ++++++++++++--------------- drivers/net/lp486e.c | 56 ++++++++++-------------- drivers/net/mace.c | 59 +++++++++++-------------- drivers/net/macmace.c | 49 ++++++++------------- drivers/net/meth.c | 28 +++++------- drivers/net/mipsnet.c | 26 +++-------- drivers/net/mv643xx_eth.c | 25 ++--------- drivers/net/myri_sbus.c | 20 ++++----- drivers/net/myri_sbus.h | 1 - drivers/net/netx-eth.c | 18 +++----- drivers/net/ni5010.c | 47 ++++++-------------- drivers/net/pasemi_mac.c | 17 ++------ drivers/net/pasemi_mac.h | 1 - drivers/net/pci-skeleton.c | 74 ++++++++++---------------------- drivers/net/plip.c | 32 +++++--------- drivers/net/qla3xxx.c | 23 ++++------ drivers/net/qla3xxx.h | 1 - drivers/net/rionet.c | 20 +++------ drivers/net/rrunner.c | 31 +++++-------- drivers/net/rrunner.h | 2 - drivers/net/saa9730.c | 93 ++++++++++++++++++--------------------- drivers/net/saa9730.h | 1 - drivers/net/sb1000.c | 19 +++----- drivers/net/sb1250-mac.c | 39 +++++------------ drivers/net/seeq8005.c | 33 +++++--------- drivers/net/sgiseeq.c | 39 ++++++----------- drivers/net/shaper.c | 15 ++----- drivers/net/sis190.c | 19 +++----- drivers/net/sis900.c | 56 ++++++++---------------- drivers/net/smc911x.c | 77 ++++++++++++--------------------- drivers/net/smc9194.c | 59 ++++++++----------------- drivers/net/smc91x.c | 69 +++++++++++------------------ drivers/net/spider_net.c | 49 +++++++-------------- drivers/net/spider_net.h | 1 - drivers/net/sun3lance.c | 53 +++++++++-------------- drivers/net/sunlance.c | 87 +++++++++++++++++-------------------- drivers/net/sunqe.c | 105 +++++++++++++++++++++------------------------ drivers/net/sunqe.h | 1 - drivers/net/tun.c | 23 ++++------ drivers/net/ucc_geth.c | 27 ++++-------- drivers/net/ucc_geth.h | 1 - drivers/net/xen-netfront.c | 27 ++++-------- drivers/net/yellowfin.c | 63 +++++++++++---------------- drivers/net/znet.c | 50 ++++++++------------- include/linux/if_eql.h | 1 - include/linux/if_shaper.h | 1 - include/linux/if_tun.h | 1 - 83 files changed, 948 insertions(+), 1763 deletions(-) (limited to 'include/linux') diff --git a/drivers/net/3c501.c b/drivers/net/3c501.c index 98e0bc4628a2..be71868d1513 100644 --- a/drivers/net/3c501.c +++ b/drivers/net/3c501.c @@ -315,7 +315,6 @@ static int __init el1_probe1(struct net_device *dev, int ioaddr) dev->tx_timeout = &el_timeout; dev->watchdog_timeo = HZ; dev->stop = &el1_close; - dev->get_stats = &el1_get_stats; dev->set_multicast_list = &set_multicast_list; dev->ethtool_ops = &netdev_ethtool_ops; return 0; @@ -374,7 +373,7 @@ static void el_timeout(struct net_device *dev) if (el_debug) printk (KERN_DEBUG "%s: transmit timed out, txsr %#2x axsr=%02x rxsr=%02x.\n", dev->name, inb(TX_STATUS), inb(AX_STATUS), inb(RX_STATUS)); - lp->stats.tx_errors++; + dev->stats.tx_errors++; outb(TX_NORM, TX_CMD); outb(RX_NORM, RX_CMD); outb(AX_OFF, AX_CMD); /* Just trigger a false interrupt. */ @@ -441,7 +440,7 @@ static int el_start_xmit(struct sk_buff *skb, struct net_device *dev) lp->tx_pkt_start = gp_start; lp->collisions = 0; - lp->stats.tx_bytes += skb->len; + dev->stats.tx_bytes += skb->len; /* * Command mode with status cleared should [in theory] @@ -588,7 +587,7 @@ static irqreturn_t el_interrupt(int irq, void *dev_id) printk (KERN_DEBUG "%s: Transmit failed 16 times, Ethernet jammed?\n",dev->name); outb(AX_SYS, AX_CMD); lp->txing = 0; - lp->stats.tx_aborted_errors++; + dev->stats.tx_aborted_errors++; netif_wake_queue(dev); } else if (txsr & TX_COLLISION) @@ -606,7 +605,7 @@ static irqreturn_t el_interrupt(int irq, void *dev_id) outb(AX_SYS, AX_CMD); outw(lp->tx_pkt_start, GP_LOW); outb(AX_XMIT, AX_CMD); - lp->stats.collisions++; + dev->stats.collisions++; spin_unlock(&lp->lock); goto out; } @@ -615,7 +614,7 @@ static irqreturn_t el_interrupt(int irq, void *dev_id) /* * It worked.. we will now fall through and receive */ - lp->stats.tx_packets++; + dev->stats.tx_packets++; if (el_debug > 6) printk(KERN_DEBUG " Tx succeeded %s\n", (txsr & TX_RDY) ? "." : "but tx is busy!"); @@ -640,10 +639,10 @@ static irqreturn_t el_interrupt(int irq, void *dev_id) * Just reading rx_status fixes most errors. */ if (rxsr & RX_MISSED) - lp->stats.rx_missed_errors++; + dev->stats.rx_missed_errors++; else if (rxsr & RX_RUNT) { /* Handled to avoid board lock-up. */ - lp->stats.rx_length_errors++; + dev->stats.rx_length_errors++; if (el_debug > 5) printk(KERN_DEBUG " runt.\n"); } @@ -694,7 +693,6 @@ out: static void el_receive(struct net_device *dev) { - struct net_local *lp = netdev_priv(dev); int ioaddr = dev->base_addr; int pkt_len; struct sk_buff *skb; @@ -708,7 +706,7 @@ static void el_receive(struct net_device *dev) { if (el_debug) printk(KERN_DEBUG "%s: bogus packet, length=%d\n", dev->name, pkt_len); - lp->stats.rx_over_errors++; + dev->stats.rx_over_errors++; return; } @@ -727,7 +725,7 @@ static void el_receive(struct net_device *dev) if (skb == NULL) { printk(KERN_INFO "%s: Memory squeeze, dropping packet.\n", dev->name); - lp->stats.rx_dropped++; + dev->stats.rx_dropped++; return; } else @@ -742,8 +740,8 @@ static void el_receive(struct net_device *dev) skb->protocol=eth_type_trans(skb,dev); netif_rx(skb); dev->last_rx = jiffies; - lp->stats.rx_packets++; - lp->stats.rx_bytes+=pkt_len; + dev->stats.rx_packets++; + dev->stats.rx_bytes+=pkt_len; } return; } @@ -810,23 +808,6 @@ static int el1_close(struct net_device *dev) return 0; } -/** - * el1_get_stats: - * @dev: The card to get the statistics for - * - * In smarter devices this function is needed to pull statistics off the - * board itself. The 3c501 has no hardware statistics. We maintain them all - * so they are by definition always up to date. - * - * Returns the statistics for the card from the card private data - */ - -static struct net_device_stats *el1_get_stats(struct net_device *dev) -{ - struct net_local *lp = netdev_priv(dev); - return &lp->stats; -} - /** * set_multicast_list: * @dev: The device to adjust diff --git a/drivers/net/3c501.h b/drivers/net/3c501.h index c56a2c62f7de..cfec64efff78 100644 --- a/drivers/net/3c501.h +++ b/drivers/net/3c501.h @@ -11,7 +11,6 @@ static irqreturn_t el_interrupt(int irq, void *dev_id); static void el_receive(struct net_device *dev); static void el_reset(struct net_device *dev); static int el1_close(struct net_device *dev); -static struct net_device_stats *el1_get_stats(struct net_device *dev); static void set_multicast_list(struct net_device *dev); static const struct ethtool_ops netdev_ethtool_ops; @@ -29,7 +28,6 @@ static int el_debug = EL_DEBUG; struct net_local { - struct net_device_stats stats; int tx_pkt_start; /* The length of the current Tx packet. */ int collisions; /* Tx collisions this packet */ int loading; /* Spot buffer load collisions */ diff --git a/drivers/net/3c507.c b/drivers/net/3c507.c index fac6edff2b8b..3d06271c3a8b 100644 --- a/drivers/net/3c507.c +++ b/drivers/net/3c507.c @@ -118,7 +118,6 @@ enum commands { /* Information that need to be kept for each board. */ struct net_local { - struct net_device_stats stats; int last_restart; ushort rx_head; ushort rx_tail; @@ -289,7 +288,6 @@ static int el16_send_packet(struct sk_buff *skb, struct net_device *dev); static irqreturn_t el16_interrupt(int irq, void *dev_id); static void el16_rx(struct net_device *dev); static int el16_close(struct net_device *dev); -static struct net_device_stats *el16_get_stats(struct net_device *dev); static void el16_tx_timeout (struct net_device *dev); static void hardware_send_packet(struct net_device *dev, void *buf, short length, short pad); @@ -455,7 +453,6 @@ static int __init el16_probe1(struct net_device *dev, int ioaddr) dev->open = el16_open; dev->stop = el16_close; dev->hard_start_xmit = el16_send_packet; - dev->get_stats = el16_get_stats; dev->tx_timeout = el16_tx_timeout; dev->watchdog_timeo = TX_TIMEOUT; dev->ethtool_ops = &netdev_ethtool_ops; @@ -489,7 +486,7 @@ static void el16_tx_timeout (struct net_device *dev) readw(shmem + iSCB_STATUS) & 0x8000 ? "IRQ conflict" : "network cable problem"); /* Try to restart the adaptor. */ - if (lp->last_restart == lp->stats.tx_packets) { + if (lp->last_restart == dev->stats.tx_packets) { if (net_debug > 1) printk ("Resetting board.\n"); /* Completely reset the adaptor. */ @@ -501,7 +498,7 @@ static void el16_tx_timeout (struct net_device *dev) printk ("Kicking board.\n"); writew(0xf000 | CUC_START | RX_START, shmem + iSCB_CMD); outb (0, ioaddr + SIGNAL_CA); /* Issue channel-attn. */ - lp->last_restart = lp->stats.tx_packets; + lp->last_restart = dev->stats.tx_packets; } dev->trans_start = jiffies; netif_wake_queue (dev); @@ -520,7 +517,7 @@ static int el16_send_packet (struct sk_buff *skb, struct net_device *dev) spin_lock_irqsave (&lp->lock, flags); - lp->stats.tx_bytes += length; + dev->stats.tx_bytes += length; /* Disable the 82586's input to the interrupt line. */ outb (0x80, ioaddr + MISC_CTRL); @@ -579,14 +576,14 @@ static irqreturn_t el16_interrupt(int irq, void *dev_id) } /* Tx unsuccessful or some interesting status bit set. */ if (!(tx_status & 0x2000) || (tx_status & 0x0f3f)) { - lp->stats.tx_errors++; - if (tx_status & 0x0600) lp->stats.tx_carrier_errors++; - if (tx_status & 0x0100) lp->stats.tx_fifo_errors++; - if (!(tx_status & 0x0040)) lp->stats.tx_heartbeat_errors++; - if (tx_status & 0x0020) lp->stats.tx_aborted_errors++; - lp->stats.collisions += tx_status & 0xf; + dev->stats.tx_errors++; + if (tx_status & 0x0600) dev->stats.tx_carrier_errors++; + if (tx_status & 0x0100) dev->stats.tx_fifo_errors++; + if (!(tx_status & 0x0040)) dev->stats.tx_heartbeat_errors++; + if (tx_status & 0x0020) dev->stats.tx_aborted_errors++; + dev->stats.collisions += tx_status & 0xf; } - lp->stats.tx_packets++; + dev->stats.tx_packets++; if (net_debug > 5) printk("Reaped %x, Tx status %04x.\n" , lp->tx_reap, tx_status); lp->tx_reap += TX_BUF_SIZE; @@ -665,17 +662,6 @@ static int el16_close(struct net_device *dev) return 0; } -/* Get the current statistics. This may be called with the card open or - closed. */ -static struct net_device_stats *el16_get_stats(struct net_device *dev) -{ - struct net_local *lp = netdev_priv(dev); - - /* ToDo: decide if there are any useful statistics from the SCB. */ - - return &lp->stats; -} - /* Initialize the Rx-block list. */ static void init_rx_bufs(struct net_device *dev) { @@ -852,12 +838,12 @@ static void el16_rx(struct net_device *dev) pkt_len); } else if ((frame_status & 0x2000) == 0) { /* Frame Rxed, but with error. */ - lp->stats.rx_errors++; - if (frame_status & 0x0800) lp->stats.rx_crc_errors++; - if (frame_status & 0x0400) lp->stats.rx_frame_errors++; - if (frame_status & 0x0200) lp->stats.rx_fifo_errors++; - if (frame_status & 0x0100) lp->stats.rx_over_errors++; - if (frame_status & 0x0080) lp->stats.rx_length_errors++; + dev->stats.rx_errors++; + if (frame_status & 0x0800) dev->stats.rx_crc_errors++; + if (frame_status & 0x0400) dev->stats.rx_frame_errors++; + if (frame_status & 0x0200) dev->stats.rx_fifo_errors++; + if (frame_status & 0x0100) dev->stats.rx_over_errors++; + if (frame_status & 0x0080) dev->stats.rx_length_errors++; } else { /* Malloc up new buffer. */ struct sk_buff *skb; @@ -866,7 +852,7 @@ static void el16_rx(struct net_device *dev) skb = dev_alloc_skb(pkt_len+2); if (skb == NULL) { printk("%s: Memory squeeze, dropping packet.\n", dev->name); - lp->stats.rx_dropped++; + dev->stats.rx_dropped++; break; } @@ -878,8 +864,8 @@ static void el16_rx(struct net_device *dev) skb->protocol=eth_type_trans(skb,dev); netif_rx(skb); dev->last_rx = jiffies; - lp->stats.rx_packets++; - lp->stats.rx_bytes += pkt_len; + dev->stats.rx_packets++; + dev->stats.rx_bytes += pkt_len; } /* Clear the status word and set End-of-List on the rx frame. */ diff --git a/drivers/net/7990.c b/drivers/net/7990.c index e89ace109a5d..224e0bff1ae0 100644 --- a/drivers/net/7990.c +++ b/drivers/net/7990.c @@ -305,18 +305,18 @@ static int lance_rx (struct net_device *dev) /* We got an incomplete frame? */ if ((bits & LE_R1_POK) != LE_R1_POK) { - lp->stats.rx_over_errors++; - lp->stats.rx_errors++; + dev->stats.rx_over_errors++; + dev->stats.rx_errors++; continue; } else if (bits & LE_R1_ERR) { /* Count only the end frame as a rx error, * not the beginning */ - if (bits & LE_R1_BUF) lp->stats.rx_fifo_errors++; - if (bits & LE_R1_CRC) lp->stats.rx_crc_errors++; - if (bits & LE_R1_OFL) lp->stats.rx_over_errors++; - if (bits & LE_R1_FRA) lp->stats.rx_frame_errors++; - if (bits & LE_R1_EOP) lp->stats.rx_errors++; + if (bits & LE_R1_BUF) dev->stats.rx_fifo_errors++; + if (bits & LE_R1_CRC) dev->stats.rx_crc_errors++; + if (bits & LE_R1_OFL) dev->stats.rx_over_errors++; + if (bits & LE_R1_FRA) dev->stats.rx_frame_errors++; + if (bits & LE_R1_EOP) dev->stats.rx_errors++; } else { len = (rd->mblength & 0xfff) - 4; skb = dev_alloc_skb (len+2); @@ -324,7 +324,7 @@ static int lance_rx (struct net_device *dev) if (skb == 0) { printk ("%s: Memory squeeze, deferring packet.\n", dev->name); - lp->stats.rx_dropped++; + dev->stats.rx_dropped++; rd->mblength = 0; rd->rmd1_bits = LE_R1_OWN; lp->rx_new = (lp->rx_new + 1) & lp->rx_ring_mod_mask; @@ -339,8 +339,8 @@ static int lance_rx (struct net_device *dev) skb->protocol = eth_type_trans (skb, dev); netif_rx (skb); dev->last_rx = jiffies; - lp->stats.rx_packets++; - lp->stats.rx_bytes += len; + dev->stats.rx_packets++; + dev->stats.rx_bytes += len; } /* Return the packet to the pool */ @@ -377,12 +377,12 @@ static int lance_tx (struct net_device *dev) if (td->tmd1_bits & LE_T1_ERR) { status = td->misc; - lp->stats.tx_errors++; - if (status & LE_T3_RTY) lp->stats.tx_aborted_errors++; - if (status & LE_T3_LCOL) lp->stats.tx_window_errors++; + dev->stats.tx_errors++; + if (status & LE_T3_RTY) dev->stats.tx_aborted_errors++; + if (status & LE_T3_LCOL) dev->stats.tx_window_errors++; if (status & LE_T3_CLOS) { - lp->stats.tx_carrier_errors++; + dev->stats.tx_carrier_errors++; if (lp->auto_select) { lp->tpe = 1 - lp->tpe; printk("%s: Carrier Lost, trying %s\n", @@ -400,7 +400,7 @@ static int lance_tx (struct net_device *dev) /* buffer errors and underflows turn off the transmitter */ /* Restart the adapter */ if (status & (LE_T3_BUF|LE_T3_UFL)) { - lp->stats.tx_fifo_errors++; + dev->stats.tx_fifo_errors++; printk ("%s: Tx: ERR_BUF|ERR_UFL, restarting\n", dev->name); @@ -420,13 +420,13 @@ static int lance_tx (struct net_device *dev) /* One collision before packet was sent. */ if (td->tmd1_bits & LE_T1_EONE) - lp->stats.collisions++; + dev->stats.collisions++; /* More than one collision, be optimistic. */ if (td->tmd1_bits & LE_T1_EMORE) - lp->stats.collisions += 2; + dev->stats.collisions += 2; - lp->stats.tx_packets++; + dev->stats.tx_packets++; } j = (j + 1) & lp->tx_ring_mod_mask; @@ -471,9 +471,9 @@ lance_interrupt (int irq, void *dev_id) /* Log misc errors. */ if (csr0 & LE_C0_BABL) - lp->stats.tx_errors++; /* Tx babble. */ + dev->stats.tx_errors++; /* Tx babble. */ if (csr0 & LE_C0_MISS) - lp->stats.rx_errors++; /* Missed a Rx frame. */ + dev->stats.rx_errors++; /* Missed a Rx frame. */ if (csr0 & LE_C0_MERR) { printk("%s: Bus master arbitration failure, status %4.4x.\n", dev->name, csr0); @@ -589,13 +589,6 @@ int lance_start_xmit (struct sk_buff *skb, struct net_device *dev) return 0; } -struct net_device_stats *lance_get_stats (struct net_device *dev) -{ - struct lance_private *lp = netdev_priv(dev); - - return &lp->stats; -} - /* taken from the depca driver via a2065.c */ static void lance_load_multicast (struct net_device *dev) { diff --git a/drivers/net/7990.h b/drivers/net/7990.h index b1212b5ed92f..0a5837b96421 100644 --- a/drivers/net/7990.h +++ b/drivers/net/7990.h @@ -111,7 +111,6 @@ struct lance_private int lance_log_rx_bufs, lance_log_tx_bufs; int rx_ring_mod_mask, tx_ring_mod_mask; - struct net_device_stats stats; int tpe; /* TPE is selected */ int auto_select; /* cable-selection is by carrier */ unsigned short busmaster_regval; @@ -246,7 +245,6 @@ struct lance_private extern int lance_open(struct net_device *dev); extern int lance_close (struct net_device *dev); extern int lance_start_xmit (struct sk_buff *skb, struct net_device *dev); -extern struct net_device_stats *lance_get_stats (struct net_device *dev); extern void lance_set_multicast (struct net_device *dev); extern void lance_tx_timeout(struct net_device *dev); #ifdef CONFIG_NET_POLL_CONTROLLER diff --git a/drivers/net/82596.c b/drivers/net/82596.c index 43dffdca708f..6b03416731de 100644 --- a/drivers/net/82596.c +++ b/drivers/net/82596.c @@ -326,7 +326,6 @@ struct i596_private { struct i596_cmd *cmd_head; int cmd_backlog; unsigned long last_cmd; - struct net_device_stats stats; struct i596_rfd rfds[RX_RING_SIZE]; struct i596_rbd rbds[RX_RING_SIZE]; struct tx_cmd tx_cmds[TX_RING_SIZE]; @@ -360,7 +359,6 @@ static int i596_open(struct net_device *dev); static int i596_start_xmit(struct sk_buff *skb, struct net_device *dev); static irqreturn_t i596_interrupt(int irq, void *dev_id); static int i596_close(struct net_device *dev); -static struct net_device_stats *i596_get_stats(struct net_device *dev); static void i596_add_cmd(struct net_device *dev, struct i596_cmd *cmd); static void i596_tx_timeout (struct net_device *dev); static void print_eth(unsigned char *buf, char *str); @@ -828,7 +826,7 @@ memory_squeeze: if (skb == NULL) { /* XXX tulip.c can defer packets here!! */ printk(KERN_WARNING "%s: i596_rx Memory squeeze, dropping packet.\n", dev->name); - lp->stats.rx_dropped++; + dev->stats.rx_dropped++; } else { if (!rx_in_place) { @@ -844,28 +842,28 @@ memory_squeeze: #endif netif_rx(skb); dev->last_rx = jiffies; - lp->stats.rx_packets++; - lp->stats.rx_bytes+=pkt_len; + dev->stats.rx_packets++; + dev->stats.rx_bytes+=pkt_len; } } else { DEB(DEB_ERRORS, printk(KERN_DEBUG "%s: Error, rfd.stat = 0x%04x\n", dev->name, rfd->stat)); - lp->stats.rx_errors++; + dev->stats.rx_errors++; if ((rfd->stat) & 0x0001) - lp->stats.collisions++; + dev->stats.collisions++; if ((rfd->stat) & 0x0080) - lp->stats.rx_length_errors++; + dev->stats.rx_length_errors++; if ((rfd->stat) & 0x0100) - lp->stats.rx_over_errors++; + dev->stats.rx_over_errors++; if ((rfd->stat) & 0x0200) - lp->stats.rx_fifo_errors++; + dev->stats.rx_fifo_errors++; if ((rfd->stat) & 0x0400) - lp->stats.rx_frame_errors++; + dev->stats.rx_frame_errors++; if ((rfd->stat) & 0x0800) - lp->stats.rx_crc_errors++; + dev->stats.rx_crc_errors++; if ((rfd->stat) & 0x1000) - lp->stats.rx_length_errors++; + dev->stats.rx_length_errors++; } /* Clear the buffer descriptor count and EOF + F flags */ @@ -916,8 +914,8 @@ static void i596_cleanup_cmd(struct net_device *dev, struct i596_private *lp) dev_kfree_skb(skb); - lp->stats.tx_errors++; - lp->stats.tx_aborted_errors++; + dev->stats.tx_errors++; + dev->stats.tx_aborted_errors++; ptr->v_next = ptr->b_next = I596_NULL; tx_cmd->cmd.command = 0; /* Mark as free */ @@ -1038,10 +1036,10 @@ static void i596_tx_timeout (struct net_device *dev) DEB(DEB_ERRORS,printk(KERN_ERR "%s: transmit timed out, status resetting.\n", dev->name)); - lp->stats.tx_errors++; + dev->stats.tx_errors++; /* Try to restart the adaptor */ - if (lp->last_restart == lp->stats.tx_packets) { + if (lp->last_restart == dev->stats.tx_packets) { DEB(DEB_ERRORS,printk(KERN_ERR "Resetting board.\n")); /* Shutdown and restart */ i596_reset (dev, lp, ioaddr); @@ -1050,7 +1048,7 @@ static void i596_tx_timeout (struct net_device *dev) DEB(DEB_ERRORS,printk(KERN_ERR "Kicking board.\n")); lp->scb.command = CUC_START | RX_START; CA (dev); - lp->last_restart = lp->stats.tx_packets; + lp->last_restart = dev->stats.tx_packets; } dev->trans_start = jiffies; @@ -1082,7 +1080,7 @@ static int i596_start_xmit(struct sk_buff *skb, struct net_device *dev) if (tx_cmd->cmd.command) { printk(KERN_NOTICE "%s: xmit ring full, dropping packet.\n", dev->name); - lp->stats.tx_dropped++; + dev->stats.tx_dropped++; dev_kfree_skb(skb); } else { @@ -1107,8 +1105,8 @@ static int i596_start_xmit(struct sk_buff *skb, struct net_device *dev) DEB(DEB_TXADDR,print_eth(skb->data, "tx-queued")); i596_add_cmd(dev, &tx_cmd->cmd); - lp->stats.tx_packets++; - lp->stats.tx_bytes += length; + dev->stats.tx_packets++; + dev->stats.tx_bytes += length; } netif_start_queue(dev); @@ -1237,7 +1235,6 @@ struct net_device * __init i82596_probe(int unit) dev->open = i596_open; dev->stop = i596_close; dev->hard_start_xmit = i596_start_xmit; - dev->get_stats = i596_get_stats; dev->set_multicast_list = set_multicast_list; dev->tx_timeout = i596_tx_timeout; dev->watchdog_timeo = TX_TIMEOUT; @@ -1343,17 +1340,17 @@ static irqreturn_t i596_interrupt(int irq, void *dev_id) if ((ptr->status) & STAT_OK) { DEB(DEB_TXADDR,print_eth(skb->data, "tx-done")); } else { - lp->stats.tx_errors++; + dev->stats.tx_errors++; if ((ptr->status) & 0x0020) - lp->stats.collisions++; + dev->stats.collisions++; if (!((ptr->status) & 0x0040)) - lp->stats.tx_heartbeat_errors++; + dev->stats.tx_heartbeat_errors++; if ((ptr->status) & 0x0400) - lp->stats.tx_carrier_errors++; + dev->stats.tx_carrier_errors++; if ((ptr->status) & 0x0800) - lp->stats.collisions++; + dev->stats.collisions++; if ((ptr->status) & 0x1000) - lp->stats.tx_aborted_errors++; + dev->stats.tx_aborted_errors++; } dev_kfree_skb_irq(skb); @@ -1408,8 +1405,8 @@ static irqreturn_t i596_interrupt(int irq, void *dev_id) if (netif_running(dev)) { DEB(DEB_ERRORS,printk(KERN_ERR "%s: i596 interrupt receive unit inactive, status 0x%x\n", dev->name, status)); ack_cmd |= RX_START; - lp->stats.rx_errors++; - lp->stats.rx_fifo_errors++; + dev->stats.rx_errors++; + dev->stats.rx_fifo_errors++; rebuild_rx_bufs(dev); } } @@ -1492,14 +1489,6 @@ static int i596_close(struct net_device *dev) return 0; } -static struct net_device_stats * - i596_get_stats(struct net_device *dev) -{ - struct i596_private *lp = dev->priv; - - return &lp->stats; -} - /* * Set or clear the multicast filter for this adaptor. */ diff --git a/drivers/net/a2065.c b/drivers/net/a2065.c index fa0c6cb3d798..77773ce52eff 100644 --- a/drivers/net/a2065.c +++ b/drivers/net/a2065.c @@ -119,7 +119,6 @@ struct lance_private { int lance_log_rx_bufs, lance_log_tx_bufs; int rx_ring_mod_mask, tx_ring_mod_mask; - struct net_device_stats stats; int tpe; /* cable-selection is TPE */ int auto_select; /* cable-selection by carrier */ unsigned short busmaster_regval; @@ -294,18 +293,18 @@ static int lance_rx (struct net_device *dev) /* We got an incomplete frame? */ if ((bits & LE_R1_POK) != LE_R1_POK) { - lp->stats.rx_over_errors++; - lp->stats.rx_errors++; + dev->stats.rx_over_errors++; + dev->stats.rx_errors++; continue; } else if (bits & LE_R1_ERR) { /* Count only the end frame as a rx error, * not the beginning */ - if (bits & LE_R1_BUF) lp->stats.rx_fifo_errors++; - if (bits & LE_R1_CRC) lp->stats.rx_crc_errors++; - if (bits & LE_R1_OFL) lp->stats.rx_over_errors++; - if (bits & LE_R1_FRA) lp->stats.rx_frame_errors++; - if (bits & LE_R1_EOP) lp->stats.rx_errors++; + if (bits & LE_R1_BUF) dev->stats.rx_fifo_errors++; + if (bits & LE_R1_CRC) dev->stats.rx_crc_errors++; + if (bits & LE_R1_OFL) dev->stats.rx_over_errors++; + if (bits & LE_R1_FRA) dev->stats.rx_frame_errors++; + if (bits & LE_R1_EOP) dev->stats.rx_errors++; } else { len = (rd->mblength & 0xfff) - 4; skb = dev_alloc_skb (len+2); @@ -313,7 +312,7 @@ static int lance_rx (struct net_device *dev) if (skb == 0) { printk(KERN_WARNING "%s: Memory squeeze, " "deferring packet.\n", dev->name); - lp->stats.rx_dropped++; + dev->stats.rx_dropped++; rd->mblength = 0; rd->rmd1_bits = LE_R1_OWN; lp->rx_new = (lp->rx_new + 1) & lp->rx_ring_mod_mask; @@ -328,8 +327,8 @@ static int lance_rx (struct net_device *dev) skb->protocol = eth_type_trans (skb, dev); netif_rx (skb); dev->last_rx = jiffies; - lp->stats.rx_packets++; - lp->stats.rx_bytes += len; + dev->stats.rx_packets++; + dev->stats.rx_bytes += len; } /* Return the packet to the pool */ @@ -364,12 +363,12 @@ static int lance_tx (struct net_device *dev) if (td->tmd1_bits & LE_T1_ERR) { status = td->misc; - lp->stats.tx_errors++; - if (status & LE_T3_RTY) lp->stats.tx_aborted_errors++; - if (status & LE_T3_LCOL) lp->stats.tx_window_errors++; + dev->stats.tx_errors++; + if (status & LE_T3_RTY) dev->stats.tx_aborted_errors++; + if (status & LE_T3_LCOL) dev->stats.tx_window_errors++; if (status & LE_T3_CLOS) { - lp->stats.tx_carrier_errors++; + dev->stats.tx_carrier_errors++; if (lp->auto_select) { lp->tpe = 1 - lp->tpe; printk(KERN_ERR "%s: Carrier Lost, " @@ -388,7 +387,7 @@ static int lance_tx (struct net_device *dev) /* buffer errors and underflows turn off the transmitter */ /* Restart the adapter */ if (status & (LE_T3_BUF|LE_T3_UFL)) { - lp->stats.tx_fifo_errors++; + dev->stats.tx_fifo_errors++; printk(KERN_ERR "%s: Tx: ERR_BUF|ERR_UFL, " "restarting\n", dev->name); @@ -408,13 +407,13 @@ static int lance_tx (struct net_device *dev) /* One collision before packet was sent. */ if (td->tmd1_bits & LE_T1_EONE) - lp->stats.collisions++; + dev->stats.collisions++; /* More than one collision, be optimistic. */ if (td->tmd1_bits & LE_T1_EMORE) - lp->stats.collisions += 2; + dev->stats.collisions += 2; - lp->stats.tx_packets++; + dev->stats.tx_packets++; } j = (j + 1) & lp->tx_ring_mod_mask; @@ -459,9 +458,9 @@ static irqreturn_t lance_interrupt (int irq, void *dev_id) /* Log misc errors. */ if (csr0 & LE_C0_BABL) - lp->stats.tx_errors++; /* Tx babble. */ + dev->stats.tx_errors++; /* Tx babble. */ if (csr0 & LE_C0_MISS) - lp->stats.rx_errors++; /* Missed a Rx frame. */ + dev->stats.rx_errors++; /* Missed a Rx frame. */ if (csr0 & LE_C0_MERR) { printk(KERN_ERR "%s: Bus master arbitration failure, status " "%4.4x.\n", dev->name, csr0); @@ -606,7 +605,7 @@ static int lance_start_xmit (struct sk_buff *skb, struct net_device *dev) /* Now, give the packet to the lance */ ib->btx_ring [entry].tmd1_bits = (LE_T1_POK|LE_T1_OWN); lp->tx_new = (lp->tx_new+1) & lp->tx_ring_mod_mask; - lp->stats.tx_bytes += skblen; + dev->stats.tx_bytes += skblen; if (TX_BUFFS_AVAIL <= 0) netif_stop_queue(dev); @@ -621,13 +620,6 @@ static int lance_start_xmit (struct sk_buff *skb, struct net_device *dev) return status; } -static struct net_device_stats *lance_get_stats (struct net_device *dev) -{ - struct lance_private *lp = netdev_priv(dev); - - return &lp->stats; -} - /* taken from the depca driver */ static void lance_load_multicast (struct net_device *dev) { @@ -782,7 +774,6 @@ static int __devinit a2065_init_one(struct zorro_dev *z, dev->hard_start_xmit = &lance_start_xmit; dev->tx_timeout = &lance_tx_timeout; dev->watchdog_timeo = 5*HZ; - dev->get_stats = &lance_get_stats; dev->set_multicast_list = &lance_set_multicast; dev->dma = 0; diff --git a/drivers/net/at1700.c b/drivers/net/at1700.c index d20148e69fa1..a124fdb2bce6 100644 --- a/drivers/net/at1700.c +++ b/drivers/net/at1700.c @@ -109,7 +109,6 @@ typedef unsigned char uchar; /* Information that need to be kept for each board. */ struct net_local { - struct net_device_stats stats; spinlock_t lock; unsigned char mc_filter[8]; uint jumpered:1; /* Set iff the board has jumper config. */ @@ -164,7 +163,6 @@ static int net_send_packet(struct sk_buff *skb, struct net_device *dev); static irqreturn_t net_interrupt(int irq, void *dev_id); static void net_rx(struct net_device *dev); static int net_close(struct net_device *dev); -static struct net_device_stats *net_get_stats(struct net_device *dev); static void set_rx_mode(struct net_device *dev); static void net_tx_timeout (struct net_device *dev); @@ -456,7 +454,6 @@ found: dev->open = net_open; dev->stop = net_close; dev->hard_start_xmit = net_send_packet; - dev->get_stats = net_get_stats; dev->set_multicast_list = &set_rx_mode; dev->tx_timeout = net_tx_timeout; dev->watchdog_timeo = TX_TIMEOUT; @@ -571,7 +568,7 @@ static void net_tx_timeout (struct net_device *dev) dev->name, inw(ioaddr + TX_STATUS), inw(ioaddr + TX_INTR), inw(ioaddr + TX_MODE), inw(ioaddr + CONFIG_0), inw(ioaddr + DATAPORT), inw(ioaddr + TX_START), inw(ioaddr + MODE13 - 1), inw(ioaddr + RX_CTRL)); - lp->stats.tx_errors++; + dev->stats.tx_errors++; /* ToDo: We should try to restart the adaptor... */ outw(0xffff, ioaddr + MODE24); outw (0xffff, ioaddr + TX_STATUS); @@ -691,10 +688,10 @@ static irqreturn_t net_interrupt(int irq, void *dev_id) printk("%s: 16 Collision occur during Txing.\n", dev->name); /* Cancel sending a packet. */ outb(0x03, ioaddr + COL16CNTL); - lp->stats.collisions++; + dev->stats.collisions++; } if (status & 0x82) { - lp->stats.tx_packets++; + dev->stats.tx_packets++; /* The Tx queue has any packets and is not being transferred a packet from the host, start transmitting. */ @@ -719,7 +716,6 @@ static irqreturn_t net_interrupt(int irq, void *dev_id) static void net_rx(struct net_device *dev) { - struct net_local *lp = netdev_priv(dev); int ioaddr = dev->base_addr; int boguscount = 5; @@ -738,11 +734,11 @@ net_rx(struct net_device *dev) #endif if ((status & 0xF0) != 0x20) { /* There was an error. */ - lp->stats.rx_errors++; - if (status & 0x08) lp->stats.rx_length_errors++; - if (status & 0x04) lp->stats.rx_frame_errors++; - if (status & 0x02) lp->stats.rx_crc_errors++; - if (status & 0x01) lp->stats.rx_over_errors++; + dev->stats.rx_errors++; + if (status & 0x08) dev->stats.rx_length_errors++; + if (status & 0x04) dev->stats.rx_frame_errors++; + if (status & 0x02) dev->stats.rx_crc_errors++; + if (status & 0x01) dev->stats.rx_over_errors++; } else { /* Malloc up new buffer. */ struct sk_buff *skb; @@ -753,7 +749,7 @@ net_rx(struct net_device *dev) /* Prime the FIFO and then flush the packet. */ inw(ioaddr + DATAPORT); inw(ioaddr + DATAPORT); outb(0x05, ioaddr + RX_CTRL); - lp->stats.rx_errors++; + dev->stats.rx_errors++; break; } skb = dev_alloc_skb(pkt_len+3); @@ -763,7 +759,7 @@ net_rx(struct net_device *dev) /* Prime the FIFO and then flush the packet. */ inw(ioaddr + DATAPORT); inw(ioaddr + DATAPORT); outb(0x05, ioaddr + RX_CTRL); - lp->stats.rx_dropped++; + dev->stats.rx_dropped++; break; } skb_reserve(skb,2); @@ -772,8 +768,8 @@ net_rx(struct net_device *dev) skb->protocol=eth_type_trans(skb, dev); netif_rx(skb); dev->last_rx = jiffies; - lp->stats.rx_packets++; - lp->stats.rx_bytes += pkt_len; + dev->stats.rx_packets++; + dev->stats.rx_bytes += pkt_len; } if (--boguscount <= 0) break; @@ -822,17 +818,6 @@ static int net_close(struct net_device *dev) return 0; } -/* Get the current statistics. - This may be called with the card open or closed. - There are no on-chip counters, so this function is trivial. -*/ -static struct net_device_stats * -net_get_stats(struct net_device *dev) -{ - struct net_local *lp = netdev_priv(dev); - return &lp->stats; -} - /* Set the multicast/promiscuous mode for this adaptor. */ diff --git a/drivers/net/atarilance.c b/drivers/net/atarilance.c index 17b9dbf7bd68..8bf548e1cb4e 100644 --- a/drivers/net/atarilance.c +++ b/drivers/net/atarilance.c @@ -224,7 +224,6 @@ struct lance_private { int dirty_tx; /* Ring entries to be freed. */ /* copy function */ void *(*memcpy_f)( void *, const void *, size_t ); - struct net_device_stats stats; /* This must be long for set_bit() */ long tx_full; spinlock_t devlock; @@ -347,7 +346,6 @@ static int lance_start_xmit( struct sk_buff *skb, struct net_device *dev ); static irqreturn_t lance_interrupt( int irq, void *dev_id ); static int lance_rx( struct net_device *dev ); static int lance_close( struct net_device *dev ); -static struct net_device_stats *lance_get_stats( struct net_device *dev ); static void set_multicast_list( struct net_device *dev ); static int lance_set_mac_address( struct net_device *dev, void *addr ); static void lance_tx_timeout (struct net_device *dev); @@ -631,7 +629,6 @@ static unsigned long __init lance_probe1( struct net_device *dev, dev->open = &lance_open; dev->hard_start_xmit = &lance_start_xmit; dev->stop = &lance_close; - dev->get_stats = &lance_get_stats; dev->set_multicast_list = &set_multicast_list; dev->set_mac_address = &lance_set_mac_address; @@ -639,13 +636,6 @@ static unsigned long __init lance_probe1( struct net_device *dev, dev->tx_timeout = lance_tx_timeout; dev->watchdog_timeo = TX_TIMEOUT; - -#if 0 - dev->start = 0; -#endif - - memset( &lp->stats, 0, sizeof(lp->stats) ); - return( 1 ); } @@ -753,7 +743,7 @@ static void lance_tx_timeout (struct net_device *dev) * little endian mode. */ REGA( CSR3 ) = CSR3_BSWP | (lp->cardtype == PAM_CARD ? CSR3_ACON : 0); - lp->stats.tx_errors++; + dev->stats.tx_errors++; #ifndef final_version { int i; DPRINTK( 2, ( "Ring data: dirty_tx %d cur_tx %d%s cur_rx %d\n", @@ -841,7 +831,7 @@ static int lance_start_xmit( struct sk_buff *skb, struct net_device *dev ) head->misc = 0; lp->memcpy_f( PKTBUF_ADDR(head), (void *)skb->data, skb->len ); head->flag = TMD1_OWN_CHIP | TMD1_ENP | TMD1_STP; - lp->stats.tx_bytes += skb->len; + dev->stats.tx_bytes += skb->len; dev_kfree_skb( skb ); lp->cur_tx++; while( lp->cur_tx >= TX_RING_SIZE && lp->dirty_tx >= TX_RING_SIZE ) { @@ -912,13 +902,13 @@ static irqreturn_t lance_interrupt( int irq, void *dev_id ) if (status & TMD1_ERR) { /* There was an major error, log it. */ int err_status = MEM->tx_head[entry].misc; - lp->stats.tx_errors++; - if (err_status & TMD3_RTRY) lp->stats.tx_aborted_errors++; - if (err_status & TMD3_LCAR) lp->stats.tx_carrier_errors++; - if (err_status & TMD3_LCOL) lp->stats.tx_window_errors++; + dev->stats.tx_errors++; + if (err_status & TMD3_RTRY) dev->stats.tx_aborted_errors++; + if (err_status & TMD3_LCAR) dev->stats.tx_carrier_errors++; + if (err_status & TMD3_LCOL) dev->stats.tx_window_errors++; if (err_status & TMD3_UFLO) { /* Ackk! On FIFO errors the Tx unit is turned off! */ - lp->stats.tx_fifo_errors++; + dev->stats.tx_fifo_errors++; /* Remove this verbosity later! */ DPRINTK( 1, ( "%s: Tx FIFO error! Status %04x\n", dev->name, csr0 )); @@ -927,8 +917,8 @@ static irqreturn_t lance_interrupt( int irq, void *dev_id ) } } else { if (status & (TMD1_MORE | TMD1_ONE | TMD1_DEF)) - lp->stats.collisions++; - lp->stats.tx_packets++; + dev->stats.collisions++; + dev->stats.tx_packets++; } /* XXX MSch: free skb?? */ @@ -955,8 +945,8 @@ static irqreturn_t lance_interrupt( int irq, void *dev_id ) } /* Log misc errors. */ - if (csr0 & CSR0_BABL) lp->stats.tx_errors++; /* Tx babble. */ - if (csr0 & CSR0_MISS) lp->stats.rx_errors++; /* Missed a Rx frame. */ + if (csr0 & CSR0_BABL) dev->stats.tx_errors++; /* Tx babble. */ + if (csr0 & CSR0_MISS) dev->stats.rx_errors++; /* Missed a Rx frame. */ if (csr0 & CSR0_MERR) { DPRINTK( 1, ( "%s: Bus master arbitration failure (?!?), " "status %04x.\n", dev->name, csr0 )); @@ -997,11 +987,11 @@ static int lance_rx( struct net_device *dev ) buffers it's possible for a jabber packet to use two buffers, with only the last correctly noting the error. */ if (status & RMD1_ENP) /* Only count a general error at the */ - lp->stats.rx_errors++; /* end of a packet.*/ - if (status & RMD1_FRAM) lp->stats.rx_frame_errors++; - if (status & RMD1_OFLO) lp->stats.rx_over_errors++; - if (status & RMD1_CRC) lp->stats.rx_crc_errors++; - if (status & RMD1_BUFF) lp->stats.rx_fifo_errors++; + dev->stats.rx_errors++; /* end of a packet.*/ + if (status & RMD1_FRAM) dev->stats.rx_frame_errors++; + if (status & RMD1_OFLO) dev->stats.rx_over_errors++; + if (status & RMD1_CRC) dev->stats.rx_crc_errors++; + if (status & RMD1_BUFF) dev->stats.rx_fifo_errors++; head->flag &= (RMD1_ENP|RMD1_STP); } else { /* Malloc up new buffer, compatible with net-3. */ @@ -1010,7 +1000,7 @@ static int lance_rx( struct net_device *dev ) if (pkt_len < 60) { printk( "%s: Runt packet!\n", dev->name ); - lp->stats.rx_errors++; + dev->stats.rx_errors++; } else { skb = dev_alloc_skb( pkt_len+2 ); @@ -1023,7 +1013,7 @@ static int lance_rx( struct net_device *dev ) break; if (i > RX_RING_SIZE - 2) { - lp->stats.rx_dropped++; + dev->stats.rx_dropped++; head->flag |= RMD1_OWN_CHIP; lp->cur_rx++; } @@ -1052,8 +1042,8 @@ static int lance_rx( struct net_device *dev ) skb->protocol = eth_type_trans( skb, dev ); netif_rx( skb ); dev->last_rx = jiffies; - lp->stats.rx_packets++; - lp->stats.rx_bytes += pkt_len; + dev->stats.rx_packets++; + dev->stats.rx_bytes += pkt_len; } } @@ -1090,14 +1080,6 @@ static int lance_close( struct net_device *dev ) } -static struct net_device_stats *lance_get_stats( struct net_device *dev ) - -{ struct lance_private *lp = (struct lance_private *)dev->priv; - - return &lp->stats; -} - - /* Set or clear the multicast filter for this adaptor. num_addrs == -1 Promiscuous mode, receive all packets num_addrs == 0 Normal mode, clear multicast list diff --git a/drivers/net/atp.c b/drivers/net/atp.c index 6020d5ec38b9..cec2e3672cd0 100644 --- a/drivers/net/atp.c +++ b/drivers/net/atp.c @@ -171,7 +171,6 @@ static char mux_8012[] = { 0xff, 0xf7, 0xff, 0xfb, 0xf3, 0xfb, 0xff, 0xf7,}; struct net_local { spinlock_t lock; struct net_device *next_module; - struct net_device_stats stats; struct timer_list timer; /* Media selection timer. */ long last_rx_time; /* Last Rx, in jiffies, to handle Rx hang. */ int saved_tx_size; @@ -205,7 +204,6 @@ static irqreturn_t atp_interrupt(int irq, void *dev_id); static void net_rx(struct net_device *dev); static void read_block(long ioaddr, int length, unsigned char *buffer, int data_mode); static int net_close(struct net_device *dev); -static struct net_device_stats *net_get_stats(struct net_device *dev); static void set_rx_mode_8002(struct net_device *dev); static void set_rx_mode_8012(struct net_device *dev); static void tx_timeout(struct net_device *dev); @@ -348,7 +346,6 @@ static int __init atp_probe1(long ioaddr) dev->open = net_open; dev->stop = net_close; dev->hard_start_xmit = atp_send_packet; - dev->get_stats = net_get_stats; dev->set_multicast_list = lp->chip_type == RTL8002 ? &set_rx_mode_8002 : &set_rx_mode_8012; dev->tx_timeout = tx_timeout; @@ -538,18 +535,17 @@ static void write_packet(long ioaddr, int length, unsigned char *packet, int pad static void tx_timeout(struct net_device *dev) { - struct net_local *np = netdev_priv(dev); long ioaddr = dev->base_addr; printk(KERN_WARNING "%s: Transmit timed out, %s?\n", dev->name, inb(ioaddr + PAR_CONTROL) & 0x10 ? "network cable problem" : "IRQ conflict"); - np->stats.tx_errors++; + dev->stats.tx_errors++; /* Try to restart the adapter. */ hardware_init(dev); dev->trans_start = jiffies; netif_wake_queue(dev); - np->stats.tx_errors++; + dev->stats.tx_errors++; } static int atp_send_packet(struct sk_buff *skb, struct net_device *dev) @@ -629,7 +625,7 @@ static irqreturn_t atp_interrupt(int irq, void *dev_instance) /* We acknowledged the normal Rx interrupt, so if the interrupt is still outstanding we must have a Rx error. */ if (read_status & (CMR1_IRQ << 3)) { /* Overrun. */ - lp->stats.rx_over_errors++; + dev->stats.rx_over_errors++; /* Set to no-accept mode long enough to remove a packet. */ write_reg_high(ioaddr, CMR2, CMR2h_OFF); net_rx(dev); @@ -649,9 +645,9 @@ static irqreturn_t atp_interrupt(int irq, void *dev_instance) and reinitialize the adapter. */ write_reg(ioaddr, ISR, ISR_TxErr + ISR_TxOK); if (status & (ISR_TxErr<<3)) { - lp->stats.collisions++; + dev->stats.collisions++; if (++lp->re_tx > 15) { - lp->stats.tx_aborted_errors++; + dev->stats.tx_aborted_errors++; hardware_init(dev); break; } @@ -660,7 +656,7 @@ static irqreturn_t atp_interrupt(int irq, void *dev_instance) write_reg(ioaddr, CMR1, CMR1_ReXmit + CMR1_Xmit); } else { /* Finish up the transmit. */ - lp->stats.tx_packets++; + dev->stats.tx_packets++; lp->pac_cnt_in_tx_buf--; if ( lp->saved_tx_size) { trigger_send(ioaddr, lp->saved_tx_size); @@ -678,7 +674,7 @@ static irqreturn_t atp_interrupt(int irq, void *dev_instance) "%ld jiffies status %02x CMR1 %02x.\n", dev->name, num_tx_since_rx, jiffies - dev->last_rx, status, (read_nibble(ioaddr, CMR1) >> 3) & 15); - lp->stats.rx_missed_errors++; + dev->stats.rx_missed_errors++; hardware_init(dev); num_tx_since_rx = 0; break; @@ -735,13 +731,13 @@ static void atp_timed_checker(unsigned long data) struct net_local *lp = netdev_priv(atp_timed_dev); write_reg_byte(ioaddr, PAR0 + i, atp_timed_dev->dev_addr[i]); if (i == 2) - lp->stats.tx_errors++; + dev->stats.tx_errors++; else if (i == 3) - lp->stats.tx_dropped++; + dev->stats.tx_dropped++; else if (i == 4) - lp->stats.collisions++; + dev->stats.collisions++; else - lp->stats.rx_errors++; + dev->stats.rx_errors++; } #endif } @@ -765,14 +761,14 @@ static void net_rx(struct net_device *dev) printk(KERN_DEBUG " rx_count %04x %04x %04x %04x..", rx_head.pad, rx_head.rx_count, rx_head.rx_status, rx_head.cur_addr); if ((rx_head.rx_status & 0x77) != 0x01) { - lp->stats.rx_errors++; - if (rx_head.rx_status & 0x0004) lp->stats.rx_frame_errors++; - else if (rx_head.rx_status & 0x0002) lp->stats.rx_crc_errors++; + dev->stats.rx_errors++; + if (rx_head.rx_status & 0x0004) dev->stats.rx_frame_errors++; + else if (rx_head.rx_status & 0x0002) dev->stats.rx_crc_errors++; if (net_debug > 3) printk(KERN_DEBUG "%s: Unknown ATP Rx error %04x.\n", dev->name, rx_head.rx_status); if (rx_head.rx_status & 0x0020) { - lp->stats.rx_fifo_errors++; + dev->stats.rx_fifo_errors++; write_reg_high(ioaddr, CMR1, CMR1h_TxENABLE); write_reg_high(ioaddr, CMR1, CMR1h_RxENABLE | CMR1h_TxENABLE); } else if (rx_head.rx_status & 0x0050) @@ -787,7 +783,7 @@ static void net_rx(struct net_device *dev) if (skb == NULL) { printk(KERN_ERR "%s: Memory squeeze, dropping packet.\n", dev->name); - lp->stats.rx_dropped++; + dev->stats.rx_dropped++; goto done; } @@ -796,8 +792,8 @@ static void net_rx(struct net_device *dev) skb->protocol = eth_type_trans(skb, dev); netif_rx(skb); dev->last_rx = jiffies; - lp->stats.rx_packets++; - lp->stats.rx_bytes += pkt_len; + dev->stats.rx_packets++; + dev->stats.rx_bytes += pkt_len; } done: write_reg(ioaddr, CMR1, CMR1_NextPkt); @@ -849,15 +845,6 @@ net_close(struct net_device *dev) return 0; } -/* Get the current statistics. This may be called with the card open or - closed. */ -static struct net_device_stats * -net_get_stats(struct net_device *dev) -{ - struct net_local *lp = netdev_priv(dev); - return &lp->stats; -} - /* * Set or clear the multicast filter for this adapter. */ diff --git a/drivers/net/au1000_eth.c b/drivers/net/au1000_eth.c index e86b3691765b..b46c5d8a77bd 100644 --- a/drivers/net/au1000_eth.c +++ b/drivers/net/au1000_eth.c @@ -90,7 +90,6 @@ static int au1000_rx(struct net_device *); static irqreturn_t au1000_interrupt(int, void *); static void au1000_tx_timeout(struct net_device *); static void set_rx_mode(struct net_device *); -static struct net_device_stats *au1000_get_stats(struct net_device *); static int au1000_ioctl(struct net_device *, struct ifreq *, int); static int mdio_read(struct net_device *, int, int); static void mdio_write(struct net_device *, int, int, u16); @@ -772,7 +771,6 @@ static struct net_device * au1000_probe(int port_num) dev->open = au1000_open; dev->hard_start_xmit = au1000_tx; dev->stop = au1000_close; - dev->get_stats = au1000_get_stats; dev->set_multicast_list = &set_rx_mode; dev->do_ioctl = &au1000_ioctl; SET_ETHTOOL_OPS(dev, &au1000_ethtool_ops); @@ -1038,7 +1036,7 @@ static void __exit au1000_cleanup_module(void) static void update_tx_stats(struct net_device *dev, u32 status) { struct au1000_private *aup = (struct au1000_private *) dev->priv; - struct net_device_stats *ps = &aup->stats; + struct net_device_stats *ps = &dev->stats; if (status & TX_FRAME_ABORTED) { if (!aup->phy_dev || (DUPLEX_FULL == aup->phy_dev->duplex)) { @@ -1094,7 +1092,7 @@ static void au1000_tx_ack(struct net_device *dev) static int au1000_tx(struct sk_buff *skb, struct net_device *dev) { struct au1000_private *aup = (struct au1000_private *) dev->priv; - struct net_device_stats *ps = &aup->stats; + struct net_device_stats *ps = &dev->stats; volatile tx_dma_t *ptxd; u32 buff_stat; db_dest_t *pDB; @@ -1148,7 +1146,7 @@ static int au1000_tx(struct sk_buff *skb, struct net_device *dev) static inline void update_rx_stats(struct net_device *dev, u32 status) { struct au1000_private *aup = (struct au1000_private *) dev->priv; - struct net_device_stats *ps = &aup->stats; + struct net_device_stats *ps = &dev->stats; ps->rx_packets++; if (status & RX_MCAST_FRAME) @@ -1201,7 +1199,7 @@ static int au1000_rx(struct net_device *dev) printk(KERN_ERR "%s: Memory squeeze, dropping packet.\n", dev->name); - aup->stats.rx_dropped++; + dev->stats.rx_dropped++; continue; } skb_reserve(skb, 2); /* 16 byte IP header align */ @@ -1324,18 +1322,5 @@ static int au1000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) return phy_mii_ioctl(aup->phy_dev, if_mii(rq), cmd); } -static struct net_device_stats *au1000_get_stats(struct net_device *dev) -{ - struct au1000_private *aup = (struct au1000_private *) dev->priv; - - if (au1000_debug > 4) - printk("%s: au1000_get_stats: dev=%p\n", dev->name, dev); - - if (netif_device_present(dev)) { - return &aup->stats; - } - return 0; -} - module_init(au1000_init_module); module_exit(au1000_cleanup_module); diff --git a/drivers/net/au1000_eth.h b/drivers/net/au1000_eth.h index 52fe00dd6d24..f3baeaa12854 100644 --- a/drivers/net/au1000_eth.h +++ b/drivers/net/au1000_eth.h @@ -115,6 +115,5 @@ struct au1000_private { u32 vaddr; /* virtual address of rx/tx buffers */ dma_addr_t dma_addr; /* dma address of rx/tx buffers */ - struct net_device_stats stats; spinlock_t lock; /* Serialise access to device */ }; diff --git a/drivers/net/bfin_mac.c b/drivers/net/bfin_mac.c index e5bbcbe8de5f..cebe55440e13 100644 --- a/drivers/net/bfin_mac.c +++ b/drivers/net/bfin_mac.c @@ -579,8 +579,8 @@ out: adjust_tx_list(); current_tx_ptr = current_tx_ptr->next; dev->trans_start = jiffies; - lp->stats.tx_packets++; - lp->stats.tx_bytes += (skb->len); + dev->stats.tx_packets++; + dev->stats.tx_bytes += (skb->len); return 0; } @@ -596,7 +596,7 @@ static void bf537mac_rx(struct net_device *dev) if (!new_skb) { printk(KERN_NOTICE DRV_NAME ": rx: low on mem - packet dropped\n"); - lp->stats.rx_dropped++; + dev->stats.rx_dropped++; goto out; } /* reserve 2 bytes for RXDWA padding */ @@ -618,8 +618,8 @@ static void bf537mac_rx(struct net_device *dev) #endif netif_rx(skb); - lp->stats.rx_packets++; - lp->stats.rx_bytes += len; + dev->stats.rx_packets++; + dev->stats.rx_bytes += len; current_rx_ptr->status.status_word = 0x00000000; current_rx_ptr = current_rx_ptr->next; @@ -732,20 +732,6 @@ static void bf537mac_timeout(struct net_device *dev) netif_wake_queue(dev); } -/* - * Get the current statistics. - * This may be called with the card open or closed. - */ -static struct net_device_stats *bf537mac_query_statistics(struct net_device - *dev) -{ - struct bf537mac_local *lp = netdev_priv(dev); - - pr_debug("%s: %s\n", dev->name, __FUNCTION__); - - return &lp->stats; -} - /* * This routine will, depending on the values passed to it, * either make it accept multicast packets, go into @@ -891,7 +877,6 @@ static int __init bf537mac_probe(struct net_device *dev) dev->stop = bf537mac_close; dev->hard_start_xmit = bf537mac_hard_start_xmit; dev->tx_timeout = bf537mac_timeout; - dev->get_stats = bf537mac_query_statistics; dev->set_multicast_list = bf537mac_set_multicast_list; #ifdef CONFIG_NET_POLL_CONTROLLER dev->poll_controller = bf537mac_poll; diff --git a/drivers/net/bfin_mac.h b/drivers/net/bfin_mac.h index af87189b85fa..b82724692283 100644 --- a/drivers/net/bfin_mac.h +++ b/drivers/net/bfin_mac.h @@ -104,8 +104,6 @@ struct bf537mac_local { * can find out semi-useless statistics of how well the card is * performing */ - struct net_device_stats stats; - int version; int FlowEnabled; /* record if data flow is active */ diff --git a/drivers/net/bmac.c b/drivers/net/bmac.c index ee157f5a5dbc..2761441f6644 100644 --- a/drivers/net/bmac.c +++ b/drivers/net/bmac.c @@ -75,7 +75,6 @@ struct bmac_data { int tx_fill; int tx_empty; unsigned char tx_fullup; - struct net_device_stats stats; struct timer_list tx_timeout; int timeout_active; int sleeping; @@ -145,7 +144,6 @@ static unsigned char *bmac_emergency_rxbuf; static int bmac_open(struct net_device *dev); static int bmac_close(struct net_device *dev); static int bmac_transmit_packet(struct sk_buff *skb, struct net_device *dev); -static struct net_device_stats *bmac_stats(struct net_device *dev); static void bmac_set_multicast(struct net_device *dev); static void bmac_reset_and_enable(struct net_device *dev); static void bmac_start_chip(struct net_device *dev); @@ -668,7 +666,7 @@ static int bmac_transmit_packet(struct sk_buff *skb, struct net_device *dev) bp->tx_bufs[bp->tx_fill] = skb; bp->tx_fill = i; - bp->stats.tx_bytes += skb->len; + dev->stats.tx_bytes += skb->len; dbdma_continue(td); @@ -707,8 +705,8 @@ static irqreturn_t bmac_rxdma_intr(int irq, void *dev_id) nb = RX_BUFLEN - residual - 2; if (nb < (ETHERMINPACKET - ETHERCRC)) { skb = NULL; - bp->stats.rx_length_errors++; - bp->stats.rx_errors++; + dev->stats.rx_length_errors++; + dev->stats.rx_errors++; } else { skb = bp->rx_bufs[i]; bp->rx_bufs[i] = NULL; @@ -719,10 +717,10 @@ static irqreturn_t bmac_rxdma_intr(int irq, void *dev_id) skb->protocol = eth_type_trans(skb, dev); netif_rx(skb); dev->last_rx = jiffies; - ++bp->stats.rx_packets; - bp->stats.rx_bytes += nb; + ++dev->stats.rx_packets; + dev->stats.rx_bytes += nb; } else { - ++bp->stats.rx_dropped; + ++dev->stats.rx_dropped; } dev->last_rx = jiffies; if ((skb = bp->rx_bufs[i]) == NULL) { @@ -785,7 +783,7 @@ static irqreturn_t bmac_txdma_intr(int irq, void *dev_id) } if (bp->tx_bufs[bp->tx_empty]) { - ++bp->stats.tx_packets; + ++dev->stats.tx_packets; dev_kfree_skb_irq(bp->tx_bufs[bp->tx_empty]); } bp->tx_bufs[bp->tx_empty] = NULL; @@ -807,13 +805,6 @@ static irqreturn_t bmac_txdma_intr(int irq, void *dev_id) return IRQ_HANDLED; } -static struct net_device_stats *bmac_stats(struct net_device *dev) -{ - struct bmac_data *p = netdev_priv(dev); - - return &p->stats; -} - #ifndef SUNHME_MULTICAST /* Real fast bit-reversal algorithm, 6-bit values */ static int reverse6[64] = { @@ -1080,17 +1071,17 @@ static irqreturn_t bmac_misc_intr(int irq, void *dev_id) } /* XXDEBUG(("bmac_misc_intr, status=%#08x\n", status)); */ /* bmac_txdma_intr_inner(irq, dev_id); */ - /* if (status & FrameReceived) bp->stats.rx_dropped++; */ - if (status & RxErrorMask) bp->stats.rx_errors++; - if (status & RxCRCCntExp) bp->stats.rx_crc_errors++; - if (status & RxLenCntExp) bp->stats.rx_length_errors++; - if (status & RxOverFlow) bp->stats.rx_over_errors++; - if (status & RxAlignCntExp) bp->stats.rx_frame_errors++; - - /* if (status & FrameSent) bp->stats.tx_dropped++; */ - if (status & TxErrorMask) bp->stats.tx_errors++; - if (status & TxUnderrun) bp->stats.tx_fifo_errors++; - if (status & TxNormalCollExp) bp->stats.collisions++; + /* if (status & FrameReceived) dev->stats.rx_dropped++; */ + if (status & RxErrorMask) dev->stats.rx_errors++; + if (status & RxCRCCntExp) dev->stats.rx_crc_errors++; + if (status & RxLenCntExp) dev->stats.rx_length_errors++; + if (status & RxOverFlow) dev->stats.rx_over_errors++; + if (status & RxAlignCntExp) dev->stats.rx_frame_errors++; + + /* if (status & FrameSent) dev->stats.tx_dropped++; */ + if (status & TxErrorMask) dev->stats.tx_errors++; + if (status & TxUnderrun) dev->stats.tx_fifo_errors++; + if (status & TxNormalCollExp) dev->stats.collisions++; return IRQ_HANDLED; } @@ -1324,7 +1315,6 @@ static int __devinit bmac_probe(struct macio_dev *mdev, const struct of_device_i dev->stop = bmac_close; dev->ethtool_ops = &bmac_ethtool_ops; dev->hard_start_xmit = bmac_output; - dev->get_stats = bmac_stats; dev->set_multicast_list = bmac_set_multicast; dev->set_mac_address = bmac_set_address; @@ -1542,7 +1532,7 @@ static void bmac_tx_timeout(unsigned long data) XXDEBUG((KERN_DEBUG "bmac: tx empty=%d fill=%d fullup=%d\n", bp->tx_empty, bp->tx_fill, bp->tx_fullup)); i = bp->tx_empty; - ++bp->stats.tx_errors; + ++dev->stats.tx_errors; if (i != bp->tx_fill) { dev_kfree_skb(bp->tx_bufs[i]); bp->tx_bufs[i] = NULL; diff --git a/drivers/net/de600.c b/drivers/net/de600.c index 5dd0d9c0eac9..421c2ca49711 100644 --- a/drivers/net/de600.c +++ b/drivers/net/de600.c @@ -154,11 +154,6 @@ static int de600_close(struct net_device *dev) return 0; } -static struct net_device_stats *get_stats(struct net_device *dev) -{ - return (struct net_device_stats *)(dev->priv); -} - static inline void trigger_interrupt(struct net_device *dev) { de600_put_command(FLIP_IRQ); @@ -308,7 +303,7 @@ static int de600_tx_intr(struct net_device *dev, int irq_status) if (!(irq_status & TX_FAILED16)) { tx_fifo_out = (tx_fifo_out + 1) % TX_PAGES; ++free_tx_pages; - ((struct net_device_stats *)(dev->priv))->tx_packets++; + dev->stats.tx_packets++; netif_wake_queue(dev); } @@ -375,8 +370,8 @@ static void de600_rx_intr(struct net_device *dev) /* update stats */ dev->last_rx = jiffies; - ((struct net_device_stats *)(dev->priv))->rx_packets++; /* count all receives */ - ((struct net_device_stats *)(dev->priv))->rx_bytes += size; /* count all received bytes */ + dev->stats.rx_packets++; /* count all receives */ + dev->stats.rx_bytes += size; /* count all received bytes */ /* * If any worth-while packets have been received, netif_rx() @@ -390,7 +385,7 @@ static struct net_device * __init de600_probe(void) struct net_device *dev; int err; - dev = alloc_etherdev(sizeof(struct net_device_stats)); + dev = alloc_etherdev(0); if (!dev) return ERR_PTR(-ENOMEM); @@ -448,8 +443,6 @@ static struct net_device * __init de600_probe(void) printk(":%02X",dev->dev_addr[i]); printk("\n"); - dev->get_stats = get_stats; - dev->open = de600_open; dev->stop = de600_close; dev->hard_start_xmit = &de600_start_xmit; diff --git a/drivers/net/de600.h b/drivers/net/de600.h index 1288e48ba704..e80ecbabcf4e 100644 --- a/drivers/net/de600.h +++ b/drivers/net/de600.h @@ -121,7 +121,6 @@ static u8 de600_read_byte(unsigned char type, struct net_device *dev); /* Put in the device structure. */ static int de600_open(struct net_device *dev); static int de600_close(struct net_device *dev); -static struct net_device_stats *get_stats(struct net_device *dev); static int de600_start_xmit(struct sk_buff *skb, struct net_device *dev); /* Dispatch from interrupts. */ diff --git a/drivers/net/de620.c b/drivers/net/de620.c index a92c207b8839..4b93902906ba 100644 --- a/drivers/net/de620.c +++ b/drivers/net/de620.c @@ -216,7 +216,6 @@ MODULE_PARM_DESC(de620_debug, "DE-620 debug level (0-2)"); /* Put in the device structure. */ static int de620_open(struct net_device *); static int de620_close(struct net_device *); -static struct net_device_stats *get_stats(struct net_device *); static void de620_set_multicast_list(struct net_device *); static int de620_start_xmit(struct sk_buff *, struct net_device *); @@ -478,16 +477,6 @@ static int de620_close(struct net_device *dev) return 0; } -/********************************************* - * - * Return current statistics - * - */ -static struct net_device_stats *get_stats(struct net_device *dev) -{ - return (struct net_device_stats *)(dev->priv); -} - /********************************************* * * Set or clear the multicast filter for this adaptor. @@ -579,7 +568,7 @@ static int de620_start_xmit(struct sk_buff *skb, struct net_device *dev) if(!(using_txbuf == (TXBF0 | TXBF1))) netif_wake_queue(dev); - ((struct net_device_stats *)(dev->priv))->tx_packets++; + dev->stats.tx_packets++; spin_unlock_irqrestore(&de620_lock, flags); dev_kfree_skb (skb); return 0; @@ -660,7 +649,7 @@ static int de620_rx_intr(struct net_device *dev) /* You win some, you lose some. And sometimes plenty... */ adapter_init(dev); netif_wake_queue(dev); - ((struct net_device_stats *)(dev->priv))->rx_over_errors++; + dev->stats.rx_over_errors++; return 0; } @@ -680,7 +669,7 @@ static int de620_rx_intr(struct net_device *dev) next_rx_page = header_buf.Rx_NextPage; /* at least a try... */ de620_send_command(dev, W_DUMMY); de620_set_register(dev, W_NPRF, next_rx_page); - ((struct net_device_stats *)(dev->priv))->rx_over_errors++; + dev->stats.rx_over_errors++; return 0; } next_rx_page = pagelink; @@ -693,7 +682,7 @@ static int de620_rx_intr(struct net_device *dev) skb = dev_alloc_skb(size+2); if (skb == NULL) { /* Yeah, but no place to put it... */ printk(KERN_WARNING "%s: Couldn't allocate a sk_buff of size %d.\n", dev->name, size); - ((struct net_device_stats *)(dev->priv))->rx_dropped++; + dev->stats.rx_dropped++; } else { /* Yep! Go get it! */ skb_reserve(skb,2); /* Align */ @@ -706,8 +695,8 @@ static int de620_rx_intr(struct net_device *dev) netif_rx(skb); /* deliver it "upstairs" */ dev->last_rx = jiffies; /* count all receives */ - ((struct net_device_stats *)(dev->priv))->rx_packets++; - ((struct net_device_stats *)(dev->priv))->rx_bytes += size; + dev->stats.rx_packets++; + dev->stats.rx_bytes += size; } } @@ -819,7 +808,7 @@ struct net_device * __init de620_probe(int unit) int err = -ENOMEM; int i; - dev = alloc_etherdev(sizeof(struct net_device_stats)); + dev = alloc_etherdev(0); if (!dev) goto out; @@ -879,7 +868,6 @@ struct net_device * __init de620_probe(int unit) else printk(" UTP)\n"); - dev->get_stats = get_stats; dev->open = de620_open; dev->stop = de620_close; dev->hard_start_xmit = de620_start_xmit; diff --git a/drivers/net/declance.c b/drivers/net/declance.c index b2577f40124e..7e7ac3330e60 100644 --- a/drivers/net/declance.c +++ b/drivers/net/declance.c @@ -258,8 +258,6 @@ struct lance_private { int rx_new, tx_new; int rx_old, tx_old; - struct net_device_stats stats; - unsigned short busmaster_regval; struct timer_list multicast_timer; @@ -583,22 +581,22 @@ static int lance_rx(struct net_device *dev) /* We got an incomplete frame? */ if ((bits & LE_R1_POK) != LE_R1_POK) { - lp->stats.rx_over_errors++; - lp->stats.rx_errors++; + dev->stats.rx_over_errors++; + dev->stats.rx_errors++; } else if (bits & LE_R1_ERR) { /* Count only the end frame as a rx error, * not the beginning */ if (bits & LE_R1_BUF) - lp->stats.rx_fifo_errors++; + dev->stats.rx_fifo_errors++; if (bits & LE_R1_CRC) - lp->stats.rx_crc_errors++; + dev->stats.rx_crc_errors++; if (bits & LE_R1_OFL) - lp->stats.rx_over_errors++; + dev->stats.rx_over_errors++; if (bits & LE_R1_FRA) - lp->stats.rx_frame_errors++; + dev->stats.rx_frame_errors++; if (bits & LE_R1_EOP) - lp->stats.rx_errors++; + dev->stats.rx_errors++; } else { len = (*rds_ptr(rd, mblength, lp->type) & 0xfff) - 4; skb = dev_alloc_skb(len + 2); @@ -606,7 +604,7 @@ static int lance_rx(struct net_device *dev) if (skb == 0) { printk("%s: Memory squeeze, deferring packet.\n", dev->name); - lp->stats.rx_dropped++; + dev->stats.rx_dropped++; *rds_ptr(rd, mblength, lp->type) = 0; *rds_ptr(rd, rmd1, lp->type) = ((lp->rx_buf_ptr_lnc[entry] >> 16) & @@ -614,7 +612,7 @@ static int lance_rx(struct net_device *dev) lp->rx_new = (entry + 1) & RX_RING_MOD_MASK; return 0; } - lp->stats.rx_bytes += len; + dev->stats.rx_bytes += len; skb_reserve(skb, 2); /* 16 byte align */ skb_put(skb, len); /* make room */ @@ -625,7 +623,7 @@ static int lance_rx(struct net_device *dev) skb->protocol = eth_type_trans(skb, dev); netif_rx(skb); dev->last_rx = jiffies; - lp->stats.rx_packets++; + dev->stats.rx_packets++; } /* Return the packet to the pool */ @@ -660,14 +658,14 @@ static void lance_tx(struct net_device *dev) if (*tds_ptr(td, tmd1, lp->type) & LE_T1_ERR) { status = *tds_ptr(td, misc, lp->type); - lp->stats.tx_errors++; + dev->stats.tx_errors++; if (status & LE_T3_RTY) - lp->stats.tx_aborted_errors++; + dev->stats.tx_aborted_errors++; if (status & LE_T3_LCOL) - lp->stats.tx_window_errors++; + dev->stats.tx_window_errors++; if (status & LE_T3_CLOS) { - lp->stats.tx_carrier_errors++; + dev->stats.tx_carrier_errors++; printk("%s: Carrier Lost\n", dev->name); /* Stop the lance */ writereg(&ll->rap, LE_CSR0); @@ -681,7 +679,7 @@ static void lance_tx(struct net_device *dev) * transmitter, restart the adapter. */ if (status & (LE_T3_BUF | LE_T3_UFL)) { - lp->stats.tx_fifo_errors++; + dev->stats.tx_fifo_errors++; printk("%s: Tx: ERR_BUF|ERR_UFL, restarting\n", dev->name); @@ -702,13 +700,13 @@ static void lance_tx(struct net_device *dev) /* One collision before packet was sent. */ if (*tds_ptr(td, tmd1, lp->type) & LE_T1_EONE) - lp->stats.collisions++; + dev->stats.collisions++; /* More than one collision, be optimistic. */ if (*tds_ptr(td, tmd1, lp->type) & LE_T1_EMORE) - lp->stats.collisions += 2; + dev->stats.collisions += 2; - lp->stats.tx_packets++; + dev->stats.tx_packets++; } j = (j + 1) & TX_RING_MOD_MASK; } @@ -754,10 +752,10 @@ static irqreturn_t lance_interrupt(const int irq, void *dev_id) lance_tx(dev); if (csr0 & LE_C0_BABL) - lp->stats.tx_errors++; + dev->stats.tx_errors++; if (csr0 & LE_C0_MISS) - lp->stats.rx_errors++; + dev->stats.rx_errors++; if (csr0 & LE_C0_MERR) { printk("%s: Memory error, status %04x\n", dev->name, csr0); @@ -912,7 +910,7 @@ static int lance_start_xmit(struct sk_buff *skb, struct net_device *dev) len = ETH_ZLEN; } - lp->stats.tx_bytes += len; + dev->stats.tx_bytes += len; entry = lp->tx_new; *lib_ptr(ib, btx_ring[entry].length, lp->type) = (-len); @@ -938,13 +936,6 @@ static int lance_start_xmit(struct sk_buff *skb, struct net_device *dev) return 0; } -static struct net_device_stats *lance_get_stats(struct net_device *dev) -{ - struct lance_private *lp = netdev_priv(dev); - - return &lp->stats; -} - static void lance_load_multicast(struct net_device *dev) { struct lance_private *lp = netdev_priv(dev); @@ -1244,7 +1235,6 @@ static int __init dec_lance_probe(struct device *bdev, const int type) dev->hard_start_xmit = &lance_start_xmit; dev->tx_timeout = &lance_tx_timeout; dev->watchdog_timeo = 5*HZ; - dev->get_stats = &lance_get_stats; dev->set_multicast_list = &lance_set_multicast; /* lp->ll is the location of the registers for lance card */ diff --git a/drivers/net/depca.c b/drivers/net/depca.c index 183497020bfc..28fa2bdc8c79 100644 --- a/drivers/net/depca.c +++ b/drivers/net/depca.c @@ -485,7 +485,6 @@ struct depca_private { /* Kernel-only (not device) fields */ int rx_new, tx_new; /* The next free ring entry */ int rx_old, tx_old; /* The ring entries to be free()ed. */ - struct net_device_stats stats; spinlock_t lock; struct { /* Private stats counters */ u32 bins[DEPCA_PKT_STAT_SZ]; @@ -522,7 +521,6 @@ static irqreturn_t depca_interrupt(int irq, void *dev_id); static int depca_close(struct net_device *dev); static int depca_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); static void depca_tx_timeout(struct net_device *dev); -static struct net_device_stats *depca_get_stats(struct net_device *dev); static void set_multicast_list(struct net_device *dev); /* @@ -801,7 +799,6 @@ static int __init depca_hw_init (struct net_device *dev, struct device *device) dev->open = &depca_open; dev->hard_start_xmit = &depca_start_xmit; dev->stop = &depca_close; - dev->get_stats = &depca_get_stats; dev->set_multicast_list = &set_multicast_list; dev->do_ioctl = &depca_ioctl; dev->tx_timeout = depca_tx_timeout; @@ -1026,15 +1023,15 @@ static int depca_rx(struct net_device *dev) } if (status & R_ENP) { /* Valid frame status */ if (status & R_ERR) { /* There was an error. */ - lp->stats.rx_errors++; /* Update the error stats. */ + dev->stats.rx_errors++; /* Update the error stats. */ if (status & R_FRAM) - lp->stats.rx_frame_errors++; + dev->stats.rx_frame_errors++; if (status & R_OFLO) - lp->stats.rx_over_errors++; + dev->stats.rx_over_errors++; if (status & R_CRC) - lp->stats.rx_crc_errors++; + dev->stats.rx_crc_errors++; if (status & R_BUFF) - lp->stats.rx_fifo_errors++; + dev->stats.rx_fifo_errors++; } else { short len, pkt_len = readw(&lp->rx_ring[entry].msg_length) - 4; struct sk_buff *skb; @@ -1063,8 +1060,8 @@ static int depca_rx(struct net_device *dev) ** Update stats */ dev->last_rx = jiffies; - lp->stats.rx_packets++; - lp->stats.rx_bytes += pkt_len; + dev->stats.rx_packets++; + dev->stats.rx_bytes += pkt_len; for (i = 1; i < DEPCA_PKT_STAT_SZ - 1; i++) { if (pkt_len < (i * DEPCA_PKT_BIN_SZ)) { lp->pktStats.bins[i]++; @@ -1087,7 +1084,7 @@ static int depca_rx(struct net_device *dev) } } else { printk("%s: Memory squeeze, deferring packet.\n", dev->name); - lp->stats.rx_dropped++; /* Really, deferred. */ + dev->stats.rx_dropped++; /* Really, deferred. */ break; } } @@ -1125,24 +1122,24 @@ static int depca_tx(struct net_device *dev) break; } else if (status & T_ERR) { /* An error occurred. */ status = readl(&lp->tx_ring[entry].misc); - lp->stats.tx_errors++; + dev->stats.tx_errors++; if (status & TMD3_RTRY) - lp->stats.tx_aborted_errors++; + dev->stats.tx_aborted_errors++; if (status & TMD3_LCAR) - lp->stats.tx_carrier_errors++; + dev->stats.tx_carrier_errors++; if (status & TMD3_LCOL) - lp->stats.tx_window_errors++; + dev->stats.tx_window_errors++; if (status & TMD3_UFLO) - lp->stats.tx_fifo_errors++; + dev->stats.tx_fifo_errors++; if (status & (TMD3_BUFF | TMD3_UFLO)) { /* Trigger an immediate send demand. */ outw(CSR0, DEPCA_ADDR); outw(INEA | TDMD, DEPCA_DATA); } } else if (status & (T_MORE | T_ONE)) { - lp->stats.collisions++; + dev->stats.collisions++; } else { - lp->stats.tx_packets++; + dev->stats.tx_packets++; } /* Update all the pointers */ @@ -1234,15 +1231,6 @@ static int InitRestartDepca(struct net_device *dev) return status; } -static struct net_device_stats *depca_get_stats(struct net_device *dev) -{ - struct depca_private *lp = (struct depca_private *) dev->priv; - - /* Null body since there is no framing error counter */ - - return &lp->stats; -} - /* ** Set or clear the multicast filter for this adaptor. */ diff --git a/drivers/net/dgrs.c b/drivers/net/dgrs.c index ddedb76303d5..a9ef79da3dc7 100644 --- a/drivers/net/dgrs.c +++ b/drivers/net/dgrs.c @@ -193,11 +193,6 @@ static int dgrs_nicmode; */ typedef struct { - /* - * Stuff for generic ethercard I/F - */ - struct net_device_stats stats; - /* * DGRS specific data */ @@ -499,7 +494,7 @@ dgrs_rcv_frame( if ((skb = dev_alloc_skb(len+5)) == NULL) { printk("%s: dev_alloc_skb failed for rcv buffer\n", devN->name); - ++privN->stats.rx_dropped; + ++dev0->stats.rx_dropped; /* discarding the frame */ goto out; } @@ -667,8 +662,8 @@ again: skb->protocol = eth_type_trans(skb, devN); netif_rx(skb); devN->last_rx = jiffies; - ++privN->stats.rx_packets; - privN->stats.rx_bytes += len; + ++devN->stats.rx_packets; + devN->stats.rx_bytes += len; out: cbp->xmit.status = I596_CB_STATUS_C | I596_CB_STATUS_OK; @@ -776,7 +771,7 @@ frame_done: priv0->rfdp->status = I596_RFD_C | I596_RFD_OK; priv0->rfdp = (I596_RFD *) S2H(priv0->rfdp->next); - ++privN->stats.tx_packets; + ++devN->stats.tx_packets; dev_kfree_skb (skb); return (0); @@ -805,16 +800,6 @@ static int dgrs_close( struct net_device *dev ) return (0); } -/* - * Get statistics - */ -static struct net_device_stats *dgrs_get_stats( struct net_device *dev ) -{ - DGRS_PRIV *priv = (DGRS_PRIV *) dev->priv; - - return (&priv->stats); -} - /* * Set multicast list and/or promiscuous mode */ @@ -1213,7 +1198,6 @@ dgrs_probe1(struct net_device *dev) */ dev->open = &dgrs_open; dev->stop = &dgrs_close; - dev->get_stats = &dgrs_get_stats; dev->hard_start_xmit = &dgrs_start_xmit; dev->set_multicast_list = &dgrs_set_multicast_list; dev->do_ioctl = &dgrs_ioctl; diff --git a/drivers/net/dm9000.c b/drivers/net/dm9000.c index 857eb366bb11..f691ef61b2d3 100644 --- a/drivers/net/dm9000.c +++ b/drivers/net/dm9000.c @@ -148,7 +148,6 @@ typedef struct board_info { struct resource *irq_res; struct timer_list timer; - struct net_device_stats stats; unsigned char srom[128]; spinlock_t lock; @@ -166,8 +165,6 @@ static int dm9000_stop(struct net_device *); static void dm9000_timer(unsigned long); static void dm9000_init_dm9000(struct net_device *); -static struct net_device_stats *dm9000_get_stats(struct net_device *); - static irqreturn_t dm9000_interrupt(int, void *); static int dm9000_phy_read(struct net_device *dev, int phyaddr_unsused, int reg); @@ -558,7 +555,6 @@ dm9000_probe(struct platform_device *pdev) ndev->tx_timeout = &dm9000_timeout; ndev->watchdog_timeo = msecs_to_jiffies(watchdog); ndev->stop = &dm9000_stop; - ndev->get_stats = &dm9000_get_stats; ndev->set_multicast_list = &dm9000_hash_table; #ifdef CONFIG_NET_POLL_CONTROLLER ndev->poll_controller = &dm9000_poll_controller; @@ -713,7 +709,7 @@ dm9000_start_xmit(struct sk_buff *skb, struct net_device *dev) writeb(DM9000_MWCMD, db->io_addr); (db->outblk)(db->io_data, skb->data, skb->len); - db->stats.tx_bytes += skb->len; + dev->stats.tx_bytes += skb->len; db->tx_pkt_cnt++; /* TX control: First packet immediately send, second packet queue */ @@ -790,7 +786,7 @@ dm9000_tx_done(struct net_device *dev, board_info_t * db) if (tx_status & (NSR_TX2END | NSR_TX1END)) { /* One packet sent complete */ db->tx_pkt_cnt--; - db->stats.tx_packets++; + dev->stats.tx_packets++; /* Queue packet check & send */ if (db->tx_pkt_cnt > 0) { @@ -851,17 +847,6 @@ dm9000_interrupt(int irq, void *dev_id) return IRQ_HANDLED; } -/* - * Get statistics from driver. - */ -static struct net_device_stats * -dm9000_get_stats(struct net_device *dev) -{ - board_info_t *db = (board_info_t *) dev->priv; - return &db->stats; -} - - /* * A periodic timer routine * Dynamic media sense, allocated Rx buffer... @@ -939,15 +924,15 @@ dm9000_rx(struct net_device *dev) GoodPacket = false; if (rxhdr.RxStatus & 0x100) { PRINTK1("fifo error\n"); - db->stats.rx_fifo_errors++; + dev->stats.rx_fifo_errors++; } if (rxhdr.RxStatus & 0x200) { PRINTK1("crc error\n"); - db->stats.rx_crc_errors++; + dev->stats.rx_crc_errors++; } if (rxhdr.RxStatus & 0x8000) { PRINTK1("length error\n"); - db->stats.rx_length_errors++; + dev->stats.rx_length_errors++; } } @@ -960,12 +945,12 @@ dm9000_rx(struct net_device *dev) /* Read received packet from RX SRAM */ (db->inblk)(db->io_data, rdptr, RxLen); - db->stats.rx_bytes += RxLen; + dev->stats.rx_bytes += RxLen; /* Pass to upper layer */ skb->protocol = eth_type_trans(skb, dev); netif_rx(skb); - db->stats.rx_packets++; + dev->stats.rx_packets++; } else { /* need to dump the packet's data */ diff --git a/drivers/net/e100.c b/drivers/net/e100.c index f9aa13e04ada..99126564f1a0 100644 --- a/drivers/net/e100.c +++ b/drivers/net/e100.c @@ -558,7 +558,6 @@ struct nic { enum mac mac; enum phy phy; struct params params; - struct net_device_stats net_stats; struct timer_list watchdog; struct timer_list blink_timer; struct mii_if_info mii; @@ -1483,7 +1482,8 @@ static void e100_set_multicast_list(struct net_device *netdev) static void e100_update_stats(struct nic *nic) { - struct net_device_stats *ns = &nic->net_stats; + struct net_device *dev = nic->netdev; + struct net_device_stats *ns = &dev->stats; struct stats *s = &nic->mem->stats; u32 *complete = (nic->mac < mac_82558_D101_A4) ? &s->fc_xmt_pause : (nic->mac < mac_82559_D101M) ? (u32 *)&s->xmt_tco_frames : @@ -1661,6 +1661,7 @@ static int e100_xmit_frame(struct sk_buff *skb, struct net_device *netdev) static int e100_tx_clean(struct nic *nic) { + struct net_device *dev = nic->netdev; struct cb *cb; int tx_cleaned = 0; @@ -1675,8 +1676,8 @@ static int e100_tx_clean(struct nic *nic) cb->status); if(likely(cb->skb != NULL)) { - nic->net_stats.tx_packets++; - nic->net_stats.tx_bytes += cb->skb->len; + dev->stats.tx_packets++; + dev->stats.tx_bytes += cb->skb->len; pci_unmap_single(nic->pdev, le32_to_cpu(cb->u.tcb.tbd.buf_addr), @@ -1807,6 +1808,7 @@ static int e100_rx_alloc_skb(struct nic *nic, struct rx *rx) static int e100_rx_indicate(struct nic *nic, struct rx *rx, unsigned int *work_done, unsigned int work_to_do) { + struct net_device *dev = nic->netdev; struct sk_buff *skb = rx->skb; struct rfd *rfd = (struct rfd *)skb->data; u16 rfd_status, actual_size; @@ -1851,8 +1853,8 @@ static int e100_rx_indicate(struct nic *nic, struct rx *rx, nic->rx_over_length_errors++; dev_kfree_skb_any(skb); } else { - nic->net_stats.rx_packets++; - nic->net_stats.rx_bytes += actual_size; + dev->stats.rx_packets++; + dev->stats.rx_bytes += actual_size; nic->netdev->last_rx = jiffies; netif_receive_skb(skb); if(work_done) @@ -2015,12 +2017,6 @@ static void e100_netpoll(struct net_device *netdev) } #endif -static struct net_device_stats *e100_get_stats(struct net_device *netdev) -{ - struct nic *nic = netdev_priv(netdev); - return &nic->net_stats; -} - static int e100_set_mac_address(struct net_device *netdev, void *p) { struct nic *nic = netdev_priv(netdev); @@ -2457,7 +2453,7 @@ static void e100_get_ethtool_stats(struct net_device *netdev, int i; for(i = 0; i < E100_NET_STATS_LEN; i++) - data[i] = ((unsigned long *)&nic->net_stats)[i]; + data[i] = ((unsigned long *)&netdev->stats)[i]; data[i++] = nic->tx_deferred; data[i++] = nic->tx_single_collisions; @@ -2562,7 +2558,6 @@ static int __devinit e100_probe(struct pci_dev *pdev, netdev->open = e100_open; netdev->stop = e100_close; netdev->hard_start_xmit = e100_xmit_frame; - netdev->get_stats = e100_get_stats; netdev->set_multicast_list = e100_set_multicast_list; netdev->set_mac_address = e100_set_mac_address; netdev->change_mtu = e100_change_mtu; diff --git a/drivers/net/eepro.c b/drivers/net/eepro.c index 6eb84f14c88d..54811f6f766d 100644 --- a/drivers/net/eepro.c +++ b/drivers/net/eepro.c @@ -192,7 +192,6 @@ static unsigned int net_debug = NET_DEBUG; /* Information that need to be kept for each board. */ struct eepro_local { - struct net_device_stats stats; unsigned rx_start; unsigned tx_start; /* start of the transmit chain */ int tx_last; /* pointer to last packet in the transmit chain */ @@ -315,7 +314,6 @@ static irqreturn_t eepro_interrupt(int irq, void *dev_id); static void eepro_rx(struct net_device *dev); static void eepro_transmit_interrupt(struct net_device *dev); static int eepro_close(struct net_device *dev); -static struct net_device_stats *eepro_get_stats(struct net_device *dev); static void set_multicast_list(struct net_device *dev); static void eepro_tx_timeout (struct net_device *dev); @@ -514,7 +512,7 @@ buffer (transmit-buffer = 32K - receive-buffer). /* a complete sel reset */ #define eepro_complete_selreset(ioaddr) { \ - lp->stats.tx_errors++;\ + dev->stats.tx_errors++;\ eepro_sel_reset(ioaddr);\ lp->tx_end = \ lp->xmt_lower_limit;\ @@ -856,7 +854,6 @@ static int __init eepro_probe1(struct net_device *dev, int autoprobe) dev->open = eepro_open; dev->stop = eepro_close; dev->hard_start_xmit = eepro_send_packet; - dev->get_stats = eepro_get_stats; dev->set_multicast_list = &set_multicast_list; dev->tx_timeout = eepro_tx_timeout; dev->watchdog_timeo = TX_TIMEOUT; @@ -1154,9 +1151,9 @@ static int eepro_send_packet(struct sk_buff *skb, struct net_device *dev) if (hardware_send_packet(dev, buf, length)) /* we won't wake queue here because we're out of space */ - lp->stats.tx_dropped++; + dev->stats.tx_dropped++; else { - lp->stats.tx_bytes+=skb->len; + dev->stats.tx_bytes+=skb->len; dev->trans_start = jiffies; netif_wake_queue(dev); } @@ -1166,7 +1163,7 @@ static int eepro_send_packet(struct sk_buff *skb, struct net_device *dev) dev_kfree_skb (skb); /* You might need to clean up and record Tx statistics here. */ - /* lp->stats.tx_aborted_errors++; */ + /* dev->stats.tx_aborted_errors++; */ if (net_debug > 5) printk(KERN_DEBUG "%s: exiting eepro_send_packet routine.\n", dev->name); @@ -1273,16 +1270,6 @@ static int eepro_close(struct net_device *dev) return 0; } -/* Get the current statistics. This may be called with the card open or - closed. */ -static struct net_device_stats * -eepro_get_stats(struct net_device *dev) -{ - struct eepro_local *lp = netdev_priv(dev); - - return &lp->stats; -} - /* Set or clear the multicast filter for this adaptor. */ static void @@ -1575,12 +1562,12 @@ eepro_rx(struct net_device *dev) /* Malloc up new buffer. */ struct sk_buff *skb; - lp->stats.rx_bytes+=rcv_size; + dev->stats.rx_bytes+=rcv_size; rcv_size &= 0x3fff; skb = dev_alloc_skb(rcv_size+5); if (skb == NULL) { printk(KERN_NOTICE "%s: Memory squeeze, dropping packet.\n", dev->name); - lp->stats.rx_dropped++; + dev->stats.rx_dropped++; rcv_car = lp->rx_start + RCV_HEADER + rcv_size; lp->rx_start = rcv_next_frame; outw(rcv_next_frame, ioaddr + HOST_ADDRESS_REG); @@ -1602,28 +1589,28 @@ eepro_rx(struct net_device *dev) skb->protocol = eth_type_trans(skb,dev); netif_rx(skb); dev->last_rx = jiffies; - lp->stats.rx_packets++; + dev->stats.rx_packets++; } else { /* Not sure will ever reach here, I set the 595 to discard bad received frames */ - lp->stats.rx_errors++; + dev->stats.rx_errors++; if (rcv_status & 0x0100) - lp->stats.rx_over_errors++; + dev->stats.rx_over_errors++; else if (rcv_status & 0x0400) - lp->stats.rx_frame_errors++; + dev->stats.rx_frame_errors++; else if (rcv_status & 0x0800) - lp->stats.rx_crc_errors++; + dev->stats.rx_crc_errors++; printk(KERN_DEBUG "%s: event = %#x, status = %#x, next = %#x, size = %#x\n", dev->name, rcv_event, rcv_status, rcv_next_frame, rcv_size); } if (rcv_status & 0x1000) - lp->stats.rx_length_errors++; + dev->stats.rx_length_errors++; rcv_car = lp->rx_start + RCV_HEADER + rcv_size; lp->rx_start = rcv_next_frame; @@ -1666,11 +1653,11 @@ eepro_transmit_interrupt(struct net_device *dev) netif_wake_queue (dev); if (xmt_status & TX_OK) - lp->stats.tx_packets++; + dev->stats.tx_packets++; else { - lp->stats.tx_errors++; + dev->stats.tx_errors++; if (xmt_status & 0x0400) { - lp->stats.tx_carrier_errors++; + dev->stats.tx_carrier_errors++; printk(KERN_DEBUG "%s: carrier error\n", dev->name); printk(KERN_DEBUG "%s: XMT status = %#x\n", @@ -1684,11 +1671,11 @@ eepro_transmit_interrupt(struct net_device *dev) } } if (xmt_status & 0x000f) { - lp->stats.collisions += (xmt_status & 0x000f); + dev->stats.collisions += (xmt_status & 0x000f); } if ((xmt_status & 0x0040) == 0x0) { - lp->stats.tx_heartbeat_errors++; + dev->stats.tx_heartbeat_errors++; } } } diff --git a/drivers/net/eexpress.c b/drivers/net/eexpress.c index 6c91bfa72bb2..9c85e50014b4 100644 --- a/drivers/net/eexpress.c +++ b/drivers/net/eexpress.c @@ -135,7 +135,6 @@ struct net_local { - struct net_device_stats stats; unsigned long last_tx; /* jiffies when last transmit started */ unsigned long init_time; /* jiffies when eexp_hw_init586 called */ unsigned short rx_first; /* first rx buf, same as RX_BUF_START */ @@ -247,7 +246,6 @@ static char mca_irqmap[] = { 12, 9, 3, 4, 5, 10, 11, 15 }; static int eexp_open(struct net_device *dev); static int eexp_close(struct net_device *dev); static void eexp_timeout(struct net_device *dev); -static struct net_device_stats *eexp_stats(struct net_device *dev); static int eexp_xmit(struct sk_buff *buf, struct net_device *dev); static irqreturn_t eexp_irq(int irq, void *dev_addr); @@ -532,17 +530,6 @@ static int eexp_close(struct net_device *dev) return 0; } -/* - * Return interface stats - */ - -static struct net_device_stats *eexp_stats(struct net_device *dev) -{ - struct net_local *lp = netdev_priv(dev); - - return &lp->stats; -} - /* * This gets called when a higher level thinks we are broken. Check that * nothing has become jammed in the CU. @@ -646,7 +633,7 @@ static void eexp_timeout(struct net_device *dev) printk(KERN_INFO "%s: transmit timed out, %s?\n", dev->name, (SCB_complete(status)?"lost interrupt": "board on fire")); - lp->stats.tx_errors++; + dev->stats.tx_errors++; lp->last_tx = jiffies; if (!SCB_complete(status)) { scb_command(dev, SCB_CUabort); @@ -694,7 +681,7 @@ static int eexp_xmit(struct sk_buff *buf, struct net_device *dev) { unsigned short *data = (unsigned short *)buf->data; - lp->stats.tx_bytes += length; + dev->stats.tx_bytes += length; eexp_hw_tx_pio(dev,data,length); } @@ -843,7 +830,7 @@ static irqreturn_t eexp_irq(int irq, void *dev_info) outw(rbd+8, ioaddr+READ_PTR); printk("[%04x]\n", inw(ioaddr+DATAPORT)); #endif - lp->stats.rx_errors++; + dev->stats.rx_errors++; #if 1 eexp_hw_rxinit(dev); #else @@ -952,17 +939,17 @@ static void eexp_hw_rx_pio(struct net_device *dev) } else if (!FD_OK(status)) { - lp->stats.rx_errors++; + dev->stats.rx_errors++; if (FD_CRC(status)) - lp->stats.rx_crc_errors++; + dev->stats.rx_crc_errors++; if (FD_Align(status)) - lp->stats.rx_frame_errors++; + dev->stats.rx_frame_errors++; if (FD_Resrc(status)) - lp->stats.rx_fifo_errors++; + dev->stats.rx_fifo_errors++; if (FD_DMA(status)) - lp->stats.rx_over_errors++; + dev->stats.rx_over_errors++; if (FD_Short(status)) - lp->stats.rx_length_errors++; + dev->stats.rx_length_errors++; } else { @@ -972,7 +959,7 @@ static void eexp_hw_rx_pio(struct net_device *dev) if (skb == NULL) { printk(KERN_WARNING "%s: Memory squeeze, dropping packet\n",dev->name); - lp->stats.rx_dropped++; + dev->stats.rx_dropped++; break; } skb_reserve(skb, 2); @@ -981,8 +968,8 @@ static void eexp_hw_rx_pio(struct net_device *dev) skb->protocol = eth_type_trans(skb,dev); netif_rx(skb); dev->last_rx = jiffies; - lp->stats.rx_packets++; - lp->stats.rx_bytes += pkt_len; + dev->stats.rx_packets++; + dev->stats.rx_bytes += pkt_len; } outw(rx_block, ioaddr+WRITE_PTR); outw(0, ioaddr+DATAPORT); @@ -1053,7 +1040,7 @@ static void eexp_hw_tx_pio(struct net_device *dev, unsigned short *buf, outw(0xFFFF, ioaddr+SIGNAL_CA); } - lp->stats.tx_packets++; + dev->stats.tx_packets++; lp->last_tx = jiffies; } @@ -1180,7 +1167,6 @@ static int __init eexp_hw_probe(struct net_device *dev, unsigned short ioaddr) dev->open = eexp_open; dev->stop = eexp_close; dev->hard_start_xmit = eexp_xmit; - dev->get_stats = eexp_stats; dev->set_multicast_list = &eexp_set_multicast; dev->tx_timeout = eexp_timeout; dev->watchdog_timeo = 2*HZ; @@ -1263,35 +1249,35 @@ static unsigned short eexp_hw_lasttxstat(struct net_device *dev) else { lp->last_tx_restart = 0; - lp->stats.collisions += Stat_NoColl(status); + dev->stats.collisions += Stat_NoColl(status); if (!Stat_OK(status)) { char *whatsup = NULL; - lp->stats.tx_errors++; + dev->stats.tx_errors++; if (Stat_Abort(status)) - lp->stats.tx_aborted_errors++; + dev->stats.tx_aborted_errors++; if (Stat_TNoCar(status)) { whatsup = "aborted, no carrier"; - lp->stats.tx_carrier_errors++; + dev->stats.tx_carrier_errors++; } if (Stat_TNoCTS(status)) { whatsup = "aborted, lost CTS"; - lp->stats.tx_carrier_errors++; + dev->stats.tx_carrier_errors++; } if (Stat_TNoDMA(status)) { whatsup = "FIFO underran"; - lp->stats.tx_fifo_errors++; + dev->stats.tx_fifo_errors++; } if (Stat_TXColl(status)) { whatsup = "aborted, too many collisions"; - lp->stats.tx_aborted_errors++; + dev->stats.tx_aborted_errors++; } if (whatsup) printk(KERN_INFO "%s: transmit %s\n", dev->name, whatsup); } else - lp->stats.tx_packets++; + dev->stats.tx_packets++; } if (tx_block == TX_BUF_START+((lp->num_tx_bufs-1)*TX_BUF_SIZE)) lp->tx_reap = tx_block = TX_BUF_START; diff --git a/drivers/net/eql.c b/drivers/net/eql.c index 7266f6dbdd95..18f1364d3d5b 100644 --- a/drivers/net/eql.c +++ b/drivers/net/eql.c @@ -128,7 +128,6 @@ static int eql_open(struct net_device *dev); static int eql_close(struct net_device *dev); static int eql_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd); static int eql_slave_xmit(struct sk_buff *skb, struct net_device *dev); -static struct net_device_stats *eql_get_stats(struct net_device *dev); #define eql_is_slave(dev) ((dev->flags & IFF_SLAVE) == IFF_SLAVE) #define eql_is_master(dev) ((dev->flags & IFF_MASTER) == IFF_MASTER) @@ -180,7 +179,6 @@ static void __init eql_setup(struct net_device *dev) dev->stop = eql_close; dev->do_ioctl = eql_ioctl; dev->hard_start_xmit = eql_slave_xmit; - dev->get_stats = eql_get_stats; /* * Now we undo some of the things that eth_setup does @@ -337,9 +335,9 @@ static int eql_slave_xmit(struct sk_buff *skb, struct net_device *dev) skb->priority = 1; slave->bytes_queued += skb->len; dev_queue_xmit(skb); - eql->stats.tx_packets++; + dev->stats.tx_packets++; } else { - eql->stats.tx_dropped++; + dev->stats.tx_dropped++; dev_kfree_skb(skb); } @@ -348,12 +346,6 @@ static int eql_slave_xmit(struct sk_buff *skb, struct net_device *dev) return 0; } -static struct net_device_stats * eql_get_stats(struct net_device *dev) -{ - equalizer_t *eql = netdev_priv(dev); - return &eql->stats; -} - /* * Private ioctl functions */ diff --git a/drivers/net/eth16i.c b/drivers/net/eth16i.c index 0e3b33717cac..243fc6b354b5 100644 --- a/drivers/net/eth16i.c +++ b/drivers/net/eth16i.c @@ -380,7 +380,6 @@ static unsigned int eth16i_debug = ETH16I_DEBUG; /* Information for each board */ struct eth16i_local { - struct net_device_stats stats; unsigned char tx_started; unsigned char tx_buf_busy; unsigned short tx_queue; /* Number of packets in transmit buffer */ @@ -426,8 +425,6 @@ static int eth16i_set_irq(struct net_device *dev); static ushort eth16i_parse_mediatype(const char* s); #endif -static struct net_device_stats *eth16i_get_stats(struct net_device *dev); - static char cardname[] __initdata = "ICL EtherTeam 16i/32"; static int __init do_eth16i_probe(struct net_device *dev) @@ -557,7 +554,6 @@ static int __init eth16i_probe1(struct net_device *dev, int ioaddr) dev->open = eth16i_open; dev->stop = eth16i_close; dev->hard_start_xmit = eth16i_tx; - dev->get_stats = eth16i_get_stats; dev->set_multicast_list = eth16i_multicast; dev->tx_timeout = eth16i_timeout; dev->watchdog_timeo = TX_TIMEOUT; @@ -1045,7 +1041,7 @@ static void eth16i_timeout(struct net_device *dev) printk(KERN_DEBUG "lp->tx_queue_len = %d\n", lp->tx_queue_len); printk(KERN_DEBUG "lp->tx_started = %d\n", lp->tx_started); } - lp->stats.tx_errors++; + dev->stats.tx_errors++; eth16i_reset(dev); dev->trans_start = jiffies; outw(ETH16I_INTR_ON, ioaddr + TX_INTR_REG); @@ -1130,7 +1126,6 @@ static int eth16i_tx(struct sk_buff *skb, struct net_device *dev) static void eth16i_rx(struct net_device *dev) { - struct eth16i_local *lp = netdev_priv(dev); int ioaddr = dev->base_addr; int boguscount = MAX_RX_LOOP; @@ -1149,16 +1144,16 @@ static void eth16i_rx(struct net_device *dev) inb(ioaddr + RECEIVE_MODE_REG), status); if( !(status & PKT_GOOD) ) { - lp->stats.rx_errors++; + dev->stats.rx_errors++; if( (pkt_len < ETH_ZLEN) || (pkt_len > ETH_FRAME_LEN) ) { - lp->stats.rx_length_errors++; + dev->stats.rx_length_errors++; eth16i_reset(dev); return; } else { eth16i_skip_packet(dev); - lp->stats.rx_dropped++; + dev->stats.rx_dropped++; } } else { /* Ok so now we should have a good packet */ @@ -1169,7 +1164,7 @@ static void eth16i_rx(struct net_device *dev) printk(KERN_WARNING "%s: Could'n allocate memory for packet (len %d)\n", dev->name, pkt_len); eth16i_skip_packet(dev); - lp->stats.rx_dropped++; + dev->stats.rx_dropped++; break; } @@ -1212,8 +1207,8 @@ static void eth16i_rx(struct net_device *dev) } netif_rx(skb); dev->last_rx = jiffies; - lp->stats.rx_packets++; - lp->stats.rx_bytes += pkt_len; + dev->stats.rx_packets++; + dev->stats.rx_bytes += pkt_len; } /* else */ @@ -1250,32 +1245,32 @@ static irqreturn_t eth16i_interrupt(int irq, void *dev_id) if( status & 0x7f00 ) { - lp->stats.rx_errors++; + dev->stats.rx_errors++; if(status & (BUS_RD_ERR << 8) ) printk(KERN_WARNING "%s: Bus read error.\n",dev->name); - if(status & (SHORT_PKT_ERR << 8) ) lp->stats.rx_length_errors++; - if(status & (ALIGN_ERR << 8) ) lp->stats.rx_frame_errors++; - if(status & (CRC_ERR << 8) ) lp->stats.rx_crc_errors++; - if(status & (RX_BUF_OVERFLOW << 8) ) lp->stats.rx_over_errors++; + if(status & (SHORT_PKT_ERR << 8) ) dev->stats.rx_length_errors++; + if(status & (ALIGN_ERR << 8) ) dev->stats.rx_frame_errors++; + if(status & (CRC_ERR << 8) ) dev->stats.rx_crc_errors++; + if(status & (RX_BUF_OVERFLOW << 8) ) dev->stats.rx_over_errors++; } if( status & 0x001a) { - lp->stats.tx_errors++; + dev->stats.tx_errors++; - if(status & CR_LOST) lp->stats.tx_carrier_errors++; - if(status & TX_JABBER_ERR) lp->stats.tx_window_errors++; + if(status & CR_LOST) dev->stats.tx_carrier_errors++; + if(status & TX_JABBER_ERR) dev->stats.tx_window_errors++; #if 0 if(status & COLLISION) { - lp->stats.collisions += + dev->stats.collisions += ((inb(ioaddr+TRANSMIT_MODE_REG) & 0xF0) >> 4); } #endif if(status & COLLISIONS_16) { if(lp->col_16 < MAX_COL_16) { lp->col_16++; - lp->stats.collisions++; + dev->stats.collisions++; /* Resume transmitting, skip failed packet */ outb(0x02, ioaddr + COL_16_REG); } @@ -1288,8 +1283,8 @@ static irqreturn_t eth16i_interrupt(int irq, void *dev_id) if( status & 0x00ff ) { /* Let's check the transmit status reg */ if(status & TX_DONE) { /* The transmit has been done */ - lp->stats.tx_packets = lp->tx_buffered_packets; - lp->stats.tx_bytes += lp->tx_buffered_bytes; + dev->stats.tx_packets = lp->tx_buffered_packets; + dev->stats.tx_bytes += lp->tx_buffered_bytes; lp->col_16 = 0; if(lp->tx_queue) { /* Is there still packets ? */ @@ -1369,12 +1364,6 @@ static void eth16i_multicast(struct net_device *dev) } } -static struct net_device_stats *eth16i_get_stats(struct net_device *dev) -{ - struct eth16i_local *lp = netdev_priv(dev); - return &lp->stats; -} - static void eth16i_select_regbank(unsigned char banknbr, int ioaddr) { unsigned char data; diff --git a/drivers/net/ewrk3.c b/drivers/net/ewrk3.c index 6a5d0436e89e..142aa225d89e 100644 --- a/drivers/net/ewrk3.c +++ b/drivers/net/ewrk3.c @@ -275,7 +275,6 @@ struct ewrk3_private { u_long shmem_base; /* Shared memory start address */ void __iomem *shmem; u_long shmem_length; /* Shared memory window length */ - struct net_device_stats stats; /* Public stats */ struct ewrk3_stats pktStats; /* Private stats counters */ u_char irq_mask; /* Adapter IRQ mask bits */ u_char mPage; /* Maximum 2kB Page number */ @@ -302,7 +301,6 @@ static int ewrk3_open(struct net_device *dev); static int ewrk3_queue_pkt(struct sk_buff *skb, struct net_device *dev); static irqreturn_t ewrk3_interrupt(int irq, void *dev_id); static int ewrk3_close(struct net_device *dev); -static struct net_device_stats *ewrk3_get_stats(struct net_device *dev); static void set_multicast_list(struct net_device *dev); static int ewrk3_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); static const struct ethtool_ops ethtool_ops_203; @@ -611,7 +609,6 @@ ewrk3_hw_init(struct net_device *dev, u_long iobase) dev->open = ewrk3_open; dev->hard_start_xmit = ewrk3_queue_pkt; dev->stop = ewrk3_close; - dev->get_stats = ewrk3_get_stats; dev->set_multicast_list = set_multicast_list; dev->do_ioctl = ewrk3_ioctl; if (lp->adapter_name[4] == '3') @@ -863,7 +860,7 @@ static int ewrk3_queue_pkt (struct sk_buff *skb, struct net_device *dev) ENABLE_IRQs; spin_unlock_irq (&lp->hw_lock); - lp->stats.tx_bytes += skb->len; + dev->stats.tx_bytes += skb->len; dev->trans_start = jiffies; dev_kfree_skb (skb); @@ -980,13 +977,13 @@ static int ewrk3_rx(struct net_device *dev) } if (!(rx_status & R_ROK)) { /* There was an error. */ - lp->stats.rx_errors++; /* Update the error stats. */ + dev->stats.rx_errors++; /* Update the error stats. */ if (rx_status & R_DBE) - lp->stats.rx_frame_errors++; + dev->stats.rx_frame_errors++; if (rx_status & R_CRC) - lp->stats.rx_crc_errors++; + dev->stats.rx_crc_errors++; if (rx_status & R_PLL) - lp->stats.rx_fifo_errors++; + dev->stats.rx_fifo_errors++; } else { struct sk_buff *skb; @@ -1037,11 +1034,11 @@ static int ewrk3_rx(struct net_device *dev) ** Update stats */ dev->last_rx = jiffies; - lp->stats.rx_packets++; - lp->stats.rx_bytes += pkt_len; + dev->stats.rx_packets++; + dev->stats.rx_bytes += pkt_len; } else { printk("%s: Insufficient memory; nuking packet.\n", dev->name); - lp->stats.rx_dropped++; /* Really, deferred. */ + dev->stats.rx_dropped++; /* Really, deferred. */ break; } } @@ -1071,11 +1068,11 @@ static int ewrk3_tx(struct net_device *dev) while ((tx_status = inb(EWRK3_TDQ)) > 0) { /* Whilst there's old buffers */ if (tx_status & T_VSTS) { /* The status is valid */ if (tx_status & T_TXE) { - lp->stats.tx_errors++; + dev->stats.tx_errors++; if (tx_status & T_NCL) - lp->stats.tx_carrier_errors++; + dev->stats.tx_carrier_errors++; if (tx_status & T_LCL) - lp->stats.tx_window_errors++; + dev->stats.tx_window_errors++; if (tx_status & T_CTU) { if ((tx_status & T_COLL) ^ T_XUR) { lp->pktStats.tx_underruns++; @@ -1084,13 +1081,13 @@ static int ewrk3_tx(struct net_device *dev) } } else if (tx_status & T_COLL) { if ((tx_status & T_COLL) ^ T_XCOLL) { - lp->stats.collisions++; + dev->stats.collisions++; } else { lp->pktStats.excessive_collisions++; } } } else { - lp->stats.tx_packets++; + dev->stats.tx_packets++; } } } @@ -1133,14 +1130,6 @@ static int ewrk3_close(struct net_device *dev) return 0; } -static struct net_device_stats *ewrk3_get_stats(struct net_device *dev) -{ - struct ewrk3_private *lp = netdev_priv(dev); - - /* Null body since there is no framing error counter */ - return &lp->stats; -} - /* ** Set or clear the multicast filter for this adapter. */ diff --git a/drivers/net/fec.c b/drivers/net/fec.c index 4e8df910c00d..4419c3cee995 100644 --- a/drivers/net/fec.c +++ b/drivers/net/fec.c @@ -204,7 +204,6 @@ struct fec_enet_private { cbd_t *tx_bd_base; cbd_t *cur_rx, *cur_tx; /* The next free ring entry */ cbd_t *dirty_tx; /* The ring entries to be free()ed. */ - struct net_device_stats stats; uint tx_full; spinlock_t lock; @@ -234,7 +233,6 @@ static irqreturn_t fec_enet_interrupt(int irq, void * dev_id); static void fec_enet_tx(struct net_device *dev); static void fec_enet_rx(struct net_device *dev); static int fec_enet_close(struct net_device *dev); -static struct net_device_stats *fec_enet_get_stats(struct net_device *dev); static void set_multicast_list(struct net_device *dev); static void fec_restart(struct net_device *dev, int duplex); static void fec_stop(struct net_device *dev); @@ -359,7 +357,7 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev) */ fep->tx_skbuff[fep->skb_cur] = skb; - fep->stats.tx_bytes += skb->len; + dev->stats.tx_bytes += skb->len; fep->skb_cur = (fep->skb_cur+1) & TX_RING_MOD_MASK; /* Push the data cache so the CPM does not get stale memory @@ -409,7 +407,7 @@ fec_timeout(struct net_device *dev) struct fec_enet_private *fep = netdev_priv(dev); printk("%s: transmit timed out.\n", dev->name); - fep->stats.tx_errors++; + dev->stats.tx_errors++; #ifndef final_version { int i; @@ -511,19 +509,19 @@ fec_enet_tx(struct net_device *dev) if (status & (BD_ENET_TX_HB | BD_ENET_TX_LC | BD_ENET_TX_RL | BD_ENET_TX_UN | BD_ENET_TX_CSL)) { - fep->stats.tx_errors++; + dev->stats.tx_errors++; if (status & BD_ENET_TX_HB) /* No heartbeat */ - fep->stats.tx_heartbeat_errors++; + dev->stats.tx_heartbeat_errors++; if (status & BD_ENET_TX_LC) /* Late collision */ - fep->stats.tx_window_errors++; + dev->stats.tx_window_errors++; if (status & BD_ENET_TX_RL) /* Retrans limit */ - fep->stats.tx_aborted_errors++; + dev->stats.tx_aborted_errors++; if (status & BD_ENET_TX_UN) /* Underrun */ - fep->stats.tx_fifo_errors++; + dev->stats.tx_fifo_errors++; if (status & BD_ENET_TX_CSL) /* Carrier lost */ - fep->stats.tx_carrier_errors++; + dev->stats.tx_carrier_errors++; } else { - fep->stats.tx_packets++; + dev->stats.tx_packets++; } #ifndef final_version @@ -534,7 +532,7 @@ fec_enet_tx(struct net_device *dev) * but we eventually sent the packet OK. */ if (status & BD_ENET_TX_DEF) - fep->stats.collisions++; + dev->stats.collisions++; /* Free the sk buffer associated with this last transmit. */ @@ -607,17 +605,17 @@ while (!((status = bdp->cbd_sc) & BD_ENET_RX_EMPTY)) { /* Check for errors. */ if (status & (BD_ENET_RX_LG | BD_ENET_RX_SH | BD_ENET_RX_NO | BD_ENET_RX_CR | BD_ENET_RX_OV)) { - fep->stats.rx_errors++; + dev->stats.rx_errors++; if (status & (BD_ENET_RX_LG | BD_ENET_RX_SH)) { /* Frame too long or too short. */ - fep->stats.rx_length_errors++; + dev->stats.rx_length_errors++; } if (status & BD_ENET_RX_NO) /* Frame alignment */ - fep->stats.rx_frame_errors++; + dev->stats.rx_frame_errors++; if (status & BD_ENET_RX_CR) /* CRC Error */ - fep->stats.rx_crc_errors++; + dev->stats.rx_crc_errors++; if (status & BD_ENET_RX_OV) /* FIFO overrun */ - fep->stats.rx_fifo_errors++; + dev->stats.rx_fifo_errors++; } /* Report late collisions as a frame error. @@ -625,16 +623,16 @@ while (!((status = bdp->cbd_sc) & BD_ENET_RX_EMPTY)) { * have in the buffer. So, just drop this frame on the floor. */ if (status & BD_ENET_RX_CL) { - fep->stats.rx_errors++; - fep->stats.rx_frame_errors++; + dev->stats.rx_errors++; + dev->stats.rx_frame_errors++; goto rx_processing_done; } /* Process the incoming frame. */ - fep->stats.rx_packets++; + dev->stats.rx_packets++; pkt_len = bdp->cbd_datlen; - fep->stats.rx_bytes += pkt_len; + dev->stats.rx_bytes += pkt_len; data = (__u8*)__va(bdp->cbd_bufaddr); /* This does 16 byte alignment, exactly what we need. @@ -646,7 +644,7 @@ while (!((status = bdp->cbd_sc) & BD_ENET_RX_EMPTY)) { if (skb == NULL) { printk("%s: Memory squeeze, dropping packet.\n", dev->name); - fep->stats.rx_dropped++; + dev->stats.rx_dropped++; } else { skb_put(skb,pkt_len-4); /* Make room */ skb_copy_to_linear_data(skb, data, pkt_len-4); @@ -2220,13 +2218,6 @@ fec_enet_close(struct net_device *dev) return 0; } -static struct net_device_stats *fec_enet_get_stats(struct net_device *dev) -{ - struct fec_enet_private *fep = netdev_priv(dev); - - return &fep->stats; -} - /* Set or clear the multicast filter for this adaptor. * Skeleton taken from sunlance driver. * The CPM Ethernet implementation allows Multicast as well as individual @@ -2462,7 +2453,6 @@ int __init fec_enet_init(struct net_device *dev) dev->tx_timeout = fec_timeout; dev->watchdog_timeo = TX_TIMEOUT; dev->stop = fec_enet_close; - dev->get_stats = fec_enet_get_stats; dev->set_multicast_list = set_multicast_list; for (i=0; ipoll_controller = gfar_netpoll; #endif dev->stop = gfar_close; - dev->get_stats = gfar_get_stats; dev->change_mtu = gfar_change_mtu; dev->mtu = 1500; dev->set_multicast_list = gfar_set_multi; @@ -1013,7 +1011,7 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev) unsigned long flags; /* Update transmit stats */ - priv->stats.tx_bytes += skb->len; + dev->stats.tx_bytes += skb->len; /* Lock priv now */ spin_lock_irqsave(&priv->txlock, flags); @@ -1086,7 +1084,7 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev) if (txbdp == priv->dirty_tx) { netif_stop_queue(dev); - priv->stats.tx_fifo_errors++; + dev->stats.tx_fifo_errors++; } /* Update the current txbd to the next one */ @@ -1119,14 +1117,6 @@ static int gfar_close(struct net_device *dev) return 0; } -/* returns a net_device_stats structure pointer */ -static struct net_device_stats * gfar_get_stats(struct net_device *dev) -{ - struct gfar_private *priv = netdev_priv(dev); - - return &(priv->stats); -} - /* Changes the mac address if the controller is not running. */ int gfar_set_mac_address(struct net_device *dev) { @@ -1238,7 +1228,7 @@ static void gfar_timeout(struct net_device *dev) { struct gfar_private *priv = netdev_priv(dev); - priv->stats.tx_errors++; + dev->stats.tx_errors++; if (dev->flags & IFF_UP) { stop_gfar(dev); @@ -1268,12 +1258,12 @@ static irqreturn_t gfar_transmit(int irq, void *dev_id) if ((bdp == priv->cur_tx) && (netif_queue_stopped(dev) == 0)) break; - priv->stats.tx_packets++; + dev->stats.tx_packets++; /* Deferred means some collisions occurred during transmit, */ /* but we eventually sent the packet. */ if (bdp->status & TXBD_DEF) - priv->stats.collisions++; + dev->stats.collisions++; /* Free the sk buffer associated with this TxBD */ dev_kfree_skb_irq(priv->tx_skbuff[priv->skb_dirtytx]); @@ -1345,7 +1335,7 @@ struct sk_buff * gfar_new_skb(struct net_device *dev, struct rxbd8 *bdp) static inline void count_errors(unsigned short status, struct gfar_private *priv) { - struct net_device_stats *stats = &priv->stats; + struct net_device_stats *stats = &dev->stats; struct gfar_extra_stats *estats = &priv->extra_stats; /* If the packet was truncated, none of the other errors @@ -1470,7 +1460,7 @@ static int gfar_process_frame(struct net_device *dev, struct sk_buff *skb, if (NULL == skb) { if (netif_msg_rx_err(priv)) printk(KERN_WARNING "%s: Missing skb!!.\n", dev->name); - priv->stats.rx_dropped++; + dev->stats.rx_dropped++; priv->extra_stats.rx_skbmissing++; } else { int ret; @@ -1528,7 +1518,7 @@ int gfar_clean_rx_ring(struct net_device *dev, int rx_work_limit) (RXBD_LARGE | RXBD_SHORT | RXBD_NONOCTET | RXBD_CRCERR | RXBD_OVERRUN | RXBD_TRUNCATED))) { /* Increment the number of packets */ - priv->stats.rx_packets++; + dev->stats.rx_packets++; howmany++; /* Remove the FCS from the packet length */ @@ -1536,7 +1526,7 @@ int gfar_clean_rx_ring(struct net_device *dev, int rx_work_limit) gfar_process_frame(dev, skb, pkt_len); - priv->stats.rx_bytes += pkt_len; + dev->stats.rx_bytes += pkt_len; } else { count_errors(bdp->status, priv); @@ -1916,17 +1906,17 @@ static irqreturn_t gfar_error(int irq, void *dev_id) /* Update the error counters */ if (events & IEVENT_TXE) { - priv->stats.tx_errors++; + dev->stats.tx_errors++; if (events & IEVENT_LC) - priv->stats.tx_window_errors++; + dev->stats.tx_window_errors++; if (events & IEVENT_CRL) - priv->stats.tx_aborted_errors++; + dev->stats.tx_aborted_errors++; if (events & IEVENT_XFUN) { if (netif_msg_tx_err(priv)) printk(KERN_DEBUG "%s: TX FIFO underrun, " "packet dropped.\n", dev->name); - priv->stats.tx_dropped++; + dev->stats.tx_dropped++; priv->extra_stats.tx_underrun++; /* Reactivate the Tx Queues */ @@ -1936,7 +1926,7 @@ static irqreturn_t gfar_error(int irq, void *dev_id) printk(KERN_DEBUG "%s: Transmit Error\n", dev->name); } if (events & IEVENT_BSY) { - priv->stats.rx_errors++; + dev->stats.rx_errors++; priv->extra_stats.rx_bsy++; gfar_receive(irq, dev_id); @@ -1951,7 +1941,7 @@ static irqreturn_t gfar_error(int irq, void *dev_id) dev->name, gfar_read(&priv->regs->rstat)); } if (events & IEVENT_BABR) { - priv->stats.rx_errors++; + dev->stats.rx_errors++; priv->extra_stats.rx_babr++; if (netif_msg_rx_err(priv)) diff --git a/drivers/net/hplance.c b/drivers/net/hplance.c index c991cb82ff22..be6e5bc7c881 100644 --- a/drivers/net/hplance.c +++ b/drivers/net/hplance.c @@ -141,7 +141,6 @@ static void __init hplance_init(struct net_device *dev, struct dio_dev *d) dev->poll_controller = lance_poll; #endif dev->hard_start_xmit = &lance_start_xmit; - dev->get_stats = &lance_get_stats; dev->set_multicast_list = &lance_set_multicast; dev->dma = 0; diff --git a/drivers/net/ibmlana.c b/drivers/net/ibmlana.c index 67d82fa7659d..eebf39acf586 100644 --- a/drivers/net/ibmlana.c +++ b/drivers/net/ibmlana.c @@ -591,7 +591,7 @@ static void irqrx_handler(struct net_device *dev) skb = dev_alloc_skb(rda.length + 2); if (skb == NULL) - priv->stat.rx_dropped++; + dev->stats.rx_dropped++; else { /* copy out data */ @@ -606,8 +606,8 @@ static void irqrx_handler(struct net_device *dev) /* bookkeeping */ dev->last_rx = jiffies; - priv->stat.rx_packets++; - priv->stat.rx_bytes += rda.length; + dev->stats.rx_packets++; + dev->stats.rx_bytes += rda.length; /* pass to the upper layers */ netif_rx(skb); @@ -617,11 +617,11 @@ static void irqrx_handler(struct net_device *dev) /* otherwise check error status bits and increase statistics */ else { - priv->stat.rx_errors++; + dev->stats.rx_errors++; if (rda.status & RCREG_FAER) - priv->stat.rx_frame_errors++; + dev->stats.rx_frame_errors++; if (rda.status & RCREG_CRCR) - priv->stat.rx_crc_errors++; + dev->stats.rx_crc_errors++; } /* descriptor processed, will become new last descriptor in queue */ @@ -656,8 +656,8 @@ static void irqtx_handler(struct net_device *dev) memcpy_fromio(&tda, priv->base + priv->tdastart + (priv->currtxdescr * sizeof(tda_t)), sizeof(tda_t)); /* update statistics */ - priv->stat.tx_packets++; - priv->stat.tx_bytes += tda.length; + dev->stats.tx_packets++; + dev->stats.tx_bytes += tda.length; /* update our pointers */ priv->txused[priv->currtxdescr] = 0; @@ -680,15 +680,15 @@ static void irqtxerr_handler(struct net_device *dev) memcpy_fromio(&tda, priv->base + priv->tdastart + (priv->currtxdescr * sizeof(tda_t)), sizeof(tda_t)); /* update statistics */ - priv->stat.tx_errors++; + dev->stats.tx_errors++; if (tda.status & (TCREG_NCRS | TCREG_CRSL)) - priv->stat.tx_carrier_errors++; + dev->stats.tx_carrier_errors++; if (tda.status & TCREG_EXC) - priv->stat.tx_aborted_errors++; + dev->stats.tx_aborted_errors++; if (tda.status & TCREG_OWC) - priv->stat.tx_window_errors++; + dev->stats.tx_window_errors++; if (tda.status & TCREG_FU) - priv->stat.tx_fifo_errors++; + dev->stats.tx_fifo_errors++; /* update our pointers */ priv->txused[priv->currtxdescr] = 0; @@ -824,7 +824,7 @@ static int ibmlana_tx(struct sk_buff *skb, struct net_device *dev) if (priv->txusedcnt >= TXBUFCNT) { retval = -EIO; - priv->stat.tx_dropped++; + dev->stats.tx_dropped++; goto tx_done; } @@ -876,14 +876,6 @@ tx_done: return retval; } -/* return pointer to Ethernet statistics */ - -static struct net_device_stats *ibmlana_stats(struct net_device *dev) -{ - ibmlana_priv *priv = netdev_priv(dev); - return &priv->stat; -} - /* switch receiver mode. */ static void ibmlana_set_multicast_list(struct net_device *dev) @@ -978,7 +970,6 @@ static int ibmlana_probe(struct net_device *dev) dev->stop = ibmlana_close; dev->hard_start_xmit = ibmlana_tx; dev->do_ioctl = NULL; - dev->get_stats = ibmlana_stats; dev->set_multicast_list = ibmlana_set_multicast_list; dev->flags |= IFF_MULTICAST; diff --git a/drivers/net/ibmlana.h b/drivers/net/ibmlana.h index 6b58bab9e308..aa3ddbdee4bb 100644 --- a/drivers/net/ibmlana.h +++ b/drivers/net/ibmlana.h @@ -26,7 +26,6 @@ typedef enum { typedef struct { unsigned int slot; /* MCA-Slot-# */ - struct net_device_stats stat; /* packet statistics */ int realirq; /* memorizes actual IRQ, even when currently not allocated */ ibmlana_medium medium; /* physical cannector */ diff --git a/drivers/net/ibmveth.c b/drivers/net/ibmveth.c index db908c40dbe1..bdbf3dead4e2 100644 --- a/drivers/net/ibmveth.c +++ b/drivers/net/ibmveth.c @@ -87,7 +87,6 @@ static int ibmveth_close(struct net_device *dev); static int ibmveth_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd); static int ibmveth_poll(struct napi_struct *napi, int budget); static int ibmveth_start_xmit(struct sk_buff *skb, struct net_device *dev); -static struct net_device_stats *ibmveth_get_stats(struct net_device *dev); static void ibmveth_set_multicast_list(struct net_device *dev); static int ibmveth_change_mtu(struct net_device *dev, int new_mtu); static void ibmveth_proc_register_driver(void); @@ -909,9 +908,9 @@ static int ibmveth_start_xmit(struct sk_buff *skb, struct net_device *netdev) skb->len, DMA_TO_DEVICE); out: spin_lock_irqsave(&adapter->stats_lock, flags); - adapter->stats.tx_dropped += tx_dropped; - adapter->stats.tx_bytes += tx_bytes; - adapter->stats.tx_packets += tx_packets; + netdev->stats.tx_dropped += tx_dropped; + netdev->stats.tx_bytes += tx_bytes; + netdev->stats.tx_packets += tx_packets; adapter->tx_send_failed += tx_send_failed; adapter->tx_map_failed += tx_map_failed; spin_unlock_irqrestore(&adapter->stats_lock, flags); @@ -957,8 +956,8 @@ static int ibmveth_poll(struct napi_struct *napi, int budget) netif_receive_skb(skb); /* send it up */ - adapter->stats.rx_packets++; - adapter->stats.rx_bytes += length; + netdev->stats.rx_packets++; + netdev->stats.rx_bytes += length; frames_processed++; netdev->last_rx = jiffies; } @@ -1003,12 +1002,6 @@ static irqreturn_t ibmveth_interrupt(int irq, void *dev_instance) return IRQ_HANDLED; } -static struct net_device_stats *ibmveth_get_stats(struct net_device *dev) -{ - struct ibmveth_adapter *adapter = dev->priv; - return &adapter->stats; -} - static void ibmveth_set_multicast_list(struct net_device *netdev) { struct ibmveth_adapter *adapter = netdev->priv; @@ -1170,7 +1163,6 @@ static int __devinit ibmveth_probe(struct vio_dev *dev, const struct vio_device_ netdev->open = ibmveth_open; netdev->stop = ibmveth_close; netdev->hard_start_xmit = ibmveth_start_xmit; - netdev->get_stats = ibmveth_get_stats; netdev->set_multicast_list = ibmveth_set_multicast_list; netdev->do_ioctl = ibmveth_ioctl; netdev->ethtool_ops = &netdev_ethtool_ops; diff --git a/drivers/net/ifb.c b/drivers/net/ifb.c index 448e618b6974..15949d3df17e 100644 --- a/drivers/net/ifb.c +++ b/drivers/net/ifb.c @@ -40,7 +40,6 @@ #define TX_Q_LIMIT 32 struct ifb_private { - struct net_device_stats stats; struct tasklet_struct ifb_tasklet; int tasklet_pending; /* mostly debug stats leave in for now */ @@ -61,7 +60,6 @@ static int numifbs = 2; static void ri_tasklet(unsigned long dev); static int ifb_xmit(struct sk_buff *skb, struct net_device *dev); -static struct net_device_stats *ifb_get_stats(struct net_device *dev); static int ifb_open(struct net_device *dev); static int ifb_close(struct net_device *dev); @@ -70,7 +68,7 @@ static void ri_tasklet(unsigned long dev) struct net_device *_dev = (struct net_device *)dev; struct ifb_private *dp = netdev_priv(_dev); - struct net_device_stats *stats = &dp->stats; + struct net_device_stats *stats = &_dev->stats; struct sk_buff *skb; dp->st_task_enter++; @@ -140,7 +138,6 @@ resched: static void ifb_setup(struct net_device *dev) { /* Initialize the device structure. */ - dev->get_stats = ifb_get_stats; dev->hard_start_xmit = ifb_xmit; dev->open = &ifb_open; dev->stop = &ifb_close; @@ -158,7 +155,7 @@ static void ifb_setup(struct net_device *dev) static int ifb_xmit(struct sk_buff *skb, struct net_device *dev) { struct ifb_private *dp = netdev_priv(dev); - struct net_device_stats *stats = &dp->stats; + struct net_device_stats *stats = &dev->stats; int ret = 0; u32 from = G_TC_FROM(skb->tc_verd); @@ -185,19 +182,6 @@ static int ifb_xmit(struct sk_buff *skb, struct net_device *dev) return ret; } -static struct net_device_stats *ifb_get_stats(struct net_device *dev) -{ - struct ifb_private *dp = netdev_priv(dev); - struct net_device_stats *stats = &dp->stats; - - pr_debug("tasklets stats %ld:%ld:%ld:%ld:%ld:%ld:%ld:%ld:%ld \n", - dp->st_task_enter, dp->st_txq_refl_try, dp->st_rxq_enter, - dp->st_rx2tx_tran, dp->st_rxq_notenter, dp->st_rx_frm_egr, - dp->st_rx_frm_ing, dp->st_rxq_check, dp->st_rxq_rsch); - - return stats; -} - static int ifb_close(struct net_device *dev) { struct ifb_private *dp = netdev_priv(dev); diff --git a/drivers/net/iseries_veth.c b/drivers/net/iseries_veth.c index 0433c41f9029..97bd9dc2e52e 100644 --- a/drivers/net/iseries_veth.c +++ b/drivers/net/iseries_veth.c @@ -196,7 +196,6 @@ struct veth_lpar_connection { struct veth_port { struct device *dev; - struct net_device_stats stats; u64 mac_addr; HvLpIndexMap lpar_map; @@ -936,9 +935,6 @@ static void veth_release_connection(struct kobject *kobj) static int veth_open(struct net_device *dev) { - struct veth_port *port = (struct veth_port *) dev->priv; - - memset(&port->stats, 0, sizeof (port->stats)); netif_start_queue(dev); return 0; } @@ -949,13 +945,6 @@ static int veth_close(struct net_device *dev) return 0; } -static struct net_device_stats *veth_get_stats(struct net_device *dev) -{ - struct veth_port *port = (struct veth_port *) dev->priv; - - return &port->stats; -} - static int veth_change_mtu(struct net_device *dev, int new_mtu) { if ((new_mtu < 68) || (new_mtu > VETH_MAX_MTU)) @@ -1084,7 +1073,6 @@ static struct net_device * __init veth_probe_one(int vlan, dev->open = veth_open; dev->hard_start_xmit = veth_start_xmit; dev->stop = veth_close; - dev->get_stats = veth_get_stats; dev->change_mtu = veth_change_mtu; dev->set_mac_address = NULL; dev->set_multicast_list = veth_set_multicast_list; @@ -1183,7 +1171,6 @@ static void veth_transmit_to_many(struct sk_buff *skb, HvLpIndexMap lpmask, struct net_device *dev) { - struct veth_port *port = (struct veth_port *) dev->priv; int i, success, error; success = error = 0; @@ -1199,11 +1186,11 @@ static void veth_transmit_to_many(struct sk_buff *skb, } if (error) - port->stats.tx_errors++; + dev->stats.tx_errors++; if (success) { - port->stats.tx_packets++; - port->stats.tx_bytes += skb->len; + dev->stats.tx_packets++; + dev->stats.tx_bytes += skb->len; } } @@ -1541,8 +1528,8 @@ static void veth_receive(struct veth_lpar_connection *cnx, skb->protocol = eth_type_trans(skb, dev); skb->ip_summed = CHECKSUM_NONE; netif_rx(skb); /* send it up */ - port->stats.rx_packets++; - port->stats.rx_bytes += length; + dev->stats.rx_packets++; + dev->stats.rx_bytes += length; } while (startchunk += nchunks, startchunk < VETH_MAX_FRAMES_PER_MSG); /* Ack it */ diff --git a/drivers/net/lib82596.c b/drivers/net/lib82596.c index 5884f5bd04a4..afa4638052a2 100644 --- a/drivers/net/lib82596.c +++ b/drivers/net/lib82596.c @@ -322,7 +322,6 @@ struct i596_private { struct i596_cmd *cmd_head; int cmd_backlog; u32 last_cmd; - struct net_device_stats stats; int next_tx_cmd; int options; spinlock_t lock; /* serialize access to chip */ @@ -352,7 +351,6 @@ static int i596_open(struct net_device *dev); static int i596_start_xmit(struct sk_buff *skb, struct net_device *dev); static irqreturn_t i596_interrupt(int irq, void *dev_id); static int i596_close(struct net_device *dev); -static struct net_device_stats *i596_get_stats(struct net_device *dev); static void i596_add_cmd(struct net_device *dev, struct i596_cmd *cmd); static void i596_tx_timeout (struct net_device *dev); static void print_eth(unsigned char *buf, char *str); @@ -725,7 +723,7 @@ memory_squeeze: printk(KERN_ERR "%s: i596_rx Memory squeeze, dropping packet.\n", dev->name); - lp->stats.rx_dropped++; + dev->stats.rx_dropped++; } else { if (!rx_in_place) { /* 16 byte align the data fields */ @@ -742,28 +740,28 @@ memory_squeeze: skb->protocol = eth_type_trans(skb, dev); netif_rx(skb); dev->last_rx = jiffies; - lp->stats.rx_packets++; - lp->stats.rx_bytes += pkt_len; + dev->stats.rx_packets++; + dev->stats.rx_bytes += pkt_len; } } else { DEB(DEB_ERRORS, printk(KERN_DEBUG "%s: Error, rfd.stat = 0x%04x\n", dev->name, rfd->stat)); - lp->stats.rx_errors++; + dev->stats.rx_errors++; if (rfd->stat & SWAP16(0x0100)) - lp->stats.collisions++; + dev->stats.collisions++; if (rfd->stat & SWAP16(0x8000)) - lp->stats.rx_length_errors++; + dev->stats.rx_length_errors++; if (rfd->stat & SWAP16(0x0001)) - lp->stats.rx_over_errors++; + dev->stats.rx_over_errors++; if (rfd->stat & SWAP16(0x0002)) - lp->stats.rx_fifo_errors++; + dev->stats.rx_fifo_errors++; if (rfd->stat & SWAP16(0x0004)) - lp->stats.rx_frame_errors++; + dev->stats.rx_frame_errors++; if (rfd->stat & SWAP16(0x0008)) - lp->stats.rx_crc_errors++; + dev->stats.rx_crc_errors++; if (rfd->stat & SWAP16(0x0010)) - lp->stats.rx_length_errors++; + dev->stats.rx_length_errors++; } /* Clear the buffer descriptor count and EOF + F flags */ @@ -821,8 +819,8 @@ static inline void i596_cleanup_cmd(struct net_device *dev, struct i596_private dev_kfree_skb(skb); - lp->stats.tx_errors++; - lp->stats.tx_aborted_errors++; + dev->stats.tx_errors++; + dev->stats.tx_aborted_errors++; ptr->v_next = NULL; ptr->b_next = I596_NULL; @@ -951,10 +949,10 @@ static void i596_tx_timeout (struct net_device *dev) "%s: transmit timed out, status resetting.\n", dev->name)); - lp->stats.tx_errors++; + dev->stats.tx_errors++; /* Try to restart the adaptor */ - if (lp->last_restart == lp->stats.tx_packets) { + if (lp->last_restart == dev->stats.tx_packets) { DEB(DEB_ERRORS, printk(KERN_DEBUG "Resetting board.\n")); /* Shutdown and restart */ i596_reset (dev, lp); @@ -964,7 +962,7 @@ static void i596_tx_timeout (struct net_device *dev) lp->dma->scb.command = SWAP16(CUC_START | RX_START); DMA_WBACK_INV(dev, &(lp->dma->scb), sizeof(struct i596_scb)); ca (dev); - lp->last_restart = lp->stats.tx_packets; + lp->last_restart = dev->stats.tx_packets; } dev->trans_start = jiffies; @@ -999,7 +997,7 @@ static int i596_start_xmit(struct sk_buff *skb, struct net_device *dev) DEB(DEB_ERRORS, printk(KERN_DEBUG "%s: xmit ring full, dropping packet.\n", dev->name)); - lp->stats.tx_dropped++; + dev->stats.tx_dropped++; dev_kfree_skb(skb); } else { @@ -1025,8 +1023,8 @@ static int i596_start_xmit(struct sk_buff *skb, struct net_device *dev) DMA_WBACK_INV(dev, tbd, sizeof(struct i596_tbd)); i596_add_cmd(dev, &tx_cmd->cmd); - lp->stats.tx_packets++; - lp->stats.tx_bytes += length; + dev->stats.tx_packets++; + dev->stats.tx_bytes += length; } netif_start_queue(dev); @@ -1076,7 +1074,6 @@ static int __devinit i82596_probe(struct net_device *dev) dev->open = i596_open; dev->stop = i596_close; dev->hard_start_xmit = i596_start_xmit; - dev->get_stats = i596_get_stats; dev->set_multicast_list = set_multicast_list; dev->tx_timeout = i596_tx_timeout; dev->watchdog_timeo = TX_TIMEOUT; @@ -1197,17 +1194,17 @@ static irqreturn_t i596_interrupt(int irq, void *dev_id) DEB(DEB_TXADDR, print_eth(skb->data, "tx-done")); } else { - lp->stats.tx_errors++; + dev->stats.tx_errors++; if (ptr->status & SWAP16(0x0020)) - lp->stats.collisions++; + dev->stats.collisions++; if (!(ptr->status & SWAP16(0x0040))) - lp->stats.tx_heartbeat_errors++; + dev->stats.tx_heartbeat_errors++; if (ptr->status & SWAP16(0x0400)) - lp->stats.tx_carrier_errors++; + dev->stats.tx_carrier_errors++; if (ptr->status & SWAP16(0x0800)) - lp->stats.collisions++; + dev->stats.collisions++; if (ptr->status & SWAP16(0x1000)) - lp->stats.tx_aborted_errors++; + dev->stats.tx_aborted_errors++; } dma_unmap_single(dev->dev.parent, tx_cmd->dma_addr, @@ -1292,8 +1289,8 @@ static irqreturn_t i596_interrupt(int irq, void *dev_id) "%s: i596 interrupt receive unit inactive, status 0x%x\n", dev->name, status)); ack_cmd |= RX_START; - lp->stats.rx_errors++; - lp->stats.rx_fifo_errors++; + dev->stats.rx_errors++; + dev->stats.rx_fifo_errors++; rebuild_rx_bufs(dev); } } @@ -1346,13 +1343,6 @@ static int i596_close(struct net_device *dev) return 0; } -static struct net_device_stats *i596_get_stats(struct net_device *dev) -{ - struct i596_private *lp = netdev_priv(dev); - - return &lp->stats; -} - /* * Set or clear the multicast filter for this adaptor. */ diff --git a/drivers/net/lp486e.c b/drivers/net/lp486e.c index 408ae6eb6a8b..c5095ecd8b11 100644 --- a/drivers/net/lp486e.c +++ b/drivers/net/lp486e.c @@ -350,7 +350,6 @@ struct i596_private { /* aligned to a 16-byte boundary */ struct i596_cmd *cmd_head; int cmd_backlog; unsigned long last_cmd; - struct net_device_stats stats; spinlock_t cmd_lock; }; @@ -381,7 +380,6 @@ static int i596_open(struct net_device *dev); static int i596_start_xmit(struct sk_buff *skb, struct net_device *dev); static irqreturn_t i596_interrupt(int irq, void *dev_id); static int i596_close(struct net_device *dev); -static struct net_device_stats *i596_get_stats(struct net_device *dev); static void i596_add_cmd(struct net_device *dev, struct i596_cmd *cmd); static void print_eth(char *); static void set_multicast_list(struct net_device *dev); @@ -670,7 +668,7 @@ i596_rx_one(struct net_device *dev, struct i596_private *lp, if (skb == NULL) { printk ("%s: i596_rx Memory squeeze, " "dropping packet.\n", dev->name); - lp->stats.rx_dropped++; + dev->stats.rx_dropped++; return 1; } @@ -679,27 +677,27 @@ i596_rx_one(struct net_device *dev, struct i596_private *lp, skb->protocol = eth_type_trans(skb,dev); netif_rx(skb); dev->last_rx = jiffies; - lp->stats.rx_packets++; + dev->stats.rx_packets++; } else { #if 0 printk("Frame reception error status %04x\n", rfd->stat); #endif - lp->stats.rx_errors++; + dev->stats.rx_errors++; if (rfd->stat & RFD_COLLISION) - lp->stats.collisions++; + dev->stats.collisions++; if (rfd->stat & RFD_SHORT_FRAME_ERR) - lp->stats.rx_length_errors++; + dev->stats.rx_length_errors++; if (rfd->stat & RFD_DMA_ERR) - lp->stats.rx_over_errors++; + dev->stats.rx_over_errors++; if (rfd->stat & RFD_NOBUFS_ERR) - lp->stats.rx_fifo_errors++; + dev->stats.rx_fifo_errors++; if (rfd->stat & RFD_ALIGN_ERR) - lp->stats.rx_frame_errors++; + dev->stats.rx_frame_errors++; if (rfd->stat & RFD_CRC_ERR) - lp->stats.rx_crc_errors++; + dev->stats.rx_crc_errors++; if (rfd->stat & RFD_LENGTH_ERR) - lp->stats.rx_length_errors++; + dev->stats.rx_length_errors++; } rfd->stat = rfd->count = 0; return 0; @@ -755,8 +753,8 @@ i596_cleanup_cmd(struct net_device *dev) { dev_kfree_skb_any(tx_cmd_tbd->skb); - lp->stats.tx_errors++; - lp->stats.tx_aborted_errors++; + dev->stats.tx_errors++; + dev->stats.tx_aborted_errors++; cmd->pa_next = I596_NULL; kfree((unsigned char *)tx_cmd); @@ -867,7 +865,6 @@ static int i596_open(struct net_device *dev) } static int i596_start_xmit (struct sk_buff *skb, struct net_device *dev) { - struct i596_private *lp = dev->priv; struct tx_cmd *tx_cmd; short length; @@ -884,7 +881,7 @@ static int i596_start_xmit (struct sk_buff *skb, struct net_device *dev) { tx_cmd = kmalloc((sizeof (struct tx_cmd) + sizeof (struct i596_tbd)), GFP_ATOMIC); if (tx_cmd == NULL) { printk(KERN_WARNING "%s: i596_xmit Memory squeeze, dropping packet.\n", dev->name); - lp->stats.tx_dropped++; + dev->stats.tx_dropped++; dev_kfree_skb (skb); } else { struct i596_tbd *tx_cmd_tbd; @@ -907,7 +904,7 @@ static int i596_start_xmit (struct sk_buff *skb, struct net_device *dev) { i596_add_cmd (dev, (struct i596_cmd *) tx_cmd); - lp->stats.tx_packets++; + dev->stats.tx_packets++; } return 0; @@ -920,10 +917,10 @@ i596_tx_timeout (struct net_device *dev) { /* Transmitter timeout, serious problems. */ printk(KERN_WARNING "%s: transmit timed out, status resetting.\n", dev->name); - lp->stats.tx_errors++; + dev->stats.tx_errors++; /* Try to restart the adaptor */ - if (lp->last_restart == lp->stats.tx_packets) { + if (lp->last_restart == dev->stats.tx_packets) { printk ("Resetting board.\n"); /* Shutdown and restart */ @@ -933,7 +930,7 @@ i596_tx_timeout (struct net_device *dev) { printk ("Kicking board.\n"); lp->scb.command = (CUC_START | RX_START); CA(); - lp->last_restart = lp->stats.tx_packets; + lp->last_restart = dev->stats.tx_packets; } netif_wake_queue(dev); } @@ -1021,7 +1018,6 @@ static int __init lp486e_probe(struct net_device *dev) { dev->open = &i596_open; dev->stop = &i596_close; dev->hard_start_xmit = &i596_start_xmit; - dev->get_stats = &i596_get_stats; dev->set_multicast_list = &set_multicast_list; dev->watchdog_timeo = 5*HZ; dev->tx_timeout = i596_tx_timeout; @@ -1078,20 +1074,20 @@ i596_handle_CU_completion(struct net_device *dev, if (i596_debug) print_eth(pa_to_va(tx_cmd_tbd->pa_data)); } else { - lp->stats.tx_errors++; + dev->stats.tx_errors++; if (i596_debug) printk("transmission failure:%04x\n", cmd->status); if (cmd->status & 0x0020) - lp->stats.collisions++; + dev->stats.collisions++; if (!(cmd->status & 0x0040)) - lp->stats.tx_heartbeat_errors++; + dev->stats.tx_heartbeat_errors++; if (cmd->status & 0x0400) - lp->stats.tx_carrier_errors++; + dev->stats.tx_carrier_errors++; if (cmd->status & 0x0800) - lp->stats.collisions++; + dev->stats.collisions++; if (cmd->status & 0x1000) - lp->stats.tx_aborted_errors++; + dev->stats.tx_aborted_errors++; } dev_kfree_skb_irq(tx_cmd_tbd->skb); @@ -1242,12 +1238,6 @@ static int i596_close(struct net_device *dev) { return 0; } -static struct net_device_stats * i596_get_stats(struct net_device *dev) { - struct i596_private *lp = dev->priv; - - return &lp->stats; -} - /* * Set or clear the multicast filter for this adaptor. */ diff --git a/drivers/net/mace.c b/drivers/net/mace.c index de3b002e9a4c..ee132b1e09b0 100644 --- a/drivers/net/mace.c +++ b/drivers/net/mace.c @@ -57,7 +57,6 @@ struct mace_data { unsigned char tx_fullup; unsigned char tx_active; unsigned char tx_bad_runt; - struct net_device_stats stats; struct timer_list tx_timeout; int timeout_active; int port_aaui; @@ -78,7 +77,6 @@ struct mace_data { static int mace_open(struct net_device *dev); static int mace_close(struct net_device *dev); static int mace_xmit_start(struct sk_buff *skb, struct net_device *dev); -static struct net_device_stats *mace_stats(struct net_device *dev); static void mace_set_multicast(struct net_device *dev); static void mace_reset(struct net_device *dev); static int mace_set_address(struct net_device *dev, void *addr); @@ -188,7 +186,6 @@ static int __devinit mace_probe(struct macio_dev *mdev, const struct of_device_i mp->tx_cmds = (volatile struct dbdma_cmd *) DBDMA_ALIGN(mp + 1); mp->rx_cmds = mp->tx_cmds + NCMDS_TX * N_TX_RING + 1; - memset(&mp->stats, 0, sizeof(mp->stats)); memset((char *) mp->tx_cmds, 0, (NCMDS_TX*N_TX_RING + N_RX_RING + 2) * sizeof(struct dbdma_cmd)); init_timer(&mp->tx_timeout); @@ -213,7 +210,6 @@ static int __devinit mace_probe(struct macio_dev *mdev, const struct of_device_i dev->open = mace_open; dev->stop = mace_close; dev->hard_start_xmit = mace_xmit_start; - dev->get_stats = mace_stats; dev->set_multicast_list = mace_set_multicast; dev->set_mac_address = mace_set_address; @@ -584,13 +580,6 @@ static int mace_xmit_start(struct sk_buff *skb, struct net_device *dev) return 0; } -static struct net_device_stats *mace_stats(struct net_device *dev) -{ - struct mace_data *p = (struct mace_data *) dev->priv; - - return &p->stats; -} - static void mace_set_multicast(struct net_device *dev) { struct mace_data *mp = (struct mace_data *) dev->priv; @@ -644,19 +633,19 @@ static void mace_set_multicast(struct net_device *dev) spin_unlock_irqrestore(&mp->lock, flags); } -static void mace_handle_misc_intrs(struct mace_data *mp, int intr) +static void mace_handle_misc_intrs(struct mace_data *mp, int intr, struct net_device *dev) { volatile struct mace __iomem *mb = mp->mace; static int mace_babbles, mace_jabbers; if (intr & MPCO) - mp->stats.rx_missed_errors += 256; - mp->stats.rx_missed_errors += in_8(&mb->mpc); /* reading clears it */ + dev->stats.rx_missed_errors += 256; + dev->stats.rx_missed_errors += in_8(&mb->mpc); /* reading clears it */ if (intr & RNTPCO) - mp->stats.rx_length_errors += 256; - mp->stats.rx_length_errors += in_8(&mb->rntpc); /* reading clears it */ + dev->stats.rx_length_errors += 256; + dev->stats.rx_length_errors += in_8(&mb->rntpc); /* reading clears it */ if (intr & CERR) - ++mp->stats.tx_heartbeat_errors; + ++dev->stats.tx_heartbeat_errors; if (intr & BABBLE) if (mace_babbles++ < 4) printk(KERN_DEBUG "mace: babbling transmitter\n"); @@ -680,7 +669,7 @@ static irqreturn_t mace_interrupt(int irq, void *dev_id) spin_lock_irqsave(&mp->lock, flags); intr = in_8(&mb->ir); /* read interrupt register */ in_8(&mb->xmtrc); /* get retries */ - mace_handle_misc_intrs(mp, intr); + mace_handle_misc_intrs(mp, intr, dev); i = mp->tx_empty; while (in_8(&mb->pr) & XMTSV) { @@ -693,7 +682,7 @@ static irqreturn_t mace_interrupt(int irq, void *dev_id) */ intr = in_8(&mb->ir); if (intr != 0) - mace_handle_misc_intrs(mp, intr); + mace_handle_misc_intrs(mp, intr, dev); if (mp->tx_bad_runt) { fs = in_8(&mb->xmtfs); mp->tx_bad_runt = 0; @@ -767,14 +756,14 @@ static irqreturn_t mace_interrupt(int irq, void *dev_id) } /* Update stats */ if (fs & (UFLO|LCOL|LCAR|RTRY)) { - ++mp->stats.tx_errors; + ++dev->stats.tx_errors; if (fs & LCAR) - ++mp->stats.tx_carrier_errors; + ++dev->stats.tx_carrier_errors; if (fs & (UFLO|LCOL|RTRY)) - ++mp->stats.tx_aborted_errors; + ++dev->stats.tx_aborted_errors; } else { - mp->stats.tx_bytes += mp->tx_bufs[i]->len; - ++mp->stats.tx_packets; + dev->stats.tx_bytes += mp->tx_bufs[i]->len; + ++dev->stats.tx_packets; } dev_kfree_skb_irq(mp->tx_bufs[i]); --mp->tx_active; @@ -828,7 +817,7 @@ static void mace_tx_timeout(unsigned long data) goto out; /* update various counters */ - mace_handle_misc_intrs(mp, in_8(&mb->ir)); + mace_handle_misc_intrs(mp, in_8(&mb->ir), dev); cp = mp->tx_cmds + NCMDS_TX * mp->tx_empty; @@ -848,7 +837,7 @@ static void mace_tx_timeout(unsigned long data) /* fix up the transmit side */ i = mp->tx_empty; mp->tx_active = 0; - ++mp->stats.tx_errors; + ++dev->stats.tx_errors; if (mp->tx_bad_runt) { mp->tx_bad_runt = 0; } else if (i != mp->tx_fill) { @@ -916,18 +905,18 @@ static irqreturn_t mace_rxdma_intr(int irq, void *dev_id) /* got a packet, have a look at it */ skb = mp->rx_bufs[i]; if (skb == 0) { - ++mp->stats.rx_dropped; + ++dev->stats.rx_dropped; } else if (nb > 8) { data = skb->data; frame_status = (data[nb-3] << 8) + data[nb-4]; if (frame_status & (RS_OFLO|RS_CLSN|RS_FRAMERR|RS_FCSERR)) { - ++mp->stats.rx_errors; + ++dev->stats.rx_errors; if (frame_status & RS_OFLO) - ++mp->stats.rx_over_errors; + ++dev->stats.rx_over_errors; if (frame_status & RS_FRAMERR) - ++mp->stats.rx_frame_errors; + ++dev->stats.rx_frame_errors; if (frame_status & RS_FCSERR) - ++mp->stats.rx_crc_errors; + ++dev->stats.rx_crc_errors; } else { /* Mace feature AUTO_STRIP_RCV is on by default, dropping the * FCS on frames with 802.3 headers. This means that Ethernet @@ -939,15 +928,15 @@ static irqreturn_t mace_rxdma_intr(int irq, void *dev_id) nb -= 8; skb_put(skb, nb); skb->protocol = eth_type_trans(skb, dev); - mp->stats.rx_bytes += skb->len; + dev->stats.rx_bytes += skb->len; netif_rx(skb); dev->last_rx = jiffies; mp->rx_bufs[i] = NULL; - ++mp->stats.rx_packets; + ++dev->stats.rx_packets; } } else { - ++mp->stats.rx_errors; - ++mp->stats.rx_length_errors; + ++dev->stats.rx_errors; + ++dev->stats.rx_length_errors; } /* advance to next */ diff --git a/drivers/net/macmace.c b/drivers/net/macmace.c index 5d2daa248873..57f7c1a2c1d7 100644 --- a/drivers/net/macmace.c +++ b/drivers/net/macmace.c @@ -65,7 +65,6 @@ struct mace_data { unsigned char *rx_ring; dma_addr_t rx_ring_phys; int dma_intr; - struct net_device_stats stats; int rx_slot, rx_tail; int tx_slot, tx_sloti, tx_count; int chipid; @@ -92,7 +91,6 @@ struct mace_frame { static int mace_open(struct net_device *dev); static int mace_close(struct net_device *dev); static int mace_xmit_start(struct sk_buff *skb, struct net_device *dev); -static struct net_device_stats *mace_stats(struct net_device *dev); static void mace_set_multicast(struct net_device *dev); static int mace_set_address(struct net_device *dev, void *addr); static void mace_reset(struct net_device *dev); @@ -242,14 +240,11 @@ static int __devinit mace_probe(struct platform_device *pdev) return -ENODEV; } - memset(&mp->stats, 0, sizeof(mp->stats)); - dev->open = mace_open; dev->stop = mace_close; dev->hard_start_xmit = mace_xmit_start; dev->tx_timeout = mace_tx_timeout; dev->watchdog_timeo = TX_TIMEOUT; - dev->get_stats = mace_stats; dev->set_multicast_list = mace_set_multicast; dev->set_mac_address = mace_set_address; @@ -472,8 +467,8 @@ static int mace_xmit_start(struct sk_buff *skb, struct net_device *dev) mp->tx_count--; local_irq_restore(flags); - mp->stats.tx_packets++; - mp->stats.tx_bytes += skb->len; + dev->stats.tx_packets++; + dev->stats.tx_bytes += skb->len; /* We need to copy into our xmit buffer to take care of alignment and caching issues */ skb_copy_from_linear_data(skb, mp->tx_ring, skb->len); @@ -492,12 +487,6 @@ static int mace_xmit_start(struct sk_buff *skb, struct net_device *dev) return NETDEV_TX_OK; } -static struct net_device_stats *mace_stats(struct net_device *dev) -{ - struct mace_data *mp = netdev_priv(dev); - return &mp->stats; -} - static void mace_set_multicast(struct net_device *dev) { struct mace_data *mp = netdev_priv(dev); @@ -555,13 +544,13 @@ static void mace_handle_misc_intrs(struct mace_data *mp, int intr) static int mace_babbles, mace_jabbers; if (intr & MPCO) - mp->stats.rx_missed_errors += 256; - mp->stats.rx_missed_errors += mb->mpc; /* reading clears it */ + dev->stats.rx_missed_errors += 256; + dev->stats.rx_missed_errors += mb->mpc; /* reading clears it */ if (intr & RNTPCO) - mp->stats.rx_length_errors += 256; - mp->stats.rx_length_errors += mb->rntpc; /* reading clears it */ + dev->stats.rx_length_errors += 256; + dev->stats.rx_length_errors += mb->rntpc; /* reading clears it */ if (intr & CERR) - ++mp->stats.tx_heartbeat_errors; + ++dev->stats.tx_heartbeat_errors; if (intr & BABBLE) if (mace_babbles++ < 4) printk(KERN_DEBUG "macmace: babbling transmitter\n"); @@ -600,14 +589,14 @@ static irqreturn_t mace_interrupt(int irq, void *dev_id) } /* Update stats */ if (fs & (UFLO|LCOL|LCAR|RTRY)) { - ++mp->stats.tx_errors; + ++dev->stats.tx_errors; if (fs & LCAR) - ++mp->stats.tx_carrier_errors; + ++dev->stats.tx_carrier_errors; else if (fs & (UFLO|LCOL|RTRY)) { - ++mp->stats.tx_aborted_errors; + ++dev->stats.tx_aborted_errors; if (mb->xmtfs & UFLO) { printk(KERN_ERR "%s: DMA underrun.\n", dev->name); - mp->stats.tx_fifo_errors++; + dev->stats.tx_fifo_errors++; mace_txdma_reset(dev); } } @@ -661,23 +650,23 @@ static void mace_dma_rx_frame(struct net_device *dev, struct mace_frame *mf) unsigned int frame_status = mf->rcvsts; if (frame_status & (RS_OFLO | RS_CLSN | RS_FRAMERR | RS_FCSERR)) { - mp->stats.rx_errors++; + dev->stats.rx_errors++; if (frame_status & RS_OFLO) { printk(KERN_DEBUG "%s: fifo overflow.\n", dev->name); - mp->stats.rx_fifo_errors++; + dev->stats.rx_fifo_errors++; } if (frame_status & RS_CLSN) - mp->stats.collisions++; + dev->stats.collisions++; if (frame_status & RS_FRAMERR) - mp->stats.rx_frame_errors++; + dev->stats.rx_frame_errors++; if (frame_status & RS_FCSERR) - mp->stats.rx_crc_errors++; + dev->stats.rx_crc_errors++; } else { unsigned int frame_length = mf->rcvcnt + ((frame_status & 0x0F) << 8 ); skb = dev_alloc_skb(frame_length + 2); if (!skb) { - mp->stats.rx_dropped++; + dev->stats.rx_dropped++; return; } skb_reserve(skb, 2); @@ -686,8 +675,8 @@ static void mace_dma_rx_frame(struct net_device *dev, struct mace_frame *mf) skb->protocol = eth_type_trans(skb, dev); netif_rx(skb); dev->last_rx = jiffies; - mp->stats.rx_packets++; - mp->stats.rx_bytes += frame_length; + dev->stats.rx_packets++; + dev->stats.rx_bytes += frame_length; } } diff --git a/drivers/net/meth.c b/drivers/net/meth.c index 32bed6bc6c06..fe5b6c372072 100644 --- a/drivers/net/meth.c +++ b/drivers/net/meth.c @@ -66,7 +66,6 @@ module_param(timeout, int, 0); * packets in and out, so there is place for a packet */ struct meth_private { - struct net_device_stats stats; /* in-memory copy of MAC Control register */ unsigned long mac_ctrl; /* in-memory copy of DMA Control register */ @@ -401,15 +400,15 @@ static void meth_rx(struct net_device* dev, unsigned long int_status) printk(KERN_DEBUG "%s: bogus packet size: %ld, status=%#2lx.\n", dev->name, priv->rx_write, priv->rx_ring[priv->rx_write]->status.raw); - priv->stats.rx_errors++; - priv->stats.rx_length_errors++; + dev->stats.rx_errors++; + dev->stats.rx_length_errors++; skb = priv->rx_skbs[priv->rx_write]; } else { skb = alloc_skb(METH_RX_BUFF_SIZE, GFP_ATOMIC); if (!skb) { /* Ouch! No memory! Drop packet on the floor */ DPRINTK("No mem: dropping packet\n"); - priv->stats.rx_dropped++; + dev->stats.rx_dropped++; skb = priv->rx_skbs[priv->rx_write]; } else { struct sk_buff *skb_c = priv->rx_skbs[priv->rx_write]; @@ -421,13 +420,13 @@ static void meth_rx(struct net_device* dev, unsigned long int_status) priv->rx_skbs[priv->rx_write] = skb; skb_c->protocol = eth_type_trans(skb_c, dev); dev->last_rx = jiffies; - priv->stats.rx_packets++; - priv->stats.rx_bytes += len; + dev->stats.rx_packets++; + dev->stats.rx_bytes += len; netif_rx(skb_c); } } } else { - priv->stats.rx_errors++; + dev->stats.rx_errors++; skb=priv->rx_skbs[priv->rx_write]; #if MFE_DEBUG>0 printk(KERN_WARNING "meth: RX error: status=0x%016lx\n",status); @@ -490,10 +489,10 @@ static void meth_tx_cleanup(struct net_device* dev, unsigned long int_status) #endif if (status & METH_TX_ST_DONE) { if (status & METH_TX_ST_SUCCESS){ - priv->stats.tx_packets++; - priv->stats.tx_bytes += skb->len; + dev->stats.tx_packets++; + dev->stats.tx_bytes += skb->len; } else { - priv->stats.tx_errors++; + dev->stats.tx_errors++; #if MFE_DEBUG>=1 DPRINTK("TX error: status=%016lx <",status); if(status & METH_TX_ST_SUCCESS) @@ -734,7 +733,7 @@ static void meth_tx_timeout(struct net_device *dev) /* Try to reset the interface. */ meth_reset(dev); - priv->stats.tx_errors++; + dev->stats.tx_errors++; /* Clear all rings */ meth_free_tx_ring(priv); @@ -773,12 +772,6 @@ static int meth_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) /* * Return statistics to the caller */ -static struct net_device_stats *meth_stats(struct net_device *dev) -{ - struct meth_private *priv = netdev_priv(dev); - return &priv->stats; -} - /* * The init function. */ @@ -796,7 +789,6 @@ static int __init meth_probe(struct platform_device *pdev) dev->stop = meth_release; dev->hard_start_xmit = meth_tx; dev->do_ioctl = meth_ioctl; - dev->get_stats = meth_stats; #ifdef HAVE_TX_TIMEOUT dev->tx_timeout = meth_tx_timeout; dev->watchdog_timeo = timeout; diff --git a/drivers/net/mipsnet.c b/drivers/net/mipsnet.c index c0f5ad38fb17..d593175ab6f0 100644 --- a/drivers/net/mipsnet.c +++ b/drivers/net/mipsnet.c @@ -21,10 +21,6 @@ #define mipsnet_reg_address(dev, field) (dev->base_addr + field_offset(field)) -struct mipsnet_priv { - struct net_device_stats stats; -}; - static char mipsnet_string[] = "mipsnet"; /* @@ -49,7 +45,6 @@ static inline ssize_t mipsnet_put_todevice(struct net_device *dev, { int count_to_go = skb->len; char *buf_ptr = skb->data; - struct mipsnet_priv *mp = netdev_priv(dev); pr_debug("%s: %s(): telling MIPSNET txDataCount(%d)\n", dev->name, __FUNCTION__, skb->len); @@ -63,8 +58,8 @@ static inline ssize_t mipsnet_put_todevice(struct net_device *dev, outb(*buf_ptr, mipsnet_reg_address(dev, txDataBuffer)); } - mp->stats.tx_packets++; - mp->stats.tx_bytes += skb->len; + dev->stats.tx_packets++; + dev->stats.tx_bytes += skb->len; return skb->len; } @@ -87,10 +82,9 @@ static inline ssize_t mipsnet_get_fromdev(struct net_device *dev, size_t count) { struct sk_buff *skb; size_t len = count; - struct mipsnet_priv *mp = netdev_priv(dev); if (!(skb = alloc_skb(len + 2, GFP_KERNEL))) { - mp->stats.rx_dropped++; + dev->stats.rx_dropped++; return -ENOMEM; } @@ -105,8 +99,8 @@ static inline ssize_t mipsnet_get_fromdev(struct net_device *dev, size_t count) dev->name, __FUNCTION__); netif_rx(skb); - mp->stats.rx_packets++; - mp->stats.rx_bytes += len; + dev->stats.rx_packets++; + dev->stats.rx_bytes += len; return count; } @@ -203,13 +197,6 @@ static int mipsnet_close(struct net_device *dev) return 0; } -static struct net_device_stats *mipsnet_get_stats(struct net_device *dev) -{ - struct mipsnet_priv *mp = netdev_priv(dev); - - return &mp->stats; -} - static void mipsnet_set_mclist(struct net_device *dev) { // we don't do anything @@ -221,7 +208,7 @@ static int __init mipsnet_probe(struct device *dev) struct net_device *netdev; int err; - netdev = alloc_etherdev(sizeof(struct mipsnet_priv)); + netdev = alloc_etherdev(0); if (!netdev) { err = -ENOMEM; goto out; @@ -232,7 +219,6 @@ static int __init mipsnet_probe(struct device *dev) netdev->open = mipsnet_open; netdev->stop = mipsnet_close; netdev->hard_start_xmit = mipsnet_xmit; - netdev->get_stats = mipsnet_get_stats; netdev->set_multicast_list = mipsnet_set_mclist; /* diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c index 2a808e265a3e..35781616eb23 100644 --- a/drivers/net/mv643xx_eth.c +++ b/drivers/net/mv643xx_eth.c @@ -63,7 +63,6 @@ static unsigned int mv643xx_eth_port_disable_rx(unsigned int port_num); static int mv643xx_eth_open(struct net_device *); static int mv643xx_eth_stop(struct net_device *); static int mv643xx_eth_change_mtu(struct net_device *, int); -static struct net_device_stats *mv643xx_eth_get_stats(struct net_device *); static void eth_port_init_mac_tables(unsigned int eth_port_num); #ifdef MV643XX_NAPI static int mv643xx_poll(struct napi_struct *napi, int budget); @@ -341,7 +340,7 @@ int mv643xx_eth_free_tx_descs(struct net_device *dev, int force) if (cmd_sts & ETH_ERROR_SUMMARY) { printk("%s: Error in TX\n", dev->name); - mp->stats.tx_errors++; + dev->stats.tx_errors++; } spin_unlock_irqrestore(&mp->lock, flags); @@ -388,7 +387,7 @@ static void mv643xx_eth_free_all_tx_descs(struct net_device *dev) static int mv643xx_eth_receive_queue(struct net_device *dev, int budget) { struct mv643xx_private *mp = netdev_priv(dev); - struct net_device_stats *stats = &mp->stats; + struct net_device_stats *stats = &dev->stats; unsigned int received_packets = 0; struct sk_buff *skb; struct pkt_info pkt_info; @@ -1192,7 +1191,7 @@ static void eth_tx_submit_descs_for_skb(struct mv643xx_private *mp, static int mv643xx_eth_start_xmit(struct sk_buff *skb, struct net_device *dev) { struct mv643xx_private *mp = netdev_priv(dev); - struct net_device_stats *stats = &mp->stats; + struct net_device_stats *stats = &dev->stats; unsigned long flags; BUG_ON(netif_queue_stopped(dev)); @@ -1228,23 +1227,6 @@ static int mv643xx_eth_start_xmit(struct sk_buff *skb, struct net_device *dev) return 0; /* success */ } -/* - * mv643xx_eth_get_stats - * - * Returns a pointer to the interface statistics. - * - * Input : dev - a pointer to the required interface - * - * Output : a pointer to the interface's statistics - */ - -static struct net_device_stats *mv643xx_eth_get_stats(struct net_device *dev) -{ - struct mv643xx_private *mp = netdev_priv(dev); - - return &mp->stats; -} - #ifdef CONFIG_NET_POLL_CONTROLLER static void mv643xx_netpoll(struct net_device *netdev) { @@ -1339,7 +1321,6 @@ static int mv643xx_eth_probe(struct platform_device *pdev) dev->open = mv643xx_eth_open; dev->stop = mv643xx_eth_stop; dev->hard_start_xmit = mv643xx_eth_start_xmit; - dev->get_stats = mv643xx_eth_get_stats; dev->set_mac_address = mv643xx_eth_set_mac_address; dev->set_multicast_list = mv643xx_eth_set_rx_mode; diff --git a/drivers/net/myri_sbus.c b/drivers/net/myri_sbus.c index 331b76c49561..35c4c598c8d2 100644 --- a/drivers/net/myri_sbus.c +++ b/drivers/net/myri_sbus.c @@ -353,7 +353,7 @@ static void myri_tx(struct myri_eth *mp, struct net_device *dev) sbus_unmap_single(mp->myri_sdev, dma_addr, skb->len, SBUS_DMA_TODEVICE); dev_kfree_skb(skb); mp->tx_skbs[entry] = NULL; - mp->enet_stats.tx_packets++; + dev->stats.tx_packets++; entry = NEXT_TX(entry); } mp->tx_old = entry; @@ -434,20 +434,20 @@ static void myri_rx(struct myri_eth *mp, struct net_device *dev) RX_ALLOC_SIZE, SBUS_DMA_FROMDEVICE); if (len < (ETH_HLEN + MYRI_PAD_LEN) || (skb->data[0] != MYRI_PAD_LEN)) { DRX(("ERROR[")); - mp->enet_stats.rx_errors++; + dev->stats.rx_errors++; if (len < (ETH_HLEN + MYRI_PAD_LEN)) { DRX(("BAD_LENGTH] ")); - mp->enet_stats.rx_length_errors++; + dev->stats.rx_length_errors++; } else { DRX(("NO_PADDING] ")); - mp->enet_stats.rx_frame_errors++; + dev->stats.rx_frame_errors++; } /* Return it to the LANAI. */ drop_it: drops++; DRX(("DROP ")); - mp->enet_stats.rx_dropped++; + dev->stats.rx_dropped++; sbus_dma_sync_single_for_device(mp->myri_sdev, sbus_readl(&rxd->myri_scatters[0].addr), RX_ALLOC_SIZE, @@ -527,8 +527,8 @@ static void myri_rx(struct myri_eth *mp, struct net_device *dev) netif_rx(skb); dev->last_rx = jiffies; - mp->enet_stats.rx_packets++; - mp->enet_stats.rx_bytes += len; + dev->stats.rx_packets++; + dev->stats.rx_bytes += len; next: DRX(("NEXT\n")); entry = NEXT_RX(entry); @@ -596,7 +596,7 @@ static void myri_tx_timeout(struct net_device *dev) printk(KERN_ERR "%s: transmit timed out, resetting\n", dev->name); - mp->enet_stats.tx_errors++; + dev->stats.tx_errors++; myri_init(mp, 0); netif_wake_queue(dev); } @@ -806,9 +806,6 @@ static int myri_change_mtu(struct net_device *dev, int new_mtu) return 0; } -static struct net_device_stats *myri_get_stats(struct net_device *dev) -{ return &(((struct myri_eth *)dev->priv)->enet_stats); } - static void myri_set_multicast(struct net_device *dev) { /* Do nothing, all MyriCOM nodes transmit multicast frames @@ -1060,7 +1057,6 @@ static int __devinit myri_ether_init(struct sbus_dev *sdev) dev->hard_start_xmit = &myri_start_xmit; dev->tx_timeout = &myri_tx_timeout; dev->watchdog_timeo = 5*HZ; - dev->get_stats = &myri_get_stats; dev->set_multicast_list = &myri_set_multicast; dev->irq = sdev->irqs[0]; diff --git a/drivers/net/myri_sbus.h b/drivers/net/myri_sbus.h index 2f69ef7cdccb..5d93fcc95d55 100644 --- a/drivers/net/myri_sbus.h +++ b/drivers/net/myri_sbus.h @@ -280,7 +280,6 @@ struct myri_eth { void __iomem *lregs; /* Quick ptr to LANAI regs. */ struct sk_buff *rx_skbs[RX_RING_SIZE+1];/* RX skb's */ struct sk_buff *tx_skbs[TX_RING_SIZE]; /* TX skb's */ - struct net_device_stats enet_stats; /* Interface stats. */ /* These are less frequently accessed. */ void __iomem *regs; /* MyriCOM register space. */ diff --git a/drivers/net/netx-eth.c b/drivers/net/netx-eth.c index 6fee405d8403..eb0aff787dfd 100644 --- a/drivers/net/netx-eth.c +++ b/drivers/net/netx-eth.c @@ -97,7 +97,6 @@ struct netx_eth_priv { void __iomem *sram_base, *xpec_base, *xmac_base; int id; - struct net_device_stats stats; struct mii_if_info mii; u32 msg_enable; struct xc *xc; @@ -129,8 +128,8 @@ netx_eth_hard_start_xmit(struct sk_buff *skb, struct net_device *ndev) FIFO_PTR_FRAMELEN(len)); ndev->trans_start = jiffies; - priv->stats.tx_packets++; - priv->stats.tx_bytes += skb->len; + dev->stats.tx_packets++; + dev->stats.tx_bytes += skb->len; netif_stop_queue(ndev); spin_unlock_irq(&priv->lock); @@ -156,7 +155,7 @@ static void netx_eth_receive(struct net_device *ndev) if (unlikely(skb == NULL)) { printk(KERN_NOTICE "%s: Low memory, packet dropped.\n", ndev->name); - priv->stats.rx_dropped++; + dev->stats.rx_dropped++; return; } @@ -170,8 +169,8 @@ static void netx_eth_receive(struct net_device *ndev) ndev->last_rx = jiffies; skb->protocol = eth_type_trans(skb, ndev); netif_rx(skb); - priv->stats.rx_packets++; - priv->stats.rx_bytes += len; + dev->stats.rx_packets++; + dev->stats.rx_bytes += len; } static irqreturn_t @@ -210,12 +209,6 @@ netx_eth_interrupt(int irq, void *dev_id) return IRQ_HANDLED; } -static struct net_device_stats *netx_eth_query_statistics(struct net_device *ndev) -{ - struct netx_eth_priv *priv = netdev_priv(ndev); - return &priv->stats; -} - static int netx_eth_open(struct net_device *ndev) { struct netx_eth_priv *priv = netdev_priv(ndev); @@ -323,7 +316,6 @@ static int netx_eth_enable(struct net_device *ndev) ndev->hard_start_xmit = netx_eth_hard_start_xmit; ndev->tx_timeout = netx_eth_timeout; ndev->watchdog_timeo = msecs_to_jiffies(5000); - ndev->get_stats = netx_eth_query_statistics; ndev->set_multicast_list = netx_eth_set_multicast_list; priv->msg_enable = NETIF_MSG_LINK; diff --git a/drivers/net/ni5010.c b/drivers/net/ni5010.c index cc1d09a21c0c..1dc74a78afa6 100644 --- a/drivers/net/ni5010.c +++ b/drivers/net/ni5010.c @@ -89,7 +89,6 @@ static unsigned int ports[] __initdata = /* Information that needs to be kept for each board. */ struct ni5010_local { - struct net_device_stats stats; int o_pkt_size; spinlock_t lock; }; @@ -103,7 +102,6 @@ static irqreturn_t ni5010_interrupt(int irq, void *dev_id); static void ni5010_rx(struct net_device *dev); static void ni5010_timeout(struct net_device *dev); static int ni5010_close(struct net_device *dev); -static struct net_device_stats *ni5010_get_stats(struct net_device *dev); static void ni5010_set_multicast_list(struct net_device *dev); static void reset_receiver(struct net_device *dev); @@ -334,7 +332,6 @@ static int __init ni5010_probe1(struct net_device *dev, int ioaddr) dev->open = ni5010_open; dev->stop = ni5010_close; dev->hard_start_xmit = ni5010_send_packet; - dev->get_stats = ni5010_get_stats; dev->set_multicast_list = ni5010_set_multicast_list; dev->tx_timeout = ni5010_timeout; dev->watchdog_timeo = HZ/20; @@ -532,11 +529,11 @@ static void ni5010_rx(struct net_device *dev) if ( (rcv_stat & RS_VALID_BITS) != RS_PKT_OK) { PRINTK((KERN_INFO "%s: receive error.\n", dev->name)); - lp->stats.rx_errors++; - if (rcv_stat & RS_RUNT) lp->stats.rx_length_errors++; - if (rcv_stat & RS_ALIGN) lp->stats.rx_frame_errors++; - if (rcv_stat & RS_CRC_ERR) lp->stats.rx_crc_errors++; - if (rcv_stat & RS_OFLW) lp->stats.rx_fifo_errors++; + dev->stats.rx_errors++; + if (rcv_stat & RS_RUNT) dev->stats.rx_length_errors++; + if (rcv_stat & RS_ALIGN) dev->stats.rx_frame_errors++; + if (rcv_stat & RS_CRC_ERR) dev->stats.rx_crc_errors++; + if (rcv_stat & RS_OFLW) dev->stats.rx_fifo_errors++; outb(0xff, EDLC_RCLR); /* Clear the interrupt */ return; } @@ -547,8 +544,8 @@ static void ni5010_rx(struct net_device *dev) if (i_pkt_size > ETH_FRAME_LEN || i_pkt_size < 10 ) { PRINTK((KERN_DEBUG "%s: Packet size error, packet size = %#4.4x\n", dev->name, i_pkt_size)); - lp->stats.rx_errors++; - lp->stats.rx_length_errors++; + dev->stats.rx_errors++; + dev->stats.rx_length_errors++; return; } @@ -556,7 +553,7 @@ static void ni5010_rx(struct net_device *dev) skb = dev_alloc_skb(i_pkt_size + 3); if (skb == NULL) { printk(KERN_WARNING "%s: Memory squeeze, dropping packet.\n", dev->name); - lp->stats.rx_dropped++; + dev->stats.rx_dropped++; return; } @@ -573,8 +570,8 @@ static void ni5010_rx(struct net_device *dev) skb->protocol = eth_type_trans(skb,dev); netif_rx(skb); dev->last_rx = jiffies; - lp->stats.rx_packets++; - lp->stats.rx_bytes += i_pkt_size; + dev->stats.rx_packets++; + dev->stats.rx_bytes += i_pkt_size; PRINTK2((KERN_DEBUG "%s: Received packet, size=%#4.4x\n", dev->name, i_pkt_size)); @@ -602,14 +599,14 @@ static int process_xmt_interrupt(struct net_device *dev) /* outb(0, IE_MMODE); */ /* xmt buf on sysbus FIXME: needed ? */ outb(MM_EN_XMT | MM_MUX, IE_MMODE); outb(XM_ALL, EDLC_XMASK); /* Enable xmt IRQ's */ - lp->stats.collisions++; + dev->stats.collisions++; return 1; } /* FIXME: handle other xmt error conditions */ - lp->stats.tx_packets++; - lp->stats.tx_bytes += lp->o_pkt_size; + dev->stats.tx_packets++; + dev->stats.tx_bytes += lp->o_pkt_size; netif_wake_queue(dev); PRINTK2((KERN_DEBUG "%s: sent packet, size=%#4.4x\n", @@ -638,24 +635,6 @@ static int ni5010_close(struct net_device *dev) } -/* Get the current statistics. This may be called with the card open or - closed. */ -static struct net_device_stats *ni5010_get_stats(struct net_device *dev) -{ - struct ni5010_local *lp = netdev_priv(dev); - - PRINTK2((KERN_DEBUG "%s: entering ni5010_get_stats\n", dev->name)); - - if (NI5010_DEBUG) ni5010_show_registers(dev); - - /* cli(); */ - /* Update the statistics from the device registers. */ - /* We do this in the interrupt handler */ - /* sti(); */ - - return &lp->stats; -} - /* Set or clear the multicast filter for this adaptor. num_addrs == -1 Promiscuous mode, receive all packets num_addrs == 0 Normal mode, clear multicast list diff --git a/drivers/net/pasemi_mac.c b/drivers/net/pasemi_mac.c index 723685ee57aa..f310d94443a0 100644 --- a/drivers/net/pasemi_mac.c +++ b/drivers/net/pasemi_mac.c @@ -530,8 +530,8 @@ static int pasemi_mac_clean_rx(struct pasemi_mac *mac, int limit) } else skb->ip_summed = CHECKSUM_NONE; - mac->stats.rx_bytes += len; - mac->stats.rx_packets++; + mac->netdev->stats.rx_bytes += len; + mac->netdev->stats.rx_packets++; skb->protocol = eth_type_trans(skb, mac->netdev); netif_receive_skb(skb); @@ -1032,8 +1032,8 @@ static int pasemi_mac_start_tx(struct sk_buff *skb, struct net_device *dev) info->skb = skb; txring->next_to_fill++; - mac->stats.tx_packets++; - mac->stats.tx_bytes += skb->len; + dev->stats.tx_packets++; + dev->stats.tx_bytes += skb->len; spin_unlock_irqrestore(&txring->lock, flags); @@ -1047,14 +1047,6 @@ out_err: return NETDEV_TX_BUSY; } -static struct net_device_stats *pasemi_mac_get_stats(struct net_device *dev) -{ - struct pasemi_mac *mac = netdev_priv(dev); - - return &mac->stats; -} - - static void pasemi_mac_set_rx_mode(struct net_device *dev) { struct pasemi_mac *mac = netdev_priv(dev); @@ -1223,7 +1215,6 @@ pasemi_mac_probe(struct pci_dev *pdev, const struct pci_device_id *ent) dev->open = pasemi_mac_open; dev->stop = pasemi_mac_close; dev->hard_start_xmit = pasemi_mac_start_tx; - dev->get_stats = pasemi_mac_get_stats; dev->set_multicast_list = pasemi_mac_set_rx_mode; err = pasemi_mac_map_regs(mac); diff --git a/drivers/net/pasemi_mac.h b/drivers/net/pasemi_mac.h index c5b0adbc182e..c52cfcb6c4ca 100644 --- a/drivers/net/pasemi_mac.h +++ b/drivers/net/pasemi_mac.h @@ -60,7 +60,6 @@ struct pasemi_mac { struct pci_dev *iob_pdev; struct phy_device *phydev; struct napi_struct napi; - struct net_device_stats stats; /* Pointer to the cacheable per-channel status registers */ u64 *rx_status; diff --git a/drivers/net/pci-skeleton.c b/drivers/net/pci-skeleton.c index a4b16484a5f7..7dace63fb6e6 100644 --- a/drivers/net/pci-skeleton.c +++ b/drivers/net/pci-skeleton.c @@ -457,7 +457,6 @@ struct netdrv_private { void *mmio_addr; int drv_flags; struct pci_dev *pci_dev; - struct net_device_stats stats; struct timer_list timer; /* Media selection timer. */ unsigned char *rx_ring; unsigned int cur_rx; /* Index into the Rx buffer of next Rx pkt. */ @@ -505,7 +504,6 @@ static int netdrv_start_xmit (struct sk_buff *skb, static irqreturn_t netdrv_interrupt (int irq, void *dev_instance); static int netdrv_close (struct net_device *dev); static int netdrv_ioctl (struct net_device *dev, struct ifreq *rq, int cmd); -static struct net_device_stats *netdrv_get_stats (struct net_device *dev); static void netdrv_set_rx_mode (struct net_device *dev); static void netdrv_hw_start (struct net_device *dev); @@ -775,7 +773,6 @@ static int __devinit netdrv_init_one (struct pci_dev *pdev, dev->open = netdrv_open; dev->hard_start_xmit = netdrv_start_xmit; dev->stop = netdrv_close; - dev->get_stats = netdrv_get_stats; dev->set_multicast_list = netdrv_set_rx_mode; dev->do_ioctl = netdrv_ioctl; dev->tx_timeout = netdrv_tx_timeout; @@ -1276,7 +1273,7 @@ static void netdrv_tx_clear (struct netdrv_private *tp) if (rp->skb) { dev_kfree_skb (rp->skb); rp->skb = NULL; - tp->stats.tx_dropped++; + dev->stats.tx_dropped++; } } } @@ -1389,25 +1386,25 @@ static void netdrv_tx_interrupt (struct net_device *dev, /* There was an major error, log it. */ DPRINTK ("%s: Transmit error, Tx status %8.8x.\n", dev->name, txstatus); - tp->stats.tx_errors++; + dev->stats.tx_errors++; if (txstatus & TxAborted) { - tp->stats.tx_aborted_errors++; + dev->stats.tx_aborted_errors++; NETDRV_W32 (TxConfig, TxClearAbt | (TX_DMA_BURST << TxDMAShift)); } if (txstatus & TxCarrierLost) - tp->stats.tx_carrier_errors++; + dev->stats.tx_carrier_errors++; if (txstatus & TxOutOfWindow) - tp->stats.tx_window_errors++; + dev->stats.tx_window_errors++; } else { if (txstatus & TxUnderrun) { /* Add 64 to the Tx FIFO threshold. */ if (tp->tx_flag < 0x00300000) tp->tx_flag += 0x00020000; - tp->stats.tx_fifo_errors++; + dev->stats.tx_fifo_errors++; } - tp->stats.collisions += (txstatus >> 24) & 15; - tp->stats.tx_bytes += txstatus & 0x7ff; - tp->stats.tx_packets++; + dev->stats.collisions += (txstatus >> 24) & 15; + dev->stats.tx_bytes += txstatus & 0x7ff; + dev->stats.tx_packets++; } /* Free the original skb. */ @@ -1460,13 +1457,13 @@ static void netdrv_rx_err (u32 rx_status, struct net_device *dev, dev->name, rx_status); /* A.C.: The chip hangs here. */ } - tp->stats.rx_errors++; + dev->stats.rx_errors++; if (rx_status & (RxBadSymbol | RxBadAlign)) - tp->stats.rx_frame_errors++; + dev->stats.rx_frame_errors++; if (rx_status & (RxRunt | RxTooLong)) - tp->stats.rx_length_errors++; + dev->stats.rx_length_errors++; if (rx_status & RxCRCErr) - tp->stats.rx_crc_errors++; + dev->stats.rx_crc_errors++; /* Reset the receiver, based on RealTek recommendation. (Bug?) */ tp->cur_rx = 0; @@ -1572,13 +1569,13 @@ static void netdrv_rx_interrupt (struct net_device *dev, skb->protocol = eth_type_trans (skb, dev); netif_rx (skb); dev->last_rx = jiffies; - tp->stats.rx_bytes += pkt_size; - tp->stats.rx_packets++; + dev->stats.rx_bytes += pkt_size; + dev->stats.rx_packets++; } else { printk (KERN_WARNING "%s: Memory squeeze, dropping packet.\n", dev->name); - tp->stats.rx_dropped++; + dev->stats.rx_dropped++; } cur_rx = (cur_rx + rx_size + 4 + 3) & ~3; @@ -1607,7 +1604,7 @@ static void netdrv_weird_interrupt (struct net_device *dev, assert (ioaddr != NULL); /* Update the error count. */ - tp->stats.rx_missed_errors += NETDRV_R32 (RxMissed); + dev->stats.rx_missed_errors += NETDRV_R32 (RxMissed); NETDRV_W32 (RxMissed, 0); if ((status & RxUnderrun) && link_changed && @@ -1628,14 +1625,14 @@ static void netdrv_weird_interrupt (struct net_device *dev, /* XXX along with netdrv_rx_err, are we double-counting errors? */ if (status & (RxUnderrun | RxOverflow | RxErr | RxFIFOOver)) - tp->stats.rx_errors++; + dev->stats.rx_errors++; if (status & (PCSTimeout)) - tp->stats.rx_length_errors++; + dev->stats.rx_length_errors++; if (status & (RxUnderrun | RxFIFOOver)) - tp->stats.rx_fifo_errors++; + dev->stats.rx_fifo_errors++; if (status & RxOverflow) { - tp->stats.rx_over_errors++; + dev->stats.rx_over_errors++; tp->cur_rx = NETDRV_R16 (RxBufAddr) % RX_BUF_LEN; NETDRV_W16_F (RxBufPtr, tp->cur_rx - 16); } @@ -1739,7 +1736,7 @@ static int netdrv_close (struct net_device *dev) NETDRV_W16 (IntrMask, 0x0000); /* Update the error counts. */ - tp->stats.rx_missed_errors += NETDRV_R32 (RxMissed); + dev->stats.rx_missed_errors += NETDRV_R32 (RxMissed); NETDRV_W32 (RxMissed, 0); spin_unlock_irqrestore (&tp->lock, flags); @@ -1806,31 +1803,6 @@ static int netdrv_ioctl (struct net_device *dev, struct ifreq *rq, int cmd) return rc; } - -static struct net_device_stats *netdrv_get_stats (struct net_device *dev) -{ - struct netdrv_private *tp = dev->priv; - void *ioaddr = tp->mmio_addr; - - DPRINTK ("ENTER\n"); - - assert (tp != NULL); - - if (netif_running(dev)) { - unsigned long flags; - - spin_lock_irqsave (&tp->lock, flags); - - tp->stats.rx_missed_errors += NETDRV_R32 (RxMissed); - NETDRV_W32 (RxMissed, 0); - - spin_unlock_irqrestore (&tp->lock, flags); - } - - DPRINTK ("EXIT\n"); - return &tp->stats; -} - /* Set or clear the multicast filter for this adaptor. This routine is not state sensitive and need not be SMP locked. */ @@ -1908,7 +1880,7 @@ static int netdrv_suspend (struct pci_dev *pdev, pm_message_t state) NETDRV_W8 (ChipCmd, (NETDRV_R8 (ChipCmd) & ChipCmdClear)); /* Update the error counts. */ - tp->stats.rx_missed_errors += NETDRV_R32 (RxMissed); + dev->stats.rx_missed_errors += NETDRV_R32 (RxMissed); NETDRV_W32 (RxMissed, 0); spin_unlock_irqrestore (&tp->lock, flags); diff --git a/drivers/net/plip.c b/drivers/net/plip.c index 2cfab4b36654..c17d9ac9ff30 100644 --- a/drivers/net/plip.c +++ b/drivers/net/plip.c @@ -154,7 +154,6 @@ static int plip_hard_header_cache(struct neighbour *neigh, struct hh_cache *hh); static int plip_open(struct net_device *dev); static int plip_close(struct net_device *dev); -static struct net_device_stats *plip_get_stats(struct net_device *dev); static int plip_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd); static int plip_preempt(void *handle); static void plip_wakeup(void *handle); @@ -206,7 +205,6 @@ struct plip_local { }; struct net_local { - struct net_device_stats enet_stats; struct net_device *dev; struct work_struct immediate; struct delayed_work deferred; @@ -285,7 +283,6 @@ plip_init_netdev(struct net_device *dev) dev->hard_start_xmit = plip_tx_packet; dev->open = plip_open; dev->stop = plip_close; - dev->get_stats = plip_get_stats; dev->do_ioctl = plip_ioctl; dev->header_cache_update = NULL; dev->tx_queue_len = 10; @@ -430,8 +427,8 @@ plip_bh_timeout_error(struct net_device *dev, struct net_local *nl, dev->name, snd->state, c0); } else error = HS_TIMEOUT; - nl->enet_stats.tx_errors++; - nl->enet_stats.tx_aborted_errors++; + dev->stats.tx_errors++; + dev->stats.tx_aborted_errors++; } else if (nl->connection == PLIP_CN_RECEIVE) { if (rcv->state == PLIP_PK_TRIGGER) { /* Transmission was interrupted. */ @@ -448,7 +445,7 @@ plip_bh_timeout_error(struct net_device *dev, struct net_local *nl, printk(KERN_WARNING "%s: receive timeout(%d,%02x)\n", dev->name, rcv->state, c0); } - nl->enet_stats.rx_dropped++; + dev->stats.rx_dropped++; } rcv->state = PLIP_PK_DONE; if (rcv->skb) { @@ -661,7 +658,7 @@ plip_receive_packet(struct net_device *dev, struct net_local *nl, &rcv->nibble, &rcv->data)) return TIMEOUT; if (rcv->data != rcv->checksum) { - nl->enet_stats.rx_crc_errors++; + dev->stats.rx_crc_errors++; if (net_debug) printk(KERN_DEBUG "%s: checksum error\n", dev->name); return ERROR; @@ -673,8 +670,8 @@ plip_receive_packet(struct net_device *dev, struct net_local *nl, rcv->skb->protocol=plip_type_trans(rcv->skb, dev); netif_rx(rcv->skb); dev->last_rx = jiffies; - nl->enet_stats.rx_bytes += rcv->length.h; - nl->enet_stats.rx_packets++; + dev->stats.rx_bytes += rcv->length.h; + dev->stats.rx_packets++; rcv->skb = NULL; if (net_debug > 2) printk(KERN_DEBUG "%s: receive end\n", dev->name); @@ -776,7 +773,7 @@ plip_send_packet(struct net_device *dev, struct net_local *nl, if (nl->connection == PLIP_CN_RECEIVE) { spin_unlock_irq(&nl->lock); /* Interrupted. */ - nl->enet_stats.collisions++; + dev->stats.collisions++; return OK; } c0 = read_status(dev); @@ -792,7 +789,7 @@ plip_send_packet(struct net_device *dev, struct net_local *nl, {enable,disable}_irq *counts* them. -- AV */ ENABLE(dev->irq); - nl->enet_stats.collisions++; + dev->stats.collisions++; return OK; } disable_parport_interrupts (dev); @@ -840,9 +837,9 @@ plip_send_packet(struct net_device *dev, struct net_local *nl, &snd->nibble, snd->checksum)) return TIMEOUT; - nl->enet_stats.tx_bytes += snd->skb->len; + dev->stats.tx_bytes += snd->skb->len; dev_kfree_skb(snd->skb); - nl->enet_stats.tx_packets++; + dev->stats.tx_packets++; snd->state = PLIP_PK_DONE; case PLIP_PK_DONE: @@ -1199,15 +1196,6 @@ plip_wakeup(void *handle) return; } -static struct net_device_stats * -plip_get_stats(struct net_device *dev) -{ - struct net_local *nl = netdev_priv(dev); - struct net_device_stats *r = &nl->enet_stats; - - return r; -} - static int plip_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { diff --git a/drivers/net/qla3xxx.c b/drivers/net/qla3xxx.c index 309199bb7d12..97c6ed07dd15 100755 --- a/drivers/net/qla3xxx.c +++ b/drivers/net/qla3xxx.c @@ -2053,7 +2053,7 @@ static void ql_process_mac_tx_intr(struct ql3_adapter *qdev, if(mac_rsp->flags & OB_MAC_IOCB_RSP_S) { printk(KERN_ERR "Frame too short to be legal, frame not sent.\n"); - qdev->stats.tx_errors++; + qdev->ndev->stats.tx_errors++; retval = -EIO; goto frame_not_sent; } @@ -2061,7 +2061,7 @@ static void ql_process_mac_tx_intr(struct ql3_adapter *qdev, if(tx_cb->seg_count == 0) { printk(KERN_ERR "tx_cb->seg_count == 0: %d\n", mac_rsp->transaction_id); - qdev->stats.tx_errors++; + qdev->ndev->stats.tx_errors++; retval = -EIO; goto invalid_seg_count; } @@ -2080,8 +2080,8 @@ static void ql_process_mac_tx_intr(struct ql3_adapter *qdev, PCI_DMA_TODEVICE); } } - qdev->stats.tx_packets++; - qdev->stats.tx_bytes += tx_cb->skb->len; + qdev->ndev->stats.tx_packets++; + qdev->ndev->stats.tx_bytes += tx_cb->skb->len; frame_not_sent: dev_kfree_skb_irq(tx_cb->skb); @@ -2140,8 +2140,8 @@ static void ql_process_mac_rx_intr(struct ql3_adapter *qdev, lrg_buf_cb2 = ql_get_lbuf(qdev); skb = lrg_buf_cb2->skb; - qdev->stats.rx_packets++; - qdev->stats.rx_bytes += length; + qdev->ndev->stats.rx_packets++; + qdev->ndev->stats.rx_bytes += length; skb_put(skb, length); pci_unmap_single(qdev->pdev, @@ -2225,8 +2225,8 @@ static void ql_process_macip_rx_intr(struct ql3_adapter *qdev, skb2->protocol = eth_type_trans(skb2, qdev->ndev); netif_receive_skb(skb2); - qdev->stats.rx_packets++; - qdev->stats.rx_bytes += length; + ndev->stats.rx_packets++; + ndev->stats.rx_bytes += length; ndev->last_rx = jiffies; lrg_buf_cb2->skb = NULL; @@ -3753,12 +3753,6 @@ static int ql3xxx_open(struct net_device *ndev) return (ql_adapter_up(qdev)); } -static struct net_device_stats *ql3xxx_get_stats(struct net_device *dev) -{ - struct ql3_adapter *qdev = (struct ql3_adapter *)dev->priv; - return &qdev->stats; -} - static void ql3xxx_set_multicast_list(struct net_device *ndev) { /* @@ -4048,7 +4042,6 @@ static int __devinit ql3xxx_probe(struct pci_dev *pdev, ndev->open = ql3xxx_open; ndev->hard_start_xmit = ql3xxx_send; ndev->stop = ql3xxx_close; - ndev->get_stats = ql3xxx_get_stats; ndev->set_multicast_list = ql3xxx_set_multicast_list; SET_ETHTOOL_OPS(ndev, &ql3xxx_ethtool_ops); ndev->set_mac_address = ql3xxx_set_mac_address; diff --git a/drivers/net/qla3xxx.h b/drivers/net/qla3xxx.h index aa2216f0d7b8..483840f7fc10 100755 --- a/drivers/net/qla3xxx.h +++ b/drivers/net/qla3xxx.h @@ -1283,7 +1283,6 @@ struct ql3_adapter { u32 update_ob_opcode; /* Opcode to use for updating NCB */ u32 mb_bit_mask; /* MA Bits mask to use on transmission */ u32 numPorts; - struct net_device_stats stats; struct workqueue_struct *workqueue; struct delayed_work reset_work; struct delayed_work tx_timeout_work; diff --git a/drivers/net/rionet.c b/drivers/net/rionet.c index 25a9dd821aa2..d43dcf3ed5a9 100644 --- a/drivers/net/rionet.c +++ b/drivers/net/rionet.c @@ -53,7 +53,6 @@ struct rionet_private { struct rio_mport *mport; struct sk_buff *rx_skb[RIONET_RX_RING_SIZE]; struct sk_buff *tx_skb[RIONET_TX_RING_SIZE]; - struct net_device_stats stats; int rx_slot; int tx_slot; int tx_cnt; @@ -91,12 +90,6 @@ static struct rio_dev *rionet_active[RIO_MAX_ROUTE_ENTRIES]; #define RIONET_MAC_MATCH(x) (*(u32 *)x == 0x00010001) #define RIONET_GET_DESTID(x) (*(u16 *)(x + 4)) -static struct net_device_stats *rionet_stats(struct net_device *ndev) -{ - struct rionet_private *rnet = ndev->priv; - return &rnet->stats; -} - static int rionet_rx_clean(struct net_device *ndev) { int i; @@ -120,15 +113,15 @@ static int rionet_rx_clean(struct net_device *ndev) error = netif_rx(rnet->rx_skb[i]); if (error == NET_RX_DROP) { - rnet->stats.rx_dropped++; + ndev->stats.rx_dropped++; } else if (error == NET_RX_BAD) { if (netif_msg_rx_err(rnet)) printk(KERN_WARNING "%s: bad rx packet\n", DRV_NAME); - rnet->stats.rx_errors++; + ndev->stats.rx_errors++; } else { - rnet->stats.rx_packets++; - rnet->stats.rx_bytes += RIO_MAX_MSG_SIZE; + ndev->stats.rx_packets++; + ndev->stats.rx_bytes += RIO_MAX_MSG_SIZE; } } while ((i = (i + 1) % RIONET_RX_RING_SIZE) != rnet->rx_slot); @@ -163,8 +156,8 @@ static int rionet_queue_tx_msg(struct sk_buff *skb, struct net_device *ndev, rio_add_outb_message(rnet->mport, rdev, 0, skb->data, skb->len); rnet->tx_skb[rnet->tx_slot] = skb; - rnet->stats.tx_packets++; - rnet->stats.tx_bytes += skb->len; + ndev->stats.tx_packets++; + ndev->stats.tx_bytes += skb->len; if (++rnet->tx_cnt == RIONET_TX_RING_SIZE) netif_stop_queue(ndev); @@ -466,7 +459,6 @@ static int rionet_setup_netdev(struct rio_mport *mport) ndev->open = &rionet_open; ndev->hard_start_xmit = &rionet_start_xmit; ndev->stop = &rionet_close; - ndev->get_stats = &rionet_stats; ndev->mtu = RIO_MAX_MSG_SIZE - 14; ndev->features = NETIF_F_LLTX; SET_ETHTOOL_OPS(ndev, &rionet_ethtool_ops); diff --git a/drivers/net/rrunner.c b/drivers/net/rrunner.c index 41f877d482c7..03facba05259 100644 --- a/drivers/net/rrunner.c +++ b/drivers/net/rrunner.c @@ -126,7 +126,6 @@ static int __devinit rr_init_one(struct pci_dev *pdev, dev->open = &rr_open; dev->hard_start_xmit = &rr_start_xmit; dev->stop = &rr_close; - dev->get_stats = &rr_get_stats; dev->do_ioctl = &rr_ioctl; dev->base_addr = pci_resource_start(pdev, 0); @@ -808,7 +807,7 @@ static u32 rr_handle_event(struct net_device *dev, u32 prodidx, u32 eidx) case E_CON_REJ: printk(KERN_WARNING "%s: Connection rejected\n", dev->name); - rrpriv->stats.tx_aborted_errors++; + dev->stats.tx_aborted_errors++; break; case E_CON_TMOUT: printk(KERN_WARNING "%s: Connection timeout\n", @@ -817,7 +816,7 @@ static u32 rr_handle_event(struct net_device *dev, u32 prodidx, u32 eidx) case E_DISC_ERR: printk(KERN_WARNING "%s: HIPPI disconnect error\n", dev->name); - rrpriv->stats.tx_aborted_errors++; + dev->stats.tx_aborted_errors++; break; case E_INT_PRTY: printk(KERN_ERR "%s: HIPPI Internal Parity error\n", @@ -833,7 +832,7 @@ static u32 rr_handle_event(struct net_device *dev, u32 prodidx, u32 eidx) case E_TX_LINK_DROP: printk(KERN_WARNING "%s: Link lost during transmit\n", dev->name); - rrpriv->stats.tx_aborted_errors++; + dev->stats.tx_aborted_errors++; writel(readl(®s->HostCtrl)|HALT_NIC|RR_CLEAR_INT, ®s->HostCtrl); wmb(); @@ -973,7 +972,7 @@ static void rx_int(struct net_device *dev, u32 rxlimit, u32 index) printk("len %x, mode %x\n", pkt_len, desc->mode); #endif if ( (rrpriv->rx_ring[index].mode & PACKET_BAD) == PACKET_BAD){ - rrpriv->stats.rx_dropped++; + dev->stats.rx_dropped++; goto defer; } @@ -986,7 +985,7 @@ static void rx_int(struct net_device *dev, u32 rxlimit, u32 index) skb = alloc_skb(pkt_len, GFP_ATOMIC); if (skb == NULL){ printk(KERN_WARNING "%s: Unable to allocate skb (%i bytes), deferring packet\n", dev->name, pkt_len); - rrpriv->stats.rx_dropped++; + dev->stats.rx_dropped++; goto defer; } else { pci_dma_sync_single_for_cpu(rrpriv->pci_dev, @@ -1024,7 +1023,7 @@ static void rx_int(struct net_device *dev, u32 rxlimit, u32 index) } else { printk("%s: Out of memory, deferring " "packet\n", dev->name); - rrpriv->stats.rx_dropped++; + dev->stats.rx_dropped++; goto defer; } } @@ -1033,8 +1032,8 @@ static void rx_int(struct net_device *dev, u32 rxlimit, u32 index) netif_rx(skb); /* send it up */ dev->last_rx = jiffies; - rrpriv->stats.rx_packets++; - rrpriv->stats.rx_bytes += pkt_len; + dev->stats.rx_packets++; + dev->stats.rx_bytes += pkt_len; } defer: desc->mode = 0; @@ -1102,8 +1101,8 @@ static irqreturn_t rr_interrupt(int irq, void *dev_id) desc = &(rrpriv->tx_ring[txcon]); skb = rrpriv->tx_skbuff[txcon]; - rrpriv->stats.tx_packets++; - rrpriv->stats.tx_bytes += skb->len; + dev->stats.tx_packets++; + dev->stats.tx_bytes += skb->len; pci_unmap_single(rrpriv->pci_dev, desc->addr.addrlo, skb->len, @@ -1491,16 +1490,6 @@ static int rr_start_xmit(struct sk_buff *skb, struct net_device *dev) } -static struct net_device_stats *rr_get_stats(struct net_device *dev) -{ - struct rr_private *rrpriv; - - rrpriv = netdev_priv(dev); - - return(&rrpriv->stats); -} - - /* * Read the firmware out of the EEPROM and put it into the SRAM * (or from user space - later) diff --git a/drivers/net/rrunner.h b/drivers/net/rrunner.h index 9f3e050c4dc6..6a79825bc8cf 100644 --- a/drivers/net/rrunner.h +++ b/drivers/net/rrunner.h @@ -819,7 +819,6 @@ struct rr_private u32 tx_full; u32 fw_rev; volatile short fw_running; - struct net_device_stats stats; struct pci_dev *pci_dev; }; @@ -834,7 +833,6 @@ static irqreturn_t rr_interrupt(int irq, void *dev_id); static int rr_open(struct net_device *dev); static int rr_start_xmit(struct sk_buff *skb, struct net_device *dev); static int rr_close(struct net_device *dev); -static struct net_device_stats *rr_get_stats(struct net_device *dev); static int rr_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); static unsigned int rr_read_eeprom(struct rr_private *rrpriv, unsigned long offset, diff --git a/drivers/net/saa9730.c b/drivers/net/saa9730.c index 7dae4d404978..14361e885415 100644 --- a/drivers/net/saa9730.c +++ b/drivers/net/saa9730.c @@ -151,30 +151,30 @@ static void __attribute_used__ show_saa9730_regs(struct lan_saa9730_private *lp) printk("lp->lan_saa9730_regs->CamData = %x\n", readl(&lp->lan_saa9730_regs->CamData)); } - printk("lp->stats.tx_packets = %lx\n", lp->stats.tx_packets); - printk("lp->stats.tx_errors = %lx\n", lp->stats.tx_errors); - printk("lp->stats.tx_aborted_errors = %lx\n", - lp->stats.tx_aborted_errors); - printk("lp->stats.tx_window_errors = %lx\n", - lp->stats.tx_window_errors); - printk("lp->stats.tx_carrier_errors = %lx\n", - lp->stats.tx_carrier_errors); - printk("lp->stats.tx_fifo_errors = %lx\n", - lp->stats.tx_fifo_errors); - printk("lp->stats.tx_heartbeat_errors = %lx\n", - lp->stats.tx_heartbeat_errors); - printk("lp->stats.collisions = %lx\n", lp->stats.collisions); - - printk("lp->stats.rx_packets = %lx\n", lp->stats.rx_packets); - printk("lp->stats.rx_errors = %lx\n", lp->stats.rx_errors); - printk("lp->stats.rx_dropped = %lx\n", lp->stats.rx_dropped); - printk("lp->stats.rx_crc_errors = %lx\n", lp->stats.rx_crc_errors); - printk("lp->stats.rx_frame_errors = %lx\n", - lp->stats.rx_frame_errors); - printk("lp->stats.rx_fifo_errors = %lx\n", - lp->stats.rx_fifo_errors); - printk("lp->stats.rx_length_errors = %lx\n", - lp->stats.rx_length_errors); + printk("dev->stats.tx_packets = %lx\n", dev->stats.tx_packets); + printk("dev->stats.tx_errors = %lx\n", dev->stats.tx_errors); + printk("dev->stats.tx_aborted_errors = %lx\n", + dev->stats.tx_aborted_errors); + printk("dev->stats.tx_window_errors = %lx\n", + dev->stats.tx_window_errors); + printk("dev->stats.tx_carrier_errors = %lx\n", + dev->stats.tx_carrier_errors); + printk("dev->stats.tx_fifo_errors = %lx\n", + dev->stats.tx_fifo_errors); + printk("dev->stats.tx_heartbeat_errors = %lx\n", + dev->stats.tx_heartbeat_errors); + printk("dev->stats.collisions = %lx\n", dev->stats.collisions); + + printk("dev->stats.rx_packets = %lx\n", dev->stats.rx_packets); + printk("dev->stats.rx_errors = %lx\n", dev->stats.rx_errors); + printk("dev->stats.rx_dropped = %lx\n", dev->stats.rx_dropped); + printk("dev->stats.rx_crc_errors = %lx\n", dev->stats.rx_crc_errors); + printk("dev->stats.rx_frame_errors = %lx\n", + dev->stats.rx_frame_errors); + printk("dev->stats.rx_fifo_errors = %lx\n", + dev->stats.rx_fifo_errors); + printk("dev->stats.rx_length_errors = %lx\n", + dev->stats.rx_length_errors); printk("lp->lan_saa9730_regs->DebugPCIMasterAddr = %x\n", readl(&lp->lan_saa9730_regs->DebugPCIMasterAddr)); @@ -605,24 +605,24 @@ static int lan_saa9730_tx(struct net_device *dev) printk("lan_saa9730_tx: tx error = %x\n", tx_status); - lp->stats.tx_errors++; + dev->stats.tx_errors++; if (tx_status & (TX_STATUS_EX_COLL << TX_STAT_CTL_STATUS_SHF)) - lp->stats.tx_aborted_errors++; + dev->stats.tx_aborted_errors++; if (tx_status & (TX_STATUS_LATE_COLL << TX_STAT_CTL_STATUS_SHF)) - lp->stats.tx_window_errors++; + dev->stats.tx_window_errors++; if (tx_status & (TX_STATUS_L_CARR << TX_STAT_CTL_STATUS_SHF)) - lp->stats.tx_carrier_errors++; + dev->stats.tx_carrier_errors++; if (tx_status & (TX_STATUS_UNDER << TX_STAT_CTL_STATUS_SHF)) - lp->stats.tx_fifo_errors++; + dev->stats.tx_fifo_errors++; if (tx_status & (TX_STATUS_SQ_ERR << TX_STAT_CTL_STATUS_SHF)) - lp->stats.tx_heartbeat_errors++; + dev->stats.tx_heartbeat_errors++; - lp->stats.collisions += + dev->stats.collisions += tx_status & TX_STATUS_TX_COLL_MSK; } @@ -684,10 +684,10 @@ static int lan_saa9730_rx(struct net_device *dev) printk ("%s: Memory squeeze, deferring packet.\n", dev->name); - lp->stats.rx_dropped++; + dev->stats.rx_dropped++; } else { - lp->stats.rx_bytes += len; - lp->stats.rx_packets++; + dev->stats.rx_bytes += len; + dev->stats.rx_packets++; skb_reserve(skb, 2); /* 16 byte align */ skb_put(skb, len); /* make room */ skb_copy_to_linear_data(skb, @@ -704,19 +704,19 @@ static int lan_saa9730_rx(struct net_device *dev) ("lan_saa9730_rx: We got an error packet = %x\n", rx_status); - lp->stats.rx_errors++; + dev->stats.rx_errors++; if (rx_status & (RX_STATUS_CRC_ERR << RX_STAT_CTL_STATUS_SHF)) - lp->stats.rx_crc_errors++; + dev->stats.rx_crc_errors++; if (rx_status & (RX_STATUS_ALIGN_ERR << RX_STAT_CTL_STATUS_SHF)) - lp->stats.rx_frame_errors++; + dev->stats.rx_frame_errors++; if (rx_status & (RX_STATUS_OVERFLOW << RX_STAT_CTL_STATUS_SHF)) - lp->stats.rx_fifo_errors++; + dev->stats.rx_fifo_errors++; if (rx_status & (RX_STATUS_LONG_ERR << RX_STAT_CTL_STATUS_SHF)) - lp->stats.rx_length_errors++; + dev->stats.rx_length_errors++; } /* Indicate we have processed the buffer. */ @@ -853,7 +853,7 @@ static void lan_saa9730_tx_timeout(struct net_device *dev) struct lan_saa9730_private *lp = netdev_priv(dev); /* Transmitter timeout, serious problems */ - lp->stats.tx_errors++; + dev->stats.tx_errors++; printk("%s: transmit timed out, reset\n", dev->name); /*show_saa9730_regs(lp); */ lan_saa9730_restart(lp); @@ -886,8 +886,8 @@ static int lan_saa9730_start_xmit(struct sk_buff *skb, return -1; } - lp->stats.tx_bytes += len; - lp->stats.tx_packets++; + dev->stats.tx_bytes += len; + dev->stats.tx_packets++; dev->trans_start = jiffies; netif_wake_queue(dev); @@ -919,14 +919,6 @@ static int lan_saa9730_close(struct net_device *dev) return 0; } -static struct net_device_stats *lan_saa9730_get_stats(struct net_device - *dev) -{ - struct lan_saa9730_private *lp = netdev_priv(dev); - - return &lp->stats; -} - static void lan_saa9730_set_multicast(struct net_device *dev) { struct lan_saa9730_private *lp = netdev_priv(dev); @@ -1040,7 +1032,6 @@ static int lan_saa9730_init(struct net_device *dev, struct pci_dev *pdev, dev->open = lan_saa9730_open; dev->hard_start_xmit = lan_saa9730_start_xmit; dev->stop = lan_saa9730_close; - dev->get_stats = lan_saa9730_get_stats; dev->set_multicast_list = lan_saa9730_set_multicast; dev->tx_timeout = lan_saa9730_tx_timeout; dev->watchdog_timeo = (HZ >> 1); diff --git a/drivers/net/saa9730.h b/drivers/net/saa9730.h index f656f2f40bb8..010a120ea938 100644 --- a/drivers/net/saa9730.h +++ b/drivers/net/saa9730.h @@ -378,7 +378,6 @@ struct lan_saa9730_private { unsigned char PhysicalAddress[LAN_SAA9730_CAM_ENTRIES][6]; - struct net_device_stats stats; spinlock_t lock; }; diff --git a/drivers/net/sb1000.c b/drivers/net/sb1000.c index aeaa75f549e6..487f9d2ac5b4 100644 --- a/drivers/net/sb1000.c +++ b/drivers/net/sb1000.c @@ -76,7 +76,6 @@ struct sb1000_private { unsigned char rx_session_id[NPIDS]; unsigned char rx_frame_id[NPIDS]; unsigned char rx_pkt_type[NPIDS]; - struct net_device_stats stats; }; /* prototypes for Linux interface */ @@ -85,7 +84,6 @@ static int sb1000_open(struct net_device *dev); static int sb1000_dev_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd); static int sb1000_start_xmit(struct sk_buff *skb, struct net_device *dev); static irqreturn_t sb1000_interrupt(int irq, void *dev_id); -static struct net_device_stats *sb1000_stats(struct net_device *dev); static int sb1000_close(struct net_device *dev); @@ -199,7 +197,6 @@ sb1000_probe_one(struct pnp_dev *pdev, const struct pnp_device_id *id) dev->do_ioctl = sb1000_dev_ioctl; dev->hard_start_xmit = sb1000_start_xmit; dev->stop = sb1000_close; - dev->get_stats = sb1000_stats; /* hardware address is 0:0:serial_number */ dev->dev_addr[2] = serial_number >> 24 & 0xff; @@ -739,7 +736,7 @@ sb1000_rx(struct net_device *dev) unsigned int skbsize; struct sk_buff *skb; struct sb1000_private *lp = netdev_priv(dev); - struct net_device_stats *stats = &lp->stats; + struct net_device_stats *stats = &dev->stats; /* SB1000 frame constants */ const int FrameSize = FRAMESIZE; @@ -1002,11 +999,11 @@ static int sb1000_dev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) switch (cmd) { case SIOCGCMSTATS: /* get statistics */ - stats[0] = lp->stats.rx_bytes; + stats[0] = dev->stats.rx_bytes; stats[1] = lp->rx_frames; - stats[2] = lp->stats.rx_packets; - stats[3] = lp->stats.rx_errors; - stats[4] = lp->stats.rx_dropped; + stats[2] = dev->stats.rx_packets; + stats[3] = dev->stats.rx_errors; + stats[4] = dev->stats.rx_dropped; if(copy_to_user(ifr->ifr_data, stats, sizeof(stats))) return -EFAULT; status = 0; @@ -1132,12 +1129,6 @@ static irqreturn_t sb1000_interrupt(int irq, void *dev_id) return IRQ_HANDLED; } -static struct net_device_stats *sb1000_stats(struct net_device *dev) -{ - struct sb1000_private *lp = netdev_priv(dev); - return &lp->stats; -} - static int sb1000_close(struct net_device *dev) { int i; diff --git a/drivers/net/sb1250-mac.c b/drivers/net/sb1250-mac.c index b6cafac97200..76e7ee9a6cbc 100644 --- a/drivers/net/sb1250-mac.c +++ b/drivers/net/sb1250-mac.c @@ -241,7 +241,6 @@ struct sbmac_softc { struct napi_struct napi; spinlock_t sbm_lock; /* spin lock */ struct timer_list sbm_timer; /* for monitoring MII */ - struct net_device_stats sbm_stats; int sbm_devflags; /* current device flags */ int sbm_phy_oldbmsr; @@ -317,7 +316,6 @@ static int sbmac_set_duplex(struct sbmac_softc *s,sbmac_duplex_t duplex,sbmac_fc static int sbmac_open(struct net_device *dev); static void sbmac_timer(unsigned long data); static void sbmac_tx_timeout (struct net_device *dev); -static struct net_device_stats *sbmac_get_stats(struct net_device *dev); static void sbmac_set_rx_mode(struct net_device *dev); static int sbmac_mii_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); static int sbmac_close(struct net_device *dev); @@ -1190,6 +1188,7 @@ static void sbmac_netpoll(struct net_device *netdev) static int sbdma_rx_process(struct sbmac_softc *sc,sbmacdma_t *d, int work_to_do, int poll) { + struct net_device *dev = sc->sbm_dev; int curidx; int hwidx; sbdmadscr_t *dsc; @@ -1202,7 +1201,7 @@ static int sbdma_rx_process(struct sbmac_softc *sc,sbmacdma_t *d, again: /* Check if the HW dropped any frames */ - sc->sbm_stats.rx_fifo_errors + dev->stats.rx_fifo_errors += __raw_readq(sc->sbm_rxdma.sbdma_oodpktlost) & 0xffff; __raw_writeq(0, sc->sbm_rxdma.sbdma_oodpktlost); @@ -1261,7 +1260,7 @@ again: if (unlikely (sbdma_add_rcvbuffer(d,NULL) == -ENOBUFS)) { - sc->sbm_stats.rx_dropped++; + dev->stats.rx_dropped++; sbdma_add_rcvbuffer(d,sb); /* re-add old buffer */ /* No point in continuing at the moment */ printk(KERN_ERR "dropped packet (1)\n"); @@ -1297,13 +1296,13 @@ again: dropped = netif_rx(sb); if (dropped == NET_RX_DROP) { - sc->sbm_stats.rx_dropped++; + dev->stats.rx_dropped++; d->sbdma_remptr = SBDMA_NEXTBUF(d,sbdma_remptr); goto done; } else { - sc->sbm_stats.rx_bytes += len; - sc->sbm_stats.rx_packets++; + dev->stats.rx_bytes += len; + dev->stats.rx_packets++; } } } else { @@ -1311,7 +1310,7 @@ again: * Packet was mangled somehow. Just drop it and * put it back on the receive ring. */ - sc->sbm_stats.rx_errors++; + dev->stats.rx_errors++; sbdma_add_rcvbuffer(d,sb); } @@ -1351,6 +1350,7 @@ done: static void sbdma_tx_process(struct sbmac_softc *sc,sbmacdma_t *d, int poll) { + struct net_device *dev = sc->sbm_dev; int curidx; int hwidx; sbdmadscr_t *dsc; @@ -1401,8 +1401,8 @@ static void sbdma_tx_process(struct sbmac_softc *sc,sbmacdma_t *d, int poll) * Stats */ - sc->sbm_stats.tx_bytes += sb->len; - sc->sbm_stats.tx_packets++; + dev->stats.tx_bytes += sb->len; + dev->stats.tx_packets++; /* * for transmits, we just free buffers. @@ -2457,7 +2457,6 @@ static int sbmac_init(struct net_device *dev, int idx) dev->open = sbmac_open; dev->hard_start_xmit = sbmac_start_tx; dev->stop = sbmac_close; - dev->get_stats = sbmac_get_stats; dev->set_multicast_list = sbmac_set_rx_mode; dev->do_ioctl = sbmac_mii_ioctl; dev->tx_timeout = sbmac_tx_timeout; @@ -2748,7 +2747,7 @@ static void sbmac_tx_timeout (struct net_device *dev) dev->trans_start = jiffies; - sc->sbm_stats.tx_errors++; + dev->stats.tx_errors++; spin_unlock_irq (&sc->sbm_lock); @@ -2758,22 +2757,6 @@ static void sbmac_tx_timeout (struct net_device *dev) -static struct net_device_stats *sbmac_get_stats(struct net_device *dev) -{ - struct sbmac_softc *sc = netdev_priv(dev); - unsigned long flags; - - spin_lock_irqsave(&sc->sbm_lock, flags); - - /* XXX update other stats here */ - - spin_unlock_irqrestore(&sc->sbm_lock, flags); - - return &sc->sbm_stats; -} - - - static void sbmac_set_rx_mode(struct net_device *dev) { unsigned long flags; diff --git a/drivers/net/seeq8005.c b/drivers/net/seeq8005.c index 4bce7c4f373c..8ef94028cba5 100644 --- a/drivers/net/seeq8005.c +++ b/drivers/net/seeq8005.c @@ -67,7 +67,6 @@ static unsigned int net_debug = NET_DEBUG; /* Information that need to be kept for each board. */ struct net_local { - struct net_device_stats stats; unsigned short receive_ptr; /* What address in packet memory do we expect a recv_pkt_header? */ long open_time; /* Useless example local info. */ }; @@ -86,7 +85,6 @@ static int seeq8005_send_packet(struct sk_buff *skb, struct net_device *dev); static irqreturn_t seeq8005_interrupt(int irq, void *dev_id); static void seeq8005_rx(struct net_device *dev); static int seeq8005_close(struct net_device *dev); -static struct net_device_stats *seeq8005_get_stats(struct net_device *dev); static void set_multicast_list(struct net_device *dev); /* Example routines you must write ;->. */ @@ -338,7 +336,6 @@ static int __init seeq8005_probe1(struct net_device *dev, int ioaddr) dev->hard_start_xmit = seeq8005_send_packet; dev->tx_timeout = seeq8005_timeout; dev->watchdog_timeo = HZ/20; - dev->get_stats = seeq8005_get_stats; dev->set_multicast_list = set_multicast_list; dev->flags &= ~IFF_MULTICAST; @@ -391,7 +388,6 @@ static void seeq8005_timeout(struct net_device *dev) static int seeq8005_send_packet(struct sk_buff *skb, struct net_device *dev) { - struct net_local *lp = netdev_priv(dev); short length = skb->len; unsigned char *buf; @@ -407,7 +403,7 @@ static int seeq8005_send_packet(struct sk_buff *skb, struct net_device *dev) hardware_send_packet(dev, buf, length); dev->trans_start = jiffies; - lp->stats.tx_bytes += length; + dev->stats.tx_bytes += length; dev_kfree_skb (skb); /* You might need to clean up and record Tx statistics here. */ @@ -463,7 +459,7 @@ static irqreturn_t seeq8005_interrupt(int irq, void *dev_id) if (status & SEEQSTAT_TX_INT) { handled = 1; outw( SEEQCMD_TX_INT_ACK | (status & SEEQCMD_INT_MASK), SEEQ_CMD); - lp->stats.tx_packets++; + dev->stats.tx_packets++; netif_wake_queue(dev); /* Inform upper layers. */ } if (status & SEEQSTAT_RX_INT) { @@ -531,11 +527,11 @@ static void seeq8005_rx(struct net_device *dev) } if (pkt_hdr & SEEQPKTS_ANY_ERROR) { /* There was an error. */ - lp->stats.rx_errors++; - if (pkt_hdr & SEEQPKTS_SHORT) lp->stats.rx_frame_errors++; - if (pkt_hdr & SEEQPKTS_DRIB) lp->stats.rx_frame_errors++; - if (pkt_hdr & SEEQPKTS_OVERSIZE) lp->stats.rx_over_errors++; - if (pkt_hdr & SEEQPKTS_CRC_ERR) lp->stats.rx_crc_errors++; + dev->stats.rx_errors++; + if (pkt_hdr & SEEQPKTS_SHORT) dev->stats.rx_frame_errors++; + if (pkt_hdr & SEEQPKTS_DRIB) dev->stats.rx_frame_errors++; + if (pkt_hdr & SEEQPKTS_OVERSIZE) dev->stats.rx_over_errors++; + if (pkt_hdr & SEEQPKTS_CRC_ERR) dev->stats.rx_crc_errors++; /* skip over this packet */ outw( SEEQCMD_FIFO_WRITE | SEEQCMD_DMA_INT_ACK | (status & SEEQCMD_INT_MASK), SEEQ_CMD); outw( (lp->receive_ptr & 0xff00)>>8, SEEQ_REA); @@ -547,7 +543,7 @@ static void seeq8005_rx(struct net_device *dev) skb = dev_alloc_skb(pkt_len); if (skb == NULL) { printk("%s: Memory squeeze, dropping packet.\n", dev->name); - lp->stats.rx_dropped++; + dev->stats.rx_dropped++; break; } skb_reserve(skb, 2); /* align data on 16 byte */ @@ -567,8 +563,8 @@ static void seeq8005_rx(struct net_device *dev) skb->protocol=eth_type_trans(skb,dev); netif_rx(skb); dev->last_rx = jiffies; - lp->stats.rx_packets++; - lp->stats.rx_bytes += pkt_len; + dev->stats.rx_packets++; + dev->stats.rx_bytes += pkt_len; } } while ((--boguscount) && (pkt_hdr & SEEQPKTH_CHAIN)); @@ -599,15 +595,6 @@ static int seeq8005_close(struct net_device *dev) } -/* Get the current statistics. This may be called with the card open or - closed. */ -static struct net_device_stats *seeq8005_get_stats(struct net_device *dev) -{ - struct net_local *lp = netdev_priv(dev); - - return &lp->stats; -} - /* Set or clear the multicast filter for this adaptor. num_addrs == -1 Promiscuous mode, receive all packets num_addrs == 0 Normal mode, clear multicast list diff --git a/drivers/net/sgiseeq.c b/drivers/net/sgiseeq.c index eb67b024e413..5189ef066884 100644 --- a/drivers/net/sgiseeq.c +++ b/drivers/net/sgiseeq.c @@ -93,8 +93,6 @@ struct sgiseeq_private { unsigned char control; unsigned char mode; - struct net_device_stats stats; - spinlock_t tx_lock; }; @@ -267,18 +265,17 @@ static int init_seeq(struct net_device *dev, struct sgiseeq_private *sp, return 0; } -static inline void record_rx_errors(struct sgiseeq_private *sp, - unsigned char status) +static void record_rx_errors(struct net_device *dev, unsigned char status) { if (status & SEEQ_RSTAT_OVERF || status & SEEQ_RSTAT_SFRAME) - sp->stats.rx_over_errors++; + dev->stats.rx_over_errors++; if (status & SEEQ_RSTAT_CERROR) - sp->stats.rx_crc_errors++; + dev->stats.rx_crc_errors++; if (status & SEEQ_RSTAT_DERROR) - sp->stats.rx_frame_errors++; + dev->stats.rx_frame_errors++; if (status & SEEQ_RSTAT_REOF) - sp->stats.rx_errors++; + dev->stats.rx_errors++; } static inline void rx_maybe_restart(struct sgiseeq_private *sp, @@ -328,8 +325,8 @@ static inline void sgiseeq_rx(struct net_device *dev, struct sgiseeq_private *sp if (memcmp(eth_hdr(skb)->h_source, dev->dev_addr, ETH_ALEN)) { netif_rx(skb); dev->last_rx = jiffies; - sp->stats.rx_packets++; - sp->stats.rx_bytes += len; + dev->stats.rx_packets++; + dev->stats.rx_bytes += len; } else { /* Silently drop my own packets */ dev_kfree_skb_irq(skb); @@ -337,10 +334,10 @@ static inline void sgiseeq_rx(struct net_device *dev, struct sgiseeq_private *sp } else { printk (KERN_NOTICE "%s: Memory squeeze, deferring packet.\n", dev->name); - sp->stats.rx_dropped++; + dev->stats.rx_dropped++; } } else { - record_rx_errors(sp, pkt_status); + record_rx_errors(dev, pkt_status); } /* Return the entry to the ring pool. */ @@ -392,11 +389,11 @@ static inline void sgiseeq_tx(struct net_device *dev, struct sgiseeq_private *sp if (!(status & (HPC3_ETXCTRL_ACTIVE | SEEQ_TSTAT_PTRANS))) { /* Oops, HPC detected some sort of error. */ if (status & SEEQ_TSTAT_R16) - sp->stats.tx_aborted_errors++; + dev->stats.tx_aborted_errors++; if (status & SEEQ_TSTAT_UFLOW) - sp->stats.tx_fifo_errors++; + dev->stats.tx_fifo_errors++; if (status & SEEQ_TSTAT_LCLS) - sp->stats.collisions++; + dev->stats.collisions++; } /* Ack 'em... */ @@ -412,7 +409,7 @@ static inline void sgiseeq_tx(struct net_device *dev, struct sgiseeq_private *sp } break; } - sp->stats.tx_packets++; + dev->stats.tx_packets++; sp->tx_old = NEXT_TX(sp->tx_old); td->tdma.cntinfo &= ~(HPCDMA_XIU | HPCDMA_XIE); td->tdma.cntinfo |= HPCDMA_EOX; @@ -516,7 +513,7 @@ static int sgiseeq_start_xmit(struct sk_buff *skb, struct net_device *dev) /* Setup... */ skblen = skb->len; len = (skblen <= ETH_ZLEN) ? ETH_ZLEN : skblen; - sp->stats.tx_bytes += len; + dev->stats.tx_bytes += len; entry = sp->tx_new; td = &sp->tx_desc[entry]; @@ -569,13 +566,6 @@ static void timeout(struct net_device *dev) netif_wake_queue(dev); } -static struct net_device_stats *sgiseeq_get_stats(struct net_device *dev) -{ - struct sgiseeq_private *sp = netdev_priv(dev); - - return &sp->stats; -} - static void sgiseeq_set_multicast(struct net_device *dev) { struct sgiseeq_private *sp = (struct sgiseeq_private *) dev->priv; @@ -694,7 +684,6 @@ static int __init sgiseeq_probe(struct platform_device *pdev) dev->hard_start_xmit = sgiseeq_start_xmit; dev->tx_timeout = timeout; dev->watchdog_timeo = (200 * HZ) / 1000; - dev->get_stats = sgiseeq_get_stats; dev->set_multicast_list = sgiseeq_set_multicast; dev->set_mac_address = sgiseeq_set_mac_address; dev->irq = irq; diff --git a/drivers/net/shaper.c b/drivers/net/shaper.c index b56721a68a85..315feba7dacc 100644 --- a/drivers/net/shaper.c +++ b/drivers/net/shaper.c @@ -171,7 +171,7 @@ static int shaper_start_xmit(struct sk_buff *skb, struct net_device *dev) */ if(time_after(SHAPERCB(skb)->shapeclock,jiffies + SHAPER_LATENCY)) { dev_kfree_skb(skb); - shaper->stats.tx_dropped++; + dev->stats.tx_dropped++; } else skb_queue_tail(&shaper->sendq, skb); } @@ -182,7 +182,7 @@ static int shaper_start_xmit(struct sk_buff *skb, struct net_device *dev) { ptr=skb_dequeue(&shaper->sendq); dev_kfree_skb(ptr); - shaper->stats.collisions++; + dev->stats.collisions++; } shaper_kick(shaper); spin_unlock(&shaper->lock); @@ -207,8 +207,8 @@ static void shaper_queue_xmit(struct shaper *shaper, struct sk_buff *skb) shaper->dev->name,newskb->priority); dev_queue_xmit(newskb); - shaper->stats.tx_bytes += skb->len; - shaper->stats.tx_packets++; + shaper->dev->stats.tx_bytes += skb->len; + shaper->dev->stats.tx_packets++; if(sh_debug) printk("Kicked new frame out.\n"); @@ -330,12 +330,6 @@ static int shaper_close(struct net_device *dev) * ARP and other resolutions and not before. */ -static struct net_device_stats *shaper_get_stats(struct net_device *dev) -{ - struct shaper *sh=dev->priv; - return &sh->stats; -} - static int shaper_header(struct sk_buff *skb, struct net_device *dev, unsigned short type, void *daddr, void *saddr, unsigned len) { @@ -538,7 +532,6 @@ static void __init shaper_setup(struct net_device *dev) dev->open = shaper_open; dev->stop = shaper_close; dev->hard_start_xmit = shaper_start_xmit; - dev->get_stats = shaper_get_stats; dev->set_multicast_list = NULL; /* diff --git a/drivers/net/sis190.c b/drivers/net/sis190.c index e810ae942cd6..808141b46585 100644 --- a/drivers/net/sis190.c +++ b/drivers/net/sis190.c @@ -270,7 +270,6 @@ struct sis190_private { void __iomem *mmio_addr; struct pci_dev *pci_dev; struct net_device *dev; - struct net_device_stats stats; spinlock_t lock; u32 rx_buf_sz; u32 cur_rx; @@ -569,7 +568,7 @@ static inline int sis190_rx_pkt_err(u32 status, struct net_device_stats *stats) static int sis190_rx_interrupt(struct net_device *dev, struct sis190_private *tp, void __iomem *ioaddr) { - struct net_device_stats *stats = &tp->stats; + struct net_device_stats *stats = &dev->stats; u32 rx_left, cur_rx = tp->cur_rx; u32 delta, count; @@ -683,8 +682,8 @@ static void sis190_tx_interrupt(struct net_device *dev, skb = tp->Tx_skbuff[entry]; - tp->stats.tx_packets++; - tp->stats.tx_bytes += skb->len; + dev->stats.tx_packets++; + dev->stats.tx_bytes += skb->len; sis190_unmap_tx_skb(tp->pci_dev, skb, txd); tp->Tx_skbuff[entry] = NULL; @@ -1080,7 +1079,7 @@ static void sis190_tx_clear(struct sis190_private *tp) tp->Tx_skbuff[i] = NULL; dev_kfree_skb(skb); - tp->stats.tx_dropped++; + tp->dev->stats.tx_dropped++; } tp->cur_tx = tp->dirty_tx = 0; } @@ -1143,7 +1142,7 @@ static int sis190_start_xmit(struct sk_buff *skb, struct net_device *dev) if (unlikely(skb->len < ETH_ZLEN)) { if (skb_padto(skb, ETH_ZLEN)) { - tp->stats.tx_dropped++; + dev->stats.tx_dropped++; goto out; } len = ETH_ZLEN; @@ -1196,13 +1195,6 @@ out: return NETDEV_TX_OK; } -static struct net_device_stats *sis190_get_stats(struct net_device *dev) -{ - struct sis190_private *tp = netdev_priv(dev); - - return &tp->stats; -} - static void sis190_free_phy(struct list_head *first_phy) { struct sis190_phy *cur, *next; @@ -1795,7 +1787,6 @@ static int __devinit sis190_init_one(struct pci_dev *pdev, dev->open = sis190_open; dev->stop = sis190_close; dev->do_ioctl = sis190_ioctl; - dev->get_stats = sis190_get_stats; dev->tx_timeout = sis190_tx_timeout; dev->watchdog_timeo = SIS190_TX_TIMEOUT; dev->hard_start_xmit = sis190_start_xmit; diff --git a/drivers/net/sis900.c b/drivers/net/sis900.c index e1930c3ee75d..5da8e671324d 100644 --- a/drivers/net/sis900.c +++ b/drivers/net/sis900.c @@ -158,7 +158,6 @@ typedef struct _BufferDesc { } BufferDesc; struct sis900_private { - struct net_device_stats stats; struct pci_dev * pci_dev; spinlock_t lock; @@ -221,7 +220,6 @@ static void sis900_finish_xmit (struct net_device *net_dev); static irqreturn_t sis900_interrupt(int irq, void *dev_instance); static int sis900_close(struct net_device *net_dev); static int mii_ioctl(struct net_device *net_dev, struct ifreq *rq, int cmd); -static struct net_device_stats *sis900_get_stats(struct net_device *net_dev); static u16 sis900_mcast_bitnr(u8 *addr, u8 revision); static void set_rx_mode(struct net_device *net_dev); static void sis900_reset(struct net_device *net_dev); @@ -466,7 +464,6 @@ static int __devinit sis900_probe(struct pci_dev *pci_dev, net_dev->open = &sis900_open; net_dev->hard_start_xmit = &sis900_start_xmit; net_dev->stop = &sis900_close; - net_dev->get_stats = &sis900_get_stats; net_dev->set_config = &sis900_set_config; net_dev->set_multicast_list = &set_rx_mode; net_dev->do_ioctl = &mii_ioctl; @@ -1542,7 +1539,7 @@ static void sis900_tx_timeout(struct net_device *net_dev) sis_priv->tx_skbuff[i] = NULL; sis_priv->tx_ring[i].cmdsts = 0; sis_priv->tx_ring[i].bufptr = 0; - sis_priv->stats.tx_dropped++; + net_dev->stats.tx_dropped++; } } sis_priv->tx_full = 0; @@ -1739,15 +1736,15 @@ static int sis900_rx(struct net_device *net_dev) printk(KERN_DEBUG "%s: Corrupted packet " "received, buffer status = 0x%8.8x/%d.\n", net_dev->name, rx_status, data_size); - sis_priv->stats.rx_errors++; + net_dev->stats.rx_errors++; if (rx_status & OVERRUN) - sis_priv->stats.rx_over_errors++; + net_dev->stats.rx_over_errors++; if (rx_status & (TOOLONG|RUNT)) - sis_priv->stats.rx_length_errors++; + net_dev->stats.rx_length_errors++; if (rx_status & (RXISERR | FAERR)) - sis_priv->stats.rx_frame_errors++; + net_dev->stats.rx_frame_errors++; if (rx_status & CRCERR) - sis_priv->stats.rx_crc_errors++; + net_dev->stats.rx_crc_errors++; /* reset buffer descriptor state */ sis_priv->rx_ring[entry].cmdsts = RX_BUF_SIZE; } else { @@ -1768,7 +1765,7 @@ static int sis900_rx(struct net_device *net_dev) * in the rx ring */ skb = sis_priv->rx_skbuff[entry]; - sis_priv->stats.rx_dropped++; + net_dev->stats.rx_dropped++; goto refill_rx_ring; } @@ -1793,10 +1790,10 @@ static int sis900_rx(struct net_device *net_dev) /* some network statistics */ if ((rx_status & BCAST) == MCAST) - sis_priv->stats.multicast++; + net_dev->stats.multicast++; net_dev->last_rx = jiffies; - sis_priv->stats.rx_bytes += rx_size; - sis_priv->stats.rx_packets++; + net_dev->stats.rx_bytes += rx_size; + net_dev->stats.rx_packets++; sis_priv->dirty_rx++; refill_rx_ring: sis_priv->rx_skbuff[entry] = skb; @@ -1827,7 +1824,7 @@ refill_rx_ring: printk(KERN_INFO "%s: Memory squeeze," "deferring packet.\n", net_dev->name); - sis_priv->stats.rx_dropped++; + net_dev->stats.rx_dropped++; break; } sis_priv->rx_skbuff[entry] = skb; @@ -1878,20 +1875,20 @@ static void sis900_finish_xmit (struct net_device *net_dev) printk(KERN_DEBUG "%s: Transmit " "error, Tx status %8.8x.\n", net_dev->name, tx_status); - sis_priv->stats.tx_errors++; + net_dev->stats.tx_errors++; if (tx_status & UNDERRUN) - sis_priv->stats.tx_fifo_errors++; + net_dev->stats.tx_fifo_errors++; if (tx_status & ABORT) - sis_priv->stats.tx_aborted_errors++; + net_dev->stats.tx_aborted_errors++; if (tx_status & NOCARRIER) - sis_priv->stats.tx_carrier_errors++; + net_dev->stats.tx_carrier_errors++; if (tx_status & OWCOLL) - sis_priv->stats.tx_window_errors++; + net_dev->stats.tx_window_errors++; } else { /* packet successfully transmitted */ - sis_priv->stats.collisions += (tx_status & COLCNT) >> 16; - sis_priv->stats.tx_bytes += tx_status & DSIZE; - sis_priv->stats.tx_packets++; + net_dev->stats.collisions += (tx_status & COLCNT) >> 16; + net_dev->stats.tx_bytes += tx_status & DSIZE; + net_dev->stats.tx_packets++; } /* Free the original skb. */ skb = sis_priv->tx_skbuff[entry]; @@ -2137,21 +2134,6 @@ static int mii_ioctl(struct net_device *net_dev, struct ifreq *rq, int cmd) } } -/** - * sis900_get_stats - Get sis900 read/write statistics - * @net_dev: the net device to get statistics for - * - * get tx/rx statistics for sis900 - */ - -static struct net_device_stats * -sis900_get_stats(struct net_device *net_dev) -{ - struct sis900_private *sis_priv = net_dev->priv; - - return &sis_priv->stats; -} - /** * sis900_set_config - Set media type by net_device.set_config * @dev: the net device for media type change diff --git a/drivers/net/smc911x.c b/drivers/net/smc911x.c index 5f03e44ad135..c0276c04dece 100644 --- a/drivers/net/smc911x.c +++ b/drivers/net/smc911x.c @@ -115,13 +115,6 @@ struct smc911x_local { */ struct sk_buff *pending_tx_skb; - /* - * these are things that the kernel wants me to keep, so users - * can find out semi-useless statistics of how well the card is - * performing - */ - struct net_device_stats stats; - /* version/revision of the SMC911x chip */ u16 version; u16 revision; @@ -315,8 +308,8 @@ static void smc911x_reset(struct net_device *dev) if (lp->pending_tx_skb != NULL) { dev_kfree_skb (lp->pending_tx_skb); lp->pending_tx_skb = NULL; - lp->stats.tx_errors++; - lp->stats.tx_aborted_errors++; + dev->stats.tx_errors++; + dev->stats.tx_aborted_errors++; } } @@ -449,14 +442,14 @@ static inline void smc911x_rcv(struct net_device *dev) pkt_len = (status & RX_STS_PKT_LEN_) >> 16; if (status & RX_STS_ES_) { /* Deal with a bad packet */ - lp->stats.rx_errors++; + dev->stats.rx_errors++; if (status & RX_STS_CRC_ERR_) - lp->stats.rx_crc_errors++; + dev->stats.rx_crc_errors++; else { if (status & RX_STS_LEN_ERR_) - lp->stats.rx_length_errors++; + dev->stats.rx_length_errors++; if (status & RX_STS_MCAST_) - lp->stats.multicast++; + dev->stats.multicast++; } /* Remove the bad packet data from the RX FIFO */ smc911x_drop_pkt(dev); @@ -467,7 +460,7 @@ static inline void smc911x_rcv(struct net_device *dev) if (unlikely(skb == NULL)) { PRINTK( "%s: Low memory, rcvd packet dropped.\n", dev->name); - lp->stats.rx_dropped++; + dev->stats.rx_dropped++; smc911x_drop_pkt(dev); return; } @@ -503,8 +496,8 @@ static inline void smc911x_rcv(struct net_device *dev) dev->last_rx = jiffies; skb->protocol = eth_type_trans(skb, dev); netif_rx(skb); - lp->stats.rx_packets++; - lp->stats.rx_bytes += pkt_len-4; + dev->stats.rx_packets++; + dev->stats.rx_bytes += pkt_len-4; #endif } } @@ -616,8 +609,8 @@ static int smc911x_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) printk("%s: No Tx free space %d < %d\n", dev->name, free, skb->len); lp->pending_tx_skb = NULL; - lp->stats.tx_errors++; - lp->stats.tx_dropped++; + dev->stats.tx_errors++; + dev->stats.tx_dropped++; dev_kfree_skb(skb); return 0; } @@ -667,8 +660,8 @@ static void smc911x_tx(struct net_device *dev) dev->name, (SMC_GET_TX_FIFO_INF() & TX_FIFO_INF_TSUSED_) >> 16); tx_status = SMC_GET_TX_STS_FIFO(); - lp->stats.tx_packets++; - lp->stats.tx_bytes+=tx_status>>16; + dev->stats.tx_packets++; + dev->stats.tx_bytes+=tx_status>>16; DBG(SMC_DEBUG_TX, "%s: Tx FIFO tag 0x%04x status 0x%04x\n", dev->name, (tx_status & 0xffff0000) >> 16, tx_status & 0x0000ffff); @@ -676,22 +669,22 @@ static void smc911x_tx(struct net_device *dev) * full-duplex mode */ if ((tx_status & TX_STS_ES_) && !(lp->ctl_rfduplx && !(tx_status & 0x00000306))) { - lp->stats.tx_errors++; + dev->stats.tx_errors++; } if (tx_status & TX_STS_MANY_COLL_) { - lp->stats.collisions+=16; - lp->stats.tx_aborted_errors++; + dev->stats.collisions+=16; + dev->stats.tx_aborted_errors++; } else { - lp->stats.collisions+=(tx_status & TX_STS_COLL_CNT_) >> 3; + dev->stats.collisions+=(tx_status & TX_STS_COLL_CNT_) >> 3; } /* carrier error only has meaning for half-duplex communication */ if ((tx_status & (TX_STS_LOC_ | TX_STS_NO_CARR_)) && !lp->ctl_rfduplx) { - lp->stats.tx_carrier_errors++; + dev->stats.tx_carrier_errors++; } if (tx_status & TX_STS_LATE_COLL_) { - lp->stats.collisions++; - lp->stats.tx_aborted_errors++; + dev->stats.collisions++; + dev->stats.tx_aborted_errors++; } } } @@ -1121,11 +1114,11 @@ static irqreturn_t smc911x_interrupt(int irq, void *dev_id) /* Handle various error conditions */ if (status & INT_STS_RXE_) { SMC_ACK_INT(INT_STS_RXE_); - lp->stats.rx_errors++; + dev->stats.rx_errors++; } if (status & INT_STS_RXDFH_INT_) { SMC_ACK_INT(INT_STS_RXDFH_INT_); - lp->stats.rx_dropped+=SMC_GET_RX_DROP(); + dev->stats.rx_dropped+=SMC_GET_RX_DROP(); } /* Undocumented interrupt-what is the right thing to do here? */ if (status & INT_STS_RXDF_INT_) { @@ -1140,8 +1133,8 @@ static irqreturn_t smc911x_interrupt(int irq, void *dev_id) cr &= ~MAC_CR_RXEN_; SMC_SET_MAC_CR(cr); DBG(SMC_DEBUG_RX, "%s: RX overrun\n", dev->name); - lp->stats.rx_errors++; - lp->stats.rx_fifo_errors++; + dev->stats.rx_errors++; + dev->stats.rx_fifo_errors++; } SMC_ACK_INT(INT_STS_RDFL_); } @@ -1152,8 +1145,8 @@ static irqreturn_t smc911x_interrupt(int irq, void *dev_id) SMC_SET_MAC_CR(cr); rx_overrun=1; DBG(SMC_DEBUG_RX, "%s: RX overrun\n", dev->name); - lp->stats.rx_errors++; - lp->stats.rx_fifo_errors++; + dev->stats.rx_errors++; + dev->stats.rx_fifo_errors++; } SMC_ACK_INT(INT_STS_RDFO_); } @@ -1307,8 +1300,8 @@ smc911x_rx_dma_irq(int dma, void *data) dev->last_rx = jiffies; skb->protocol = eth_type_trans(skb, dev); netif_rx(skb); - lp->stats.rx_packets++; - lp->stats.rx_bytes += skb->len; + dev->stats.rx_packets++; + dev->stats.rx_bytes += skb->len; spin_lock_irqsave(&lp->lock, flags); pkts = (SMC_GET_RX_FIFO_INF() & RX_FIFO_INF_RXSUSED_) >> 16; @@ -1567,19 +1560,6 @@ static int smc911x_close(struct net_device *dev) return 0; } -/* - * Get the current statistics. - * This may be called with the card open or closed. - */ -static struct net_device_stats *smc911x_query_statistics(struct net_device *dev) -{ - struct smc911x_local *lp = netdev_priv(dev); - DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __FUNCTION__); - - - return &lp->stats; -} - /* * Ethtool support */ @@ -2056,7 +2036,6 @@ static int __init smc911x_probe(struct net_device *dev, unsigned long ioaddr) dev->hard_start_xmit = smc911x_hard_start_xmit; dev->tx_timeout = smc911x_timeout; dev->watchdog_timeo = msecs_to_jiffies(watchdog); - dev->get_stats = smc911x_query_statistics; dev->set_multicast_list = smc911x_set_multicast_list; dev->ethtool_ops = &smc911x_ethtool_ops; #ifdef CONFIG_NET_POLL_CONTROLLER diff --git a/drivers/net/smc9194.c b/drivers/net/smc9194.c index 0a79516d196e..5b6748e3ea0e 100644 --- a/drivers/net/smc9194.c +++ b/drivers/net/smc9194.c @@ -190,13 +190,6 @@ static struct devlist smc_devlist[] __initdata = { /* store this information for the driver.. */ struct smc_local { - /* - these are things that the kernel wants me to keep, so users - can find out semi-useless statistics of how well the card is - performing - */ - struct net_device_stats stats; - /* If I have to wait until memory is available to send a packet, I will store the skbuff here, until I get the @@ -248,12 +241,6 @@ static void smc_timeout(struct net_device *dev); */ static int smc_close(struct net_device *dev); -/* - . This routine allows the proc file system to query the driver's - . statistics. -*/ -static struct net_device_stats * smc_query_statistics( struct net_device *dev); - /* . Finally, a call to set promiscuous mode ( for TCPDUMP and related . programs ) and multicast modes. @@ -514,7 +501,7 @@ static int smc_wait_to_send_packet( struct sk_buff * skb, struct net_device * de if ( lp->saved_skb) { /* THIS SHOULD NEVER HAPPEN. */ - lp->stats.tx_aborted_errors++; + dev->stats.tx_aborted_errors++; printk(CARDNAME": Bad Craziness - sent packet while busy.\n" ); return 1; } @@ -1065,7 +1052,6 @@ static int __init smc_probe(struct net_device *dev, int ioaddr) dev->hard_start_xmit = smc_wait_to_send_packet; dev->tx_timeout = smc_timeout; dev->watchdog_timeo = HZ/20; - dev->get_stats = smc_query_statistics; dev->set_multicast_list = smc_set_multicast_list; return 0; @@ -1199,7 +1185,6 @@ static void smc_timeout(struct net_device *dev) */ static void smc_rcv(struct net_device *dev) { - struct smc_local *lp = netdev_priv(dev); int ioaddr = dev->base_addr; int packet_number; word status; @@ -1243,13 +1228,13 @@ static void smc_rcv(struct net_device *dev) /* set multicast stats */ if ( status & RS_MULTICAST ) - lp->stats.multicast++; + dev->stats.multicast++; skb = dev_alloc_skb( packet_length + 5); if ( skb == NULL ) { printk(KERN_NOTICE CARDNAME ": Low memory, packet dropped.\n"); - lp->stats.rx_dropped++; + dev->stats.rx_dropped++; goto done; } @@ -1289,16 +1274,16 @@ static void smc_rcv(struct net_device *dev) skb->protocol = eth_type_trans(skb, dev ); netif_rx(skb); dev->last_rx = jiffies; - lp->stats.rx_packets++; - lp->stats.rx_bytes += packet_length; + dev->stats.rx_packets++; + dev->stats.rx_bytes += packet_length; } else { /* error ... */ - lp->stats.rx_errors++; + dev->stats.rx_errors++; - if ( status & RS_ALGNERR ) lp->stats.rx_frame_errors++; + if ( status & RS_ALGNERR ) dev->stats.rx_frame_errors++; if ( status & (RS_TOOSHORT | RS_TOOLONG ) ) - lp->stats.rx_length_errors++; - if ( status & RS_BADCRC) lp->stats.rx_crc_errors++; + dev->stats.rx_length_errors++; + if ( status & RS_BADCRC) dev->stats.rx_crc_errors++; } done: @@ -1346,12 +1331,12 @@ static void smc_tx( struct net_device * dev ) tx_status = inw( ioaddr + DATA_1 ); PRINTK3((CARDNAME": TX DONE STATUS: %4x \n", tx_status )); - lp->stats.tx_errors++; - if ( tx_status & TS_LOSTCAR ) lp->stats.tx_carrier_errors++; + dev->stats.tx_errors++; + if ( tx_status & TS_LOSTCAR ) dev->stats.tx_carrier_errors++; if ( tx_status & TS_LATCOL ) { printk(KERN_DEBUG CARDNAME ": Late collision occurred on last xmit.\n"); - lp->stats.tx_window_errors++; + dev->stats.tx_window_errors++; } #if 0 if ( tx_status & TS_16COL ) { ... } @@ -1446,10 +1431,10 @@ static irqreturn_t smc_interrupt(int irq, void * dev_id) SMC_SELECT_BANK( 0 ); card_stats = inw( ioaddr + COUNTER ); /* single collisions */ - lp->stats.collisions += card_stats & 0xF; + dev->stats.collisions += card_stats & 0xF; card_stats >>= 4; /* multiple collisions */ - lp->stats.collisions += card_stats & 0xF; + dev->stats.collisions += card_stats & 0xF; /* these are for when linux supports these statistics */ @@ -1458,7 +1443,7 @@ static irqreturn_t smc_interrupt(int irq, void * dev_id) ": TX_BUFFER_EMPTY handled\n")); outb( IM_TX_EMPTY_INT, ioaddr + INTERRUPT ); mask &= ~IM_TX_EMPTY_INT; - lp->stats.tx_packets += lp->packets_waiting; + dev->stats.tx_packets += lp->packets_waiting; lp->packets_waiting = 0; } else if (status & IM_ALLOC_INT ) { @@ -1477,8 +1462,8 @@ static irqreturn_t smc_interrupt(int irq, void * dev_id) PRINTK2((CARDNAME": Handoff done successfully.\n")); } else if (status & IM_RX_OVRN_INT ) { - lp->stats.rx_errors++; - lp->stats.rx_fifo_errors++; + dev->stats.rx_errors++; + dev->stats.rx_fifo_errors++; outb( IM_RX_OVRN_INT, ioaddr + INTERRUPT ); } else if (status & IM_EPH_INT ) { PRINTK((CARDNAME ": UNSUPPORTED: EPH INTERRUPT \n")); @@ -1521,16 +1506,6 @@ static int smc_close(struct net_device *dev) return 0; } -/*------------------------------------------------------------ - . Get the current statistics. - . This may be called with the card open or closed. - .-------------------------------------------------------------*/ -static struct net_device_stats* smc_query_statistics(struct net_device *dev) { - struct smc_local *lp = netdev_priv(dev); - - return &lp->stats; -} - /*----------------------------------------------------------- . smc_set_multicast_list . diff --git a/drivers/net/smc91x.c b/drivers/net/smc91x.c index c5837ab5c96b..fe28d277f21a 100644 --- a/drivers/net/smc91x.c +++ b/drivers/net/smc91x.c @@ -183,13 +183,6 @@ struct smc_local { struct sk_buff *pending_tx_skb; struct tasklet_struct tx_task; - /* - * these are things that the kernel wants me to keep, so users - * can find out semi-useless statistics of how well the card is - * performing - */ - struct net_device_stats stats; - /* version/revision of the SMC91x chip */ int version; @@ -332,8 +325,8 @@ static void smc_reset(struct net_device *dev) /* free any pending tx skb */ if (pending_skb) { dev_kfree_skb(pending_skb); - lp->stats.tx_errors++; - lp->stats.tx_aborted_errors++; + dev->stats.tx_errors++; + dev->stats.tx_aborted_errors++; } /* @@ -512,13 +505,13 @@ static inline void smc_rcv(struct net_device *dev) } SMC_WAIT_MMU_BUSY(); SMC_SET_MMU_CMD(MC_RELEASE); - lp->stats.rx_errors++; + dev->stats.rx_errors++; if (status & RS_ALGNERR) - lp->stats.rx_frame_errors++; + dev->stats.rx_frame_errors++; if (status & (RS_TOOSHORT | RS_TOOLONG)) - lp->stats.rx_length_errors++; + dev->stats.rx_length_errors++; if (status & RS_BADCRC) - lp->stats.rx_crc_errors++; + dev->stats.rx_crc_errors++; } else { struct sk_buff *skb; unsigned char *data; @@ -526,7 +519,7 @@ static inline void smc_rcv(struct net_device *dev) /* set multicast stats */ if (status & RS_MULTICAST) - lp->stats.multicast++; + dev->stats.multicast++; /* * Actual payload is packet_len - 6 (or 5 if odd byte). @@ -542,7 +535,7 @@ static inline void smc_rcv(struct net_device *dev) dev->name); SMC_WAIT_MMU_BUSY(); SMC_SET_MMU_CMD(MC_RELEASE); - lp->stats.rx_dropped++; + dev->stats.rx_dropped++; return; } @@ -570,8 +563,8 @@ static inline void smc_rcv(struct net_device *dev) dev->last_rx = jiffies; skb->protocol = eth_type_trans(skb, dev); netif_rx(skb); - lp->stats.rx_packets++; - lp->stats.rx_bytes += data_len; + dev->stats.rx_packets++; + dev->stats.rx_bytes += data_len; } } @@ -644,8 +637,8 @@ static void smc_hardware_send_pkt(unsigned long data) packet_no = SMC_GET_AR(); if (unlikely(packet_no & AR_FAILED)) { printk("%s: Memory allocation failed.\n", dev->name); - lp->stats.tx_errors++; - lp->stats.tx_fifo_errors++; + dev->stats.tx_errors++; + dev->stats.tx_fifo_errors++; smc_special_unlock(&lp->lock); goto done; } @@ -688,8 +681,8 @@ static void smc_hardware_send_pkt(unsigned long data) smc_special_unlock(&lp->lock); dev->trans_start = jiffies; - lp->stats.tx_packets++; - lp->stats.tx_bytes += len; + dev->stats.tx_packets++; + dev->stats.tx_bytes += len; SMC_ENABLE_INT(IM_TX_INT | IM_TX_EMPTY_INT); @@ -729,8 +722,8 @@ static int smc_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) numPages = ((skb->len & ~1) + (6 - 1)) >> 8; if (unlikely(numPages > 7)) { printk("%s: Far too big packet error.\n", dev->name); - lp->stats.tx_errors++; - lp->stats.tx_dropped++; + dev->stats.tx_errors++; + dev->stats.tx_dropped++; dev_kfree_skb(skb); return 0; } @@ -803,17 +796,17 @@ static void smc_tx(struct net_device *dev) dev->name, tx_status, packet_no); if (!(tx_status & ES_TX_SUC)) - lp->stats.tx_errors++; + dev->stats.tx_errors++; if (tx_status & ES_LOSTCARR) - lp->stats.tx_carrier_errors++; + dev->stats.tx_carrier_errors++; if (tx_status & (ES_LATCOL | ES_16COL)) { PRINTK("%s: %s occurred on last xmit\n", dev->name, (tx_status & ES_LATCOL) ? "late collision" : "too many collisions"); - lp->stats.tx_window_errors++; - if (!(lp->stats.tx_window_errors & 63) && net_ratelimit()) { + dev->stats.tx_window_errors++; + if (!(dev->stats.tx_window_errors & 63) && net_ratelimit()) { printk(KERN_INFO "%s: unexpectedly large number of " "bad collisions. Please check duplex " "setting.\n", dev->name); @@ -1347,19 +1340,19 @@ static irqreturn_t smc_interrupt(int irq, void *dev_id) SMC_SELECT_BANK(2); /* single collisions */ - lp->stats.collisions += card_stats & 0xF; + dev->stats.collisions += card_stats & 0xF; card_stats >>= 4; /* multiple collisions */ - lp->stats.collisions += card_stats & 0xF; + dev->stats.collisions += card_stats & 0xF; } else if (status & IM_RX_OVRN_INT) { DBG(1, "%s: RX overrun (EPH_ST 0x%04x)\n", dev->name, ({ int eph_st; SMC_SELECT_BANK(0); eph_st = SMC_GET_EPH_STATUS(); SMC_SELECT_BANK(2); eph_st; }) ); SMC_ACK_INT(IM_RX_OVRN_INT); - lp->stats.rx_errors++; - lp->stats.rx_fifo_errors++; + dev->stats.rx_errors++; + dev->stats.rx_fifo_errors++; } else if (status & IM_EPH_INT) { smc_eph_interrupt(dev); } else if (status & IM_MDINT) { @@ -1627,19 +1620,6 @@ static int smc_close(struct net_device *dev) return 0; } -/* - * Get the current statistics. - * This may be called with the card open or closed. - */ -static struct net_device_stats *smc_query_statistics(struct net_device *dev) -{ - struct smc_local *lp = netdev_priv(dev); - - DBG(2, "%s: %s\n", dev->name, __FUNCTION__); - - return &lp->stats; -} - /* * Ethtool support */ @@ -1965,7 +1945,6 @@ static int __init smc_probe(struct net_device *dev, void __iomem *ioaddr) dev->hard_start_xmit = smc_hard_start_xmit; dev->tx_timeout = smc_timeout; dev->watchdog_timeo = msecs_to_jiffies(watchdog); - dev->get_stats = smc_query_statistics; dev->set_multicast_list = smc_set_multicast_list; dev->ethtool_ops = &smc_ethtool_ops; #ifdef CONFIG_NET_POLL_CONTROLLER diff --git a/drivers/net/spider_net.c b/drivers/net/spider_net.c index edc736eb3b86..fab055ffcc90 100644 --- a/drivers/net/spider_net.c +++ b/drivers/net/spider_net.c @@ -795,6 +795,7 @@ spider_net_set_low_watermark(struct spider_net_card *card) static int spider_net_release_tx_chain(struct spider_net_card *card, int brutal) { + struct net_device *dev = card->netdev; struct spider_net_descr_chain *chain = &card->tx_chain; struct spider_net_descr *descr; struct spider_net_hw_descr *hwdescr; @@ -815,8 +816,8 @@ spider_net_release_tx_chain(struct spider_net_card *card, int brutal) status = spider_net_get_descr_status(hwdescr); switch (status) { case SPIDER_NET_DESCR_COMPLETE: - card->netdev_stats.tx_packets++; - card->netdev_stats.tx_bytes += descr->skb->len; + dev->stats.tx_packets++; + dev->stats.tx_bytes += descr->skb->len; break; case SPIDER_NET_DESCR_CARDOWNED: @@ -835,11 +836,11 @@ spider_net_release_tx_chain(struct spider_net_card *card, int brutal) if (netif_msg_tx_err(card)) dev_err(&card->netdev->dev, "forcing end of tx descriptor " "with status x%02x\n", status); - card->netdev_stats.tx_errors++; + dev->stats.tx_errors++; break; default: - card->netdev_stats.tx_dropped++; + dev->stats.tx_dropped++; if (!brutal) { spin_unlock_irqrestore(&chain->lock, flags); return 1; @@ -919,7 +920,7 @@ spider_net_xmit(struct sk_buff *skb, struct net_device *netdev) spider_net_release_tx_chain(card, 0); if (spider_net_prepare_tx_descr(card, skb) != 0) { - card->netdev_stats.tx_dropped++; + netdev->stats.tx_dropped++; netif_stop_queue(netdev); return NETDEV_TX_BUSY; } @@ -979,16 +980,12 @@ static void spider_net_pass_skb_up(struct spider_net_descr *descr, struct spider_net_card *card) { - struct spider_net_hw_descr *hwdescr= descr->hwdescr; - struct sk_buff *skb; - struct net_device *netdev; - u32 data_status, data_error; - - data_status = hwdescr->data_status; - data_error = hwdescr->data_error; - netdev = card->netdev; + struct spider_net_hw_descr *hwdescr = descr->hwdescr; + struct sk_buff *skb = descr->skb; + struct net_device *netdev = card->netdev; + u32 data_status = hwdescr->data_status; + u32 data_error = hwdescr->data_error; - skb = descr->skb; skb_put(skb, hwdescr->valid_size); /* the card seems to add 2 bytes of junk in front @@ -1015,8 +1012,8 @@ spider_net_pass_skb_up(struct spider_net_descr *descr, } /* update netdevice statistics */ - card->netdev_stats.rx_packets++; - card->netdev_stats.rx_bytes += skb->len; + netdev->stats.rx_packets++; + netdev->stats.rx_bytes += skb->len; /* pass skb up to stack */ netif_receive_skb(skb); @@ -1184,6 +1181,7 @@ static int spider_net_resync_tail_ptr(struct spider_net_card *card) static int spider_net_decode_one_descr(struct spider_net_card *card) { + struct net_device *dev = card->netdev; struct spider_net_descr_chain *chain = &card->rx_chain; struct spider_net_descr *descr = chain->tail; struct spider_net_hw_descr *hwdescr = descr->hwdescr; @@ -1210,9 +1208,9 @@ spider_net_decode_one_descr(struct spider_net_card *card) (status == SPIDER_NET_DESCR_PROTECTION_ERROR) || (status == SPIDER_NET_DESCR_FORCE_END) ) { if (netif_msg_rx_err(card)) - dev_err(&card->netdev->dev, + dev_err(&dev->dev, "dropping RX descriptor with state %d\n", status); - card->netdev_stats.rx_dropped++; + dev->stats.rx_dropped++; goto bad_desc; } @@ -1314,20 +1312,6 @@ static int spider_net_poll(struct napi_struct *napi, int budget) return packets_done; } -/** - * spider_net_get_stats - get interface statistics - * @netdev: interface device structure - * - * returns the interface statistics residing in the spider_net_card struct - */ -static struct net_device_stats * -spider_net_get_stats(struct net_device *netdev) -{ - struct spider_net_card *card = netdev_priv(netdev); - struct net_device_stats *stats = &card->netdev_stats; - return stats; -} - /** * spider_net_change_mtu - changes the MTU of an interface * @netdev: interface device structure @@ -2290,7 +2274,6 @@ spider_net_setup_netdev_ops(struct net_device *netdev) netdev->open = &spider_net_open; netdev->stop = &spider_net_stop; netdev->hard_start_xmit = &spider_net_xmit; - netdev->get_stats = &spider_net_get_stats; netdev->set_multicast_list = &spider_net_set_multi; netdev->set_mac_address = &spider_net_set_mac; netdev->change_mtu = &spider_net_change_mtu; diff --git a/drivers/net/spider_net.h b/drivers/net/spider_net.h index a2fcdebc3790..a897beee7d5d 100644 --- a/drivers/net/spider_net.h +++ b/drivers/net/spider_net.h @@ -487,7 +487,6 @@ struct spider_net_card { /* for ethtool */ int msg_enable; - struct net_device_stats netdev_stats; struct spider_net_extra_stats spider_stats; struct spider_net_options options; diff --git a/drivers/net/sun3lance.c b/drivers/net/sun3lance.c index c67632dcac49..f8fbc0492706 100644 --- a/drivers/net/sun3lance.c +++ b/drivers/net/sun3lance.c @@ -152,7 +152,6 @@ struct lance_private { struct lance_memory *mem; int new_rx, new_tx; /* The next free ring entry */ int old_tx, old_rx; /* ring entry to be processed */ - struct net_device_stats stats; /* These two must be longs for set_bit() */ long tx_full; long lock; @@ -241,7 +240,6 @@ static int lance_start_xmit( struct sk_buff *skb, struct net_device *dev ); static irqreturn_t lance_interrupt( int irq, void *dev_id); static int lance_rx( struct net_device *dev ); static int lance_close( struct net_device *dev ); -static struct net_device_stats *lance_get_stats( struct net_device *dev ); static void set_multicast_list( struct net_device *dev ); /************************* End of Prototypes **************************/ @@ -401,15 +399,12 @@ static int __init lance_probe( struct net_device *dev) dev->open = &lance_open; dev->hard_start_xmit = &lance_start_xmit; dev->stop = &lance_close; - dev->get_stats = &lance_get_stats; dev->set_multicast_list = &set_multicast_list; dev->set_mac_address = NULL; // KLUDGE -- REMOVE ME set_bit(__LINK_STATE_PRESENT, &dev->state); - memset( &lp->stats, 0, sizeof(lp->stats) ); - return 1; } @@ -534,7 +529,7 @@ static int lance_start_xmit( struct sk_buff *skb, struct net_device *dev ) * little endian mode. */ REGA(CSR3) = CSR3_BSWP; - lp->stats.tx_errors++; + dev->stats.tx_errors++; if(lance_debug >= 2) { int i; @@ -634,7 +629,7 @@ static int lance_start_xmit( struct sk_buff *skb, struct net_device *dev ) head->flag = TMD1_OWN_CHIP | TMD1_ENP | TMD1_STP; lp->new_tx = (lp->new_tx + 1) & TX_RING_MOD_MASK; - lp->stats.tx_bytes += skb->len; + dev->stats.tx_bytes += skb->len; /* Trigger an immediate send poll. */ REGA(CSR0) = CSR0_INEA | CSR0_TDMD | CSR0_STRT; @@ -712,12 +707,12 @@ static irqreturn_t lance_interrupt( int irq, void *dev_id) if (head->flag & TMD1_ERR) { int status = head->misc; - lp->stats.tx_errors++; - if (status & TMD3_RTRY) lp->stats.tx_aborted_errors++; - if (status & TMD3_LCAR) lp->stats.tx_carrier_errors++; - if (status & TMD3_LCOL) lp->stats.tx_window_errors++; + dev->stats.tx_errors++; + if (status & TMD3_RTRY) dev->stats.tx_aborted_errors++; + if (status & TMD3_LCAR) dev->stats.tx_carrier_errors++; + if (status & TMD3_LCOL) dev->stats.tx_window_errors++; if (status & (TMD3_UFLO | TMD3_BUFF)) { - lp->stats.tx_fifo_errors++; + dev->stats.tx_fifo_errors++; printk("%s: Tx FIFO error\n", dev->name); REGA(CSR0) = CSR0_STOP; @@ -730,9 +725,9 @@ static irqreturn_t lance_interrupt( int irq, void *dev_id) head->flag &= ~(TMD1_ENP | TMD1_STP); if(head->flag & (TMD1_ONE | TMD1_MORE)) - lp->stats.collisions++; + dev->stats.collisions++; - lp->stats.tx_packets++; + dev->stats.tx_packets++; DPRINTK(3, ("cleared tx ring %d\n", old_tx)); } old_tx = (old_tx +1) & TX_RING_MOD_MASK; @@ -752,8 +747,8 @@ static irqreturn_t lance_interrupt( int irq, void *dev_id) lance_rx( dev ); /* Log misc errors. */ - if (csr0 & CSR0_BABL) lp->stats.tx_errors++; /* Tx babble. */ - if (csr0 & CSR0_MISS) lp->stats.rx_errors++; /* Missed a Rx frame. */ + if (csr0 & CSR0_BABL) dev->stats.tx_errors++; /* Tx babble. */ + if (csr0 & CSR0_MISS) dev->stats.rx_errors++; /* Missed a Rx frame. */ if (csr0 & CSR0_MERR) { DPRINTK( 1, ( "%s: Bus master arbitration failure (?!?), " "status %04x.\n", dev->name, csr0 )); @@ -799,11 +794,11 @@ static int lance_rx( struct net_device *dev ) full-sized buffers it's possible for a jabber packet to use two buffers, with only the last correctly noting the error. */ if (status & RMD1_ENP) /* Only count a general error at the */ - lp->stats.rx_errors++; /* end of a packet.*/ - if (status & RMD1_FRAM) lp->stats.rx_frame_errors++; - if (status & RMD1_OFLO) lp->stats.rx_over_errors++; - if (status & RMD1_CRC) lp->stats.rx_crc_errors++; - if (status & RMD1_BUFF) lp->stats.rx_fifo_errors++; + dev->stats.rx_errors++; /* end of a packet.*/ + if (status & RMD1_FRAM) dev->stats.rx_frame_errors++; + if (status & RMD1_OFLO) dev->stats.rx_over_errors++; + if (status & RMD1_CRC) dev->stats.rx_crc_errors++; + if (status & RMD1_BUFF) dev->stats.rx_fifo_errors++; head->flag &= (RMD1_ENP|RMD1_STP); } else { /* Malloc up new buffer, compatible with net-3. */ @@ -813,7 +808,7 @@ static int lance_rx( struct net_device *dev ) if (pkt_len < 60) { printk( "%s: Runt packet!\n", dev->name ); - lp->stats.rx_errors++; + dev->stats.rx_errors++; } else { skb = dev_alloc_skb( pkt_len+2 ); @@ -821,7 +816,7 @@ static int lance_rx( struct net_device *dev ) DPRINTK( 1, ( "%s: Memory squeeze, deferring packet.\n", dev->name )); - lp->stats.rx_dropped++; + dev->stats.rx_dropped++; head->msg_length = 0; head->flag |= RMD1_OWN_CHIP; lp->new_rx = (lp->new_rx+1) & @@ -859,8 +854,8 @@ static int lance_rx( struct net_device *dev ) skb->protocol = eth_type_trans( skb, dev ); netif_rx( skb ); dev->last_rx = jiffies; - lp->stats.rx_packets++; - lp->stats.rx_bytes += pkt_len; + dev->stats.rx_packets++; + dev->stats.rx_bytes += pkt_len; } } @@ -897,14 +892,6 @@ static int lance_close( struct net_device *dev ) } -static struct net_device_stats *lance_get_stats( struct net_device *dev ) -{ - struct lance_private *lp = netdev_priv(dev); - - return &lp->stats; -} - - /* Set or clear the multicast filter for this adaptor. num_addrs == -1 Promiscuous mode, receive all packets num_addrs == 0 Normal mode, clear multicast list diff --git a/drivers/net/sunlance.c b/drivers/net/sunlance.c index 17d66c1185cd..7bf5c90b7749 100644 --- a/drivers/net/sunlance.c +++ b/drivers/net/sunlance.c @@ -248,7 +248,6 @@ struct lance_private { int rx_new, tx_new; int rx_old, tx_old; - struct net_device_stats stats; struct sbus_dma *ledma; /* If set this points to ledma */ char tpe; /* cable-selection is TPE */ char auto_select; /* cable-selection by carrier */ @@ -519,17 +518,17 @@ static void lance_rx_dvma(struct net_device *dev) /* We got an incomplete frame? */ if ((bits & LE_R1_POK) != LE_R1_POK) { - lp->stats.rx_over_errors++; - lp->stats.rx_errors++; + dev->stats.rx_over_errors++; + dev->stats.rx_errors++; } else if (bits & LE_R1_ERR) { /* Count only the end frame as a rx error, * not the beginning */ - if (bits & LE_R1_BUF) lp->stats.rx_fifo_errors++; - if (bits & LE_R1_CRC) lp->stats.rx_crc_errors++; - if (bits & LE_R1_OFL) lp->stats.rx_over_errors++; - if (bits & LE_R1_FRA) lp->stats.rx_frame_errors++; - if (bits & LE_R1_EOP) lp->stats.rx_errors++; + if (bits & LE_R1_BUF) dev->stats.rx_fifo_errors++; + if (bits & LE_R1_CRC) dev->stats.rx_crc_errors++; + if (bits & LE_R1_OFL) dev->stats.rx_over_errors++; + if (bits & LE_R1_FRA) dev->stats.rx_frame_errors++; + if (bits & LE_R1_EOP) dev->stats.rx_errors++; } else { len = (rd->mblength & 0xfff) - 4; skb = dev_alloc_skb(len + 2); @@ -537,14 +536,14 @@ static void lance_rx_dvma(struct net_device *dev) if (skb == NULL) { printk(KERN_INFO "%s: Memory squeeze, deferring packet.\n", dev->name); - lp->stats.rx_dropped++; + dev->stats.rx_dropped++; rd->mblength = 0; rd->rmd1_bits = LE_R1_OWN; lp->rx_new = RX_NEXT(entry); return; } - lp->stats.rx_bytes += len; + dev->stats.rx_bytes += len; skb_reserve(skb, 2); /* 16 byte align */ skb_put(skb, len); /* make room */ @@ -554,7 +553,7 @@ static void lance_rx_dvma(struct net_device *dev) skb->protocol = eth_type_trans(skb, dev); netif_rx(skb); dev->last_rx = jiffies; - lp->stats.rx_packets++; + dev->stats.rx_packets++; } /* Return the packet to the pool */ @@ -586,12 +585,12 @@ static void lance_tx_dvma(struct net_device *dev) if (bits & LE_T1_ERR) { u16 status = td->misc; - lp->stats.tx_errors++; - if (status & LE_T3_RTY) lp->stats.tx_aborted_errors++; - if (status & LE_T3_LCOL) lp->stats.tx_window_errors++; + dev->stats.tx_errors++; + if (status & LE_T3_RTY) dev->stats.tx_aborted_errors++; + if (status & LE_T3_LCOL) dev->stats.tx_window_errors++; if (status & LE_T3_CLOS) { - lp->stats.tx_carrier_errors++; + dev->stats.tx_carrier_errors++; if (lp->auto_select) { lp->tpe = 1 - lp->tpe; printk(KERN_NOTICE "%s: Carrier Lost, trying %s\n", @@ -608,7 +607,7 @@ static void lance_tx_dvma(struct net_device *dev) * transmitter, restart the adapter. */ if (status & (LE_T3_BUF|LE_T3_UFL)) { - lp->stats.tx_fifo_errors++; + dev->stats.tx_fifo_errors++; printk(KERN_ERR "%s: Tx: ERR_BUF|ERR_UFL, restarting\n", dev->name); @@ -626,13 +625,13 @@ static void lance_tx_dvma(struct net_device *dev) /* One collision before packet was sent. */ if (bits & LE_T1_EONE) - lp->stats.collisions++; + dev->stats.collisions++; /* More than one collision, be optimistic. */ if (bits & LE_T1_EMORE) - lp->stats.collisions += 2; + dev->stats.collisions += 2; - lp->stats.tx_packets++; + dev->stats.tx_packets++; } j = TX_NEXT(j); @@ -692,17 +691,17 @@ static void lance_rx_pio(struct net_device *dev) /* We got an incomplete frame? */ if ((bits & LE_R1_POK) != LE_R1_POK) { - lp->stats.rx_over_errors++; - lp->stats.rx_errors++; + dev->stats.rx_over_errors++; + dev->stats.rx_errors++; } else if (bits & LE_R1_ERR) { /* Count only the end frame as a rx error, * not the beginning */ - if (bits & LE_R1_BUF) lp->stats.rx_fifo_errors++; - if (bits & LE_R1_CRC) lp->stats.rx_crc_errors++; - if (bits & LE_R1_OFL) lp->stats.rx_over_errors++; - if (bits & LE_R1_FRA) lp->stats.rx_frame_errors++; - if (bits & LE_R1_EOP) lp->stats.rx_errors++; + if (bits & LE_R1_BUF) dev->stats.rx_fifo_errors++; + if (bits & LE_R1_CRC) dev->stats.rx_crc_errors++; + if (bits & LE_R1_OFL) dev->stats.rx_over_errors++; + if (bits & LE_R1_FRA) dev->stats.rx_frame_errors++; + if (bits & LE_R1_EOP) dev->stats.rx_errors++; } else { len = (sbus_readw(&rd->mblength) & 0xfff) - 4; skb = dev_alloc_skb(len + 2); @@ -710,14 +709,14 @@ static void lance_rx_pio(struct net_device *dev) if (skb == NULL) { printk(KERN_INFO "%s: Memory squeeze, deferring packet.\n", dev->name); - lp->stats.rx_dropped++; + dev->stats.rx_dropped++; sbus_writew(0, &rd->mblength); sbus_writeb(LE_R1_OWN, &rd->rmd1_bits); lp->rx_new = RX_NEXT(entry); return; } - lp->stats.rx_bytes += len; + dev->stats.rx_bytes += len; skb_reserve (skb, 2); /* 16 byte align */ skb_put(skb, len); /* make room */ @@ -725,7 +724,7 @@ static void lance_rx_pio(struct net_device *dev) skb->protocol = eth_type_trans(skb, dev); netif_rx(skb); dev->last_rx = jiffies; - lp->stats.rx_packets++; + dev->stats.rx_packets++; } /* Return the packet to the pool */ @@ -757,12 +756,12 @@ static void lance_tx_pio(struct net_device *dev) if (bits & LE_T1_ERR) { u16 status = sbus_readw(&td->misc); - lp->stats.tx_errors++; - if (status & LE_T3_RTY) lp->stats.tx_aborted_errors++; - if (status & LE_T3_LCOL) lp->stats.tx_window_errors++; + dev->stats.tx_errors++; + if (status & LE_T3_RTY) dev->stats.tx_aborted_errors++; + if (status & LE_T3_LCOL) dev->stats.tx_window_errors++; if (status & LE_T3_CLOS) { - lp->stats.tx_carrier_errors++; + dev->stats.tx_carrier_errors++; if (lp->auto_select) { lp->tpe = 1 - lp->tpe; printk(KERN_NOTICE "%s: Carrier Lost, trying %s\n", @@ -779,7 +778,7 @@ static void lance_tx_pio(struct net_device *dev) * transmitter, restart the adapter. */ if (status & (LE_T3_BUF|LE_T3_UFL)) { - lp->stats.tx_fifo_errors++; + dev->stats.tx_fifo_errors++; printk(KERN_ERR "%s: Tx: ERR_BUF|ERR_UFL, restarting\n", dev->name); @@ -797,13 +796,13 @@ static void lance_tx_pio(struct net_device *dev) /* One collision before packet was sent. */ if (bits & LE_T1_EONE) - lp->stats.collisions++; + dev->stats.collisions++; /* More than one collision, be optimistic. */ if (bits & LE_T1_EMORE) - lp->stats.collisions += 2; + dev->stats.collisions += 2; - lp->stats.tx_packets++; + dev->stats.tx_packets++; } j = TX_NEXT(j); @@ -844,10 +843,10 @@ static irqreturn_t lance_interrupt(int irq, void *dev_id) lp->tx(dev); if (csr0 & LE_C0_BABL) - lp->stats.tx_errors++; + dev->stats.tx_errors++; if (csr0 & LE_C0_MISS) - lp->stats.rx_errors++; + dev->stats.rx_errors++; if (csr0 & LE_C0_MERR) { if (lp->dregs) { @@ -1127,7 +1126,7 @@ static int lance_start_xmit(struct sk_buff *skb, struct net_device *dev) spin_lock_irq(&lp->lock); - lp->stats.tx_bytes += len; + dev->stats.tx_bytes += len; entry = lp->tx_new & TX_RING_MOD_MASK; if (lp->pio_buffer) { @@ -1170,13 +1169,6 @@ static int lance_start_xmit(struct sk_buff *skb, struct net_device *dev) return 0; } -static struct net_device_stats *lance_get_stats(struct net_device *dev) -{ - struct lance_private *lp = netdev_priv(dev); - - return &lp->stats; -} - /* taken from the depca driver */ static void lance_load_multicast(struct net_device *dev) { @@ -1463,7 +1455,6 @@ no_link_test: dev->hard_start_xmit = &lance_start_xmit; dev->tx_timeout = &lance_tx_timeout; dev->watchdog_timeo = 5*HZ; - dev->get_stats = &lance_get_stats; dev->set_multicast_list = &lance_set_multicast; dev->ethtool_ops = &sparc_lance_ethtool_ops; diff --git a/drivers/net/sunqe.c b/drivers/net/sunqe.c index b5c2974fd625..ff23c6489efd 100644 --- a/drivers/net/sunqe.c +++ b/drivers/net/sunqe.c @@ -260,31 +260,31 @@ static int qe_is_bolixed(struct sunqe *qep, u32 qe_status) if (qe_status & CREG_STAT_EDEFER) { printk(KERN_ERR "%s: Excessive transmit defers.\n", dev->name); - qep->net_stats.tx_errors++; + dev->stats.tx_errors++; } if (qe_status & CREG_STAT_CLOSS) { printk(KERN_ERR "%s: Carrier lost, link down?\n", dev->name); - qep->net_stats.tx_errors++; - qep->net_stats.tx_carrier_errors++; + dev->stats.tx_errors++; + dev->stats.tx_carrier_errors++; } if (qe_status & CREG_STAT_ERETRIES) { printk(KERN_ERR "%s: Excessive transmit retries (more than 16).\n", dev->name); - qep->net_stats.tx_errors++; + dev->stats.tx_errors++; mace_hwbug_workaround = 1; } if (qe_status & CREG_STAT_LCOLL) { printk(KERN_ERR "%s: Late transmit collision.\n", dev->name); - qep->net_stats.tx_errors++; - qep->net_stats.collisions++; + dev->stats.tx_errors++; + dev->stats.collisions++; mace_hwbug_workaround = 1; } if (qe_status & CREG_STAT_FUFLOW) { printk(KERN_ERR "%s: Transmit fifo underflow, driver bug.\n", dev->name); - qep->net_stats.tx_errors++; + dev->stats.tx_errors++; mace_hwbug_workaround = 1; } @@ -297,104 +297,104 @@ static int qe_is_bolixed(struct sunqe *qep, u32 qe_status) } if (qe_status & CREG_STAT_CCOFLOW) { - qep->net_stats.tx_errors += 256; - qep->net_stats.collisions += 256; + dev->stats.tx_errors += 256; + dev->stats.collisions += 256; } if (qe_status & CREG_STAT_TXDERROR) { printk(KERN_ERR "%s: Transmit descriptor is bogus, driver bug.\n", dev->name); - qep->net_stats.tx_errors++; - qep->net_stats.tx_aborted_errors++; + dev->stats.tx_errors++; + dev->stats.tx_aborted_errors++; mace_hwbug_workaround = 1; } if (qe_status & CREG_STAT_TXLERR) { printk(KERN_ERR "%s: Transmit late error.\n", dev->name); - qep->net_stats.tx_errors++; + dev->stats.tx_errors++; mace_hwbug_workaround = 1; } if (qe_status & CREG_STAT_TXPERR) { printk(KERN_ERR "%s: Transmit DMA parity error.\n", dev->name); - qep->net_stats.tx_errors++; - qep->net_stats.tx_aborted_errors++; + dev->stats.tx_errors++; + dev->stats.tx_aborted_errors++; mace_hwbug_workaround = 1; } if (qe_status & CREG_STAT_TXSERR) { printk(KERN_ERR "%s: Transmit DMA sbus error ack.\n", dev->name); - qep->net_stats.tx_errors++; - qep->net_stats.tx_aborted_errors++; + dev->stats.tx_errors++; + dev->stats.tx_aborted_errors++; mace_hwbug_workaround = 1; } if (qe_status & CREG_STAT_RCCOFLOW) { - qep->net_stats.rx_errors += 256; - qep->net_stats.collisions += 256; + dev->stats.rx_errors += 256; + dev->stats.collisions += 256; } if (qe_status & CREG_STAT_RUOFLOW) { - qep->net_stats.rx_errors += 256; - qep->net_stats.rx_over_errors += 256; + dev->stats.rx_errors += 256; + dev->stats.rx_over_errors += 256; } if (qe_status & CREG_STAT_MCOFLOW) { - qep->net_stats.rx_errors += 256; - qep->net_stats.rx_missed_errors += 256; + dev->stats.rx_errors += 256; + dev->stats.rx_missed_errors += 256; } if (qe_status & CREG_STAT_RXFOFLOW) { printk(KERN_ERR "%s: Receive fifo overflow.\n", dev->name); - qep->net_stats.rx_errors++; - qep->net_stats.rx_over_errors++; + dev->stats.rx_errors++; + dev->stats.rx_over_errors++; } if (qe_status & CREG_STAT_RLCOLL) { printk(KERN_ERR "%s: Late receive collision.\n", dev->name); - qep->net_stats.rx_errors++; - qep->net_stats.collisions++; + dev->stats.rx_errors++; + dev->stats.collisions++; } if (qe_status & CREG_STAT_FCOFLOW) { - qep->net_stats.rx_errors += 256; - qep->net_stats.rx_frame_errors += 256; + dev->stats.rx_errors += 256; + dev->stats.rx_frame_errors += 256; } if (qe_status & CREG_STAT_CECOFLOW) { - qep->net_stats.rx_errors += 256; - qep->net_stats.rx_crc_errors += 256; + dev->stats.rx_errors += 256; + dev->stats.rx_crc_errors += 256; } if (qe_status & CREG_STAT_RXDROP) { printk(KERN_ERR "%s: Receive packet dropped.\n", dev->name); - qep->net_stats.rx_errors++; - qep->net_stats.rx_dropped++; - qep->net_stats.rx_missed_errors++; + dev->stats.rx_errors++; + dev->stats.rx_dropped++; + dev->stats.rx_missed_errors++; } if (qe_status & CREG_STAT_RXSMALL) { printk(KERN_ERR "%s: Receive buffer too small, driver bug.\n", dev->name); - qep->net_stats.rx_errors++; - qep->net_stats.rx_length_errors++; + dev->stats.rx_errors++; + dev->stats.rx_length_errors++; } if (qe_status & CREG_STAT_RXLERR) { printk(KERN_ERR "%s: Receive late error.\n", dev->name); - qep->net_stats.rx_errors++; + dev->stats.rx_errors++; mace_hwbug_workaround = 1; } if (qe_status & CREG_STAT_RXPERR) { printk(KERN_ERR "%s: Receive DMA parity error.\n", dev->name); - qep->net_stats.rx_errors++; - qep->net_stats.rx_missed_errors++; + dev->stats.rx_errors++; + dev->stats.rx_missed_errors++; mace_hwbug_workaround = 1; } if (qe_status & CREG_STAT_RXSERR) { printk(KERN_ERR "%s: Receive DMA sbus error ack.\n", dev->name); - qep->net_stats.rx_errors++; - qep->net_stats.rx_missed_errors++; + dev->stats.rx_errors++; + dev->stats.rx_missed_errors++; mace_hwbug_workaround = 1; } @@ -409,6 +409,7 @@ static int qe_is_bolixed(struct sunqe *qep, u32 qe_status) static void qe_rx(struct sunqe *qep) { struct qe_rxd *rxbase = &qep->qe_block->qe_rxd[0]; + struct net_device *dev = qep->dev; struct qe_rxd *this; struct sunqe_buffers *qbufs = qep->buffers; __u32 qbufs_dvma = qep->buffers_dvma; @@ -428,14 +429,14 @@ static void qe_rx(struct sunqe *qep) /* Check for errors. */ if (len < ETH_ZLEN) { - qep->net_stats.rx_errors++; - qep->net_stats.rx_length_errors++; - qep->net_stats.rx_dropped++; + dev->stats.rx_errors++; + dev->stats.rx_length_errors++; + dev->stats.rx_dropped++; } else { skb = dev_alloc_skb(len + 2); if (skb == NULL) { drops++; - qep->net_stats.rx_dropped++; + dev->stats.rx_dropped++; } else { skb_reserve(skb, 2); skb_put(skb, len); @@ -444,8 +445,8 @@ static void qe_rx(struct sunqe *qep) skb->protocol = eth_type_trans(skb, qep->dev); netif_rx(skb); qep->dev->last_rx = jiffies; - qep->net_stats.rx_packets++; - qep->net_stats.rx_bytes += len; + dev->stats.rx_packets++; + dev->stats.rx_bytes += len; } } end_rxd->rx_addr = this_qbuf_dvma; @@ -603,8 +604,8 @@ static int qe_start_xmit(struct sk_buff *skb, struct net_device *dev) dev->trans_start = jiffies; sbus_writel(CREG_CTRL_TWAKEUP, qep->qcregs + CREG_CTRL); - qep->net_stats.tx_packets++; - qep->net_stats.tx_bytes += len; + dev->stats.tx_packets++; + dev->stats.tx_bytes += len; if (TX_BUFFS_AVAIL(qep) <= 0) { /* Halt the net queue and enable tx interrupts. @@ -622,13 +623,6 @@ static int qe_start_xmit(struct sk_buff *skb, struct net_device *dev) return 0; } -static struct net_device_stats *qe_get_stats(struct net_device *dev) -{ - struct sunqe *qep = (struct sunqe *) dev->priv; - - return &qep->net_stats; -} - static void qe_set_multicast(struct net_device *dev) { struct sunqe *qep = (struct sunqe *) dev->priv; @@ -903,7 +897,6 @@ static int __init qec_ether_init(struct sbus_dev *sdev) dev->open = qe_open; dev->stop = qe_close; dev->hard_start_xmit = qe_start_xmit; - dev->get_stats = qe_get_stats; dev->set_multicast_list = qe_set_multicast; dev->tx_timeout = qe_tx_timeout; dev->watchdog_timeo = 5*HZ; diff --git a/drivers/net/sunqe.h b/drivers/net/sunqe.h index af34f36111ed..347c8ddc1592 100644 --- a/drivers/net/sunqe.h +++ b/drivers/net/sunqe.h @@ -342,7 +342,6 @@ struct sunqe { __u32 buffers_dvma; /* DVMA visible address. */ struct sunqec *parent; u8 mconfig; /* Base MACE mconfig value */ - struct net_device_stats net_stats; /* Statistical counters */ struct sbus_dev *qe_sdev; /* QE's SBUS device struct */ struct net_device *dev; /* QE's netdevice struct */ int channel; /* Who am I? */ diff --git a/drivers/net/tun.c b/drivers/net/tun.c index 8b3ec335385c..d279151f065d 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c @@ -110,7 +110,7 @@ static int tun_net_xmit(struct sk_buff *skb, struct net_device *dev) /* We won't see all dropped packets individually, so overrun * error is more appropriate. */ - tun->stats.tx_fifo_errors++; + dev->stats.tx_fifo_errors++; } else { /* Single queue mode. * Driver handles dropping of all packets itself. */ @@ -129,7 +129,7 @@ static int tun_net_xmit(struct sk_buff *skb, struct net_device *dev) return 0; drop: - tun->stats.tx_dropped++; + dev->stats.tx_dropped++; kfree_skb(skb); return 0; } @@ -172,12 +172,6 @@ tun_net_mclist(struct net_device *dev) } } -static struct net_device_stats *tun_net_stats(struct net_device *dev) -{ - struct tun_struct *tun = netdev_priv(dev); - return &tun->stats; -} - /* Initialize net device. */ static void tun_net_init(struct net_device *dev) { @@ -250,14 +244,14 @@ static __inline__ ssize_t tun_get_user(struct tun_struct *tun, struct iovec *iv, align = NET_IP_ALIGN; if (!(skb = alloc_skb(len + align, GFP_KERNEL))) { - tun->stats.rx_dropped++; + tun->dev->stats.rx_dropped++; return -ENOMEM; } if (align) skb_reserve(skb, align); if (memcpy_fromiovec(skb_put(skb, len), iv, len)) { - tun->stats.rx_dropped++; + tun->dev->stats.rx_dropped++; kfree_skb(skb); return -EFAULT; } @@ -279,8 +273,8 @@ static __inline__ ssize_t tun_get_user(struct tun_struct *tun, struct iovec *iv, netif_rx_ni(skb); tun->dev->last_rx = jiffies; - tun->stats.rx_packets++; - tun->stats.rx_bytes += len; + tun->dev->stats.rx_packets++; + tun->dev->stats.rx_bytes += len; return count; } @@ -336,8 +330,8 @@ static __inline__ ssize_t tun_put_user(struct tun_struct *tun, skb_copy_datagram_iovec(skb, 0, iv, len); total += len; - tun->stats.tx_packets++; - tun->stats.tx_bytes += len; + tun->dev->stats.tx_packets++; + tun->dev->stats.tx_bytes += len; return total; } @@ -438,7 +432,6 @@ static void tun_setup(struct net_device *dev) dev->open = tun_net_open; dev->hard_start_xmit = tun_net_xmit; dev->stop = tun_net_close; - dev->get_stats = tun_net_stats; dev->ethtool_ops = &tun_ethtool_ops; dev->destructor = free_netdev; } diff --git a/drivers/net/ucc_geth.c b/drivers/net/ucc_geth.c index 8da41229594a..9667dac383f0 100644 --- a/drivers/net/ucc_geth.c +++ b/drivers/net/ucc_geth.c @@ -3350,14 +3350,6 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth) return 0; } -/* returns a net_device_stats structure pointer */ -static struct net_device_stats *ucc_geth_get_stats(struct net_device *dev) -{ - struct ucc_geth_private *ugeth = netdev_priv(dev); - - return &(ugeth->stats); -} - /* ucc_geth_timeout gets called when a packet has not been * transmitted after a set amount of time. * For now, assume that clearing out all the structures, and @@ -3368,7 +3360,7 @@ static void ucc_geth_timeout(struct net_device *dev) ugeth_vdbg("%s: IN", __FUNCTION__); - ugeth->stats.tx_errors++; + dev->stats.tx_errors++; ugeth_dump_regs(ugeth); @@ -3396,7 +3388,7 @@ static int ucc_geth_start_xmit(struct sk_buff *skb, struct net_device *dev) spin_lock_irq(&ugeth->lock); - ugeth->stats.tx_bytes += skb->len; + dev->stats.tx_bytes += skb->len; /* Start from the next BD that should be filled */ bd = ugeth->txBd[txQ]; @@ -3488,9 +3480,9 @@ static int ucc_geth_rx(struct ucc_geth_private *ugeth, u8 rxQ, int rx_work_limit dev_kfree_skb_any(skb); ugeth->rx_skbuff[rxQ][ugeth->skb_currx[rxQ]] = NULL; - ugeth->stats.rx_dropped++; + dev->stats.rx_dropped++; } else { - ugeth->stats.rx_packets++; + dev->stats.rx_packets++; howmany++; /* Prep the skb for the packet */ @@ -3499,7 +3491,7 @@ static int ucc_geth_rx(struct ucc_geth_private *ugeth, u8 rxQ, int rx_work_limit /* Tell the skb what kind of packet this is */ skb->protocol = eth_type_trans(skb, ugeth->dev); - ugeth->stats.rx_bytes += length; + dev->stats.rx_bytes += length; /* Send the packet up the stack */ #ifdef CONFIG_UGETH_NAPI netif_receive_skb(skb); @@ -3514,7 +3506,7 @@ static int ucc_geth_rx(struct ucc_geth_private *ugeth, u8 rxQ, int rx_work_limit if (!skb) { if (netif_msg_rx_err(ugeth)) ugeth_warn("%s: No Rx Data Buffer", __FUNCTION__); - ugeth->stats.rx_dropped++; + dev->stats.rx_dropped++; break; } @@ -3556,7 +3548,7 @@ static int ucc_geth_tx(struct net_device *dev, u8 txQ) if ((bd == ugeth->txBd[txQ]) && (netif_queue_stopped(dev) == 0)) break; - ugeth->stats.tx_packets++; + dev->stats.tx_packets++; /* Free the sk buffer associated with this TxBD */ dev_kfree_skb_irq(ugeth-> @@ -3673,10 +3665,10 @@ static irqreturn_t ucc_geth_irq_handler(int irq, void *info) /* Errors and other events */ if (ucce & UCCE_OTHER) { if (ucce & UCCE_BSY) { - ugeth->stats.rx_errors++; + dev->stats.rx_errors++; } if (ucce & UCCE_TXE) { - ugeth->stats.tx_errors++; + dev->stats.tx_errors++; } } @@ -3969,7 +3961,6 @@ static int ucc_geth_probe(struct of_device* ofdev, const struct of_device_id *ma netif_napi_add(dev, &ugeth->napi, ucc_geth_poll, UCC_GETH_DEV_WEIGHT); #endif /* CONFIG_UGETH_NAPI */ dev->stop = ucc_geth_close; - dev->get_stats = ucc_geth_get_stats; // dev->change_mtu = ucc_geth_change_mtu; dev->mtu = 1500; dev->set_multicast_list = ucc_geth_set_multi; diff --git a/drivers/net/ucc_geth.h b/drivers/net/ucc_geth.h index 0579ba081aa5..aaeb94877987 100644 --- a/drivers/net/ucc_geth.h +++ b/drivers/net/ucc_geth.h @@ -1185,7 +1185,6 @@ struct ucc_geth_private { struct ucc_fast_private *uccf; struct net_device *dev; struct napi_struct napi; - struct net_device_stats stats; /* linux network statistics */ struct ucc_geth *ug_regs; struct ucc_geth_init_pram *p_init_enet_param_shadow; struct ucc_geth_exf_global_pram *p_exf_glbl_param; diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c index 8eeb068dc4a6..78e344ae7051 100644 --- a/drivers/net/xen-netfront.c +++ b/drivers/net/xen-netfront.c @@ -73,7 +73,6 @@ struct netfront_info { struct net_device *netdev; struct napi_struct napi; - struct net_device_stats stats; struct xen_netif_tx_front_ring tx; struct xen_netif_rx_front_ring rx; @@ -309,8 +308,6 @@ static int xennet_open(struct net_device *dev) { struct netfront_info *np = netdev_priv(dev); - memset(&np->stats, 0, sizeof(np->stats)); - napi_enable(&np->napi); spin_lock_bh(&np->rx_lock); @@ -537,8 +534,8 @@ static int xennet_start_xmit(struct sk_buff *skb, struct net_device *dev) if (notify) notify_remote_via_irq(np->netdev->irq); - np->stats.tx_bytes += skb->len; - np->stats.tx_packets++; + dev->stats.tx_bytes += skb->len; + dev->stats.tx_packets++; /* Note: It is not safe to access skb after xennet_tx_buf_gc()! */ xennet_tx_buf_gc(dev); @@ -551,7 +548,7 @@ static int xennet_start_xmit(struct sk_buff *skb, struct net_device *dev) return 0; drop: - np->stats.tx_dropped++; + dev->stats.tx_dropped++; dev_kfree_skb(skb); return 0; } @@ -564,12 +561,6 @@ static int xennet_close(struct net_device *dev) return 0; } -static struct net_device_stats *xennet_get_stats(struct net_device *dev) -{ - struct netfront_info *np = netdev_priv(dev); - return &np->stats; -} - static void xennet_move_rx_slot(struct netfront_info *np, struct sk_buff *skb, grant_ref_t ref) { @@ -804,9 +795,8 @@ out: } static int handle_incoming_queue(struct net_device *dev, - struct sk_buff_head *rxq) + struct sk_buff_head *rxq) { - struct netfront_info *np = netdev_priv(dev); int packets_dropped = 0; struct sk_buff *skb; @@ -828,13 +818,13 @@ static int handle_incoming_queue(struct net_device *dev, if (skb_checksum_setup(skb)) { kfree_skb(skb); packets_dropped++; - np->stats.rx_errors++; + dev->stats.rx_errors++; continue; } } - np->stats.rx_packets++; - np->stats.rx_bytes += skb->len; + dev->stats.rx_packets++; + dev->stats.rx_bytes += skb->len; /* Pass it up. */ netif_receive_skb(skb); @@ -887,7 +877,7 @@ static int xennet_poll(struct napi_struct *napi, int budget) err: while ((skb = __skb_dequeue(&tmpq))) __skb_queue_tail(&errq, skb); - np->stats.rx_errors++; + dev->stats.rx_errors++; i = np->rx.rsp_cons; continue; } @@ -1169,7 +1159,6 @@ static struct net_device * __devinit xennet_create_dev(struct xenbus_device *dev netdev->open = xennet_open; netdev->hard_start_xmit = xennet_start_xmit; netdev->stop = xennet_close; - netdev->get_stats = xennet_get_stats; netif_napi_add(netdev, &np->napi, xennet_poll, 64); netdev->uninit = xennet_uninit; netdev->change_mtu = xennet_change_mtu; diff --git a/drivers/net/yellowfin.c b/drivers/net/yellowfin.c index 29e96950be65..709623e1c611 100644 --- a/drivers/net/yellowfin.c +++ b/drivers/net/yellowfin.c @@ -318,7 +318,6 @@ struct yellowfin_private { dma_addr_t tx_status_dma; struct timer_list timer; /* Media selection timer. */ - struct net_device_stats stats; /* Frequently used and paired value: keep adjacent for cache effect. */ int chip_id, drv_flags; struct pci_dev *pci_dev; @@ -353,7 +352,6 @@ static irqreturn_t yellowfin_interrupt(int irq, void *dev_instance); static int yellowfin_rx(struct net_device *dev); static void yellowfin_error(struct net_device *dev, int intr_status); static int yellowfin_close(struct net_device *dev); -static struct net_device_stats *yellowfin_get_stats(struct net_device *dev); static void set_rx_mode(struct net_device *dev); static const struct ethtool_ops ethtool_ops; @@ -469,7 +467,6 @@ static int __devinit yellowfin_init_one(struct pci_dev *pdev, dev->open = &yellowfin_open; dev->hard_start_xmit = &yellowfin_start_xmit; dev->stop = &yellowfin_close; - dev->get_stats = &yellowfin_get_stats; dev->set_multicast_list = &set_rx_mode; dev->do_ioctl = &netdev_ioctl; SET_ETHTOOL_OPS(dev, ðtool_ops); @@ -717,7 +714,7 @@ static void yellowfin_tx_timeout(struct net_device *dev) netif_wake_queue (dev); /* Typical path */ dev->trans_start = jiffies; - yp->stats.tx_errors++; + dev->stats.tx_errors++; } /* Initialize the Rx and Tx rings, along with various 'dev' bits. */ @@ -923,8 +920,8 @@ static irqreturn_t yellowfin_interrupt(int irq, void *dev_instance) if (yp->tx_ring[entry].result_status == 0) break; skb = yp->tx_skbuff[entry]; - yp->stats.tx_packets++; - yp->stats.tx_bytes += skb->len; + dev->stats.tx_packets++; + dev->stats.tx_bytes += skb->len; /* Free the original skb. */ pci_unmap_single(yp->pci_dev, yp->tx_ring[entry].addr, skb->len, PCI_DMA_TODEVICE); @@ -968,20 +965,20 @@ static irqreturn_t yellowfin_interrupt(int irq, void *dev_instance) printk(KERN_DEBUG "%s: Transmit error, Tx status %4.4x.\n", dev->name, tx_errs); #endif - yp->stats.tx_errors++; - if (tx_errs & 0xF800) yp->stats.tx_aborted_errors++; - if (tx_errs & 0x0800) yp->stats.tx_carrier_errors++; - if (tx_errs & 0x2000) yp->stats.tx_window_errors++; - if (tx_errs & 0x8000) yp->stats.tx_fifo_errors++; + dev->stats.tx_errors++; + if (tx_errs & 0xF800) dev->stats.tx_aborted_errors++; + if (tx_errs & 0x0800) dev->stats.tx_carrier_errors++; + if (tx_errs & 0x2000) dev->stats.tx_window_errors++; + if (tx_errs & 0x8000) dev->stats.tx_fifo_errors++; } else { #ifndef final_version if (yellowfin_debug > 4) printk(KERN_DEBUG "%s: Normal transmit, Tx status %4.4x.\n", dev->name, tx_errs); #endif - yp->stats.tx_bytes += skb->len; - yp->stats.collisions += tx_errs & 15; - yp->stats.tx_packets++; + dev->stats.tx_bytes += skb->len; + dev->stats.collisions += tx_errs & 15; + dev->stats.tx_packets++; } /* Free the original skb. */ pci_unmap_single(yp->pci_dev, @@ -1076,26 +1073,26 @@ static int yellowfin_rx(struct net_device *dev) if (data_size != 0) printk(KERN_WARNING "%s: Oversized Ethernet frame spanned multiple buffers," " status %4.4x, data_size %d!\n", dev->name, desc_status, data_size); - yp->stats.rx_length_errors++; + dev->stats.rx_length_errors++; } else if ((yp->drv_flags & IsGigabit) && (frame_status & 0x0038)) { /* There was a error. */ if (yellowfin_debug > 3) printk(KERN_DEBUG " yellowfin_rx() Rx error was %4.4x.\n", frame_status); - yp->stats.rx_errors++; - if (frame_status & 0x0060) yp->stats.rx_length_errors++; - if (frame_status & 0x0008) yp->stats.rx_frame_errors++; - if (frame_status & 0x0010) yp->stats.rx_crc_errors++; - if (frame_status < 0) yp->stats.rx_dropped++; + dev->stats.rx_errors++; + if (frame_status & 0x0060) dev->stats.rx_length_errors++; + if (frame_status & 0x0008) dev->stats.rx_frame_errors++; + if (frame_status & 0x0010) dev->stats.rx_crc_errors++; + if (frame_status < 0) dev->stats.rx_dropped++; } else if ( !(yp->drv_flags & IsGigabit) && ((buf_addr[data_size-1] & 0x85) || buf_addr[data_size-2] & 0xC0)) { u8 status1 = buf_addr[data_size-2]; u8 status2 = buf_addr[data_size-1]; - yp->stats.rx_errors++; - if (status1 & 0xC0) yp->stats.rx_length_errors++; - if (status2 & 0x03) yp->stats.rx_frame_errors++; - if (status2 & 0x04) yp->stats.rx_crc_errors++; - if (status2 & 0x80) yp->stats.rx_dropped++; + dev->stats.rx_errors++; + if (status1 & 0xC0) dev->stats.rx_length_errors++; + if (status2 & 0x03) dev->stats.rx_frame_errors++; + if (status2 & 0x04) dev->stats.rx_crc_errors++; + if (status2 & 0x80) dev->stats.rx_dropped++; #ifdef YF_PROTOTYPE /* Support for prototype hardware errata. */ } else if ((yp->flags & HasMACAddrBug) && memcmp(le32_to_cpu(yp->rx_ring_dma + @@ -1145,8 +1142,8 @@ static int yellowfin_rx(struct net_device *dev) skb->protocol = eth_type_trans(skb, dev); netif_rx(skb); dev->last_rx = jiffies; - yp->stats.rx_packets++; - yp->stats.rx_bytes += pkt_len; + dev->stats.rx_packets++; + dev->stats.rx_bytes += pkt_len; } entry = (++yp->cur_rx) % RX_RING_SIZE; } @@ -1180,15 +1177,13 @@ static int yellowfin_rx(struct net_device *dev) static void yellowfin_error(struct net_device *dev, int intr_status) { - struct yellowfin_private *yp = netdev_priv(dev); - printk(KERN_ERR "%s: Something Wicked happened! %4.4x.\n", dev->name, intr_status); /* Hmmmmm, it's not clear what to do here. */ if (intr_status & (IntrTxPCIErr | IntrTxPCIFault)) - yp->stats.tx_errors++; + dev->stats.tx_errors++; if (intr_status & (IntrRxPCIErr | IntrRxPCIFault)) - yp->stats.rx_errors++; + dev->stats.rx_errors++; } static int yellowfin_close(struct net_device *dev) @@ -1280,12 +1275,6 @@ static int yellowfin_close(struct net_device *dev) return 0; } -static struct net_device_stats *yellowfin_get_stats(struct net_device *dev) -{ - struct yellowfin_private *yp = netdev_priv(dev); - return &yp->stats; -} - /* Set or clear the multicast filter for this adaptor. */ static void set_rx_mode(struct net_device *dev) diff --git a/drivers/net/znet.c b/drivers/net/znet.c index dcd4e1b136b5..43712c7b9ecf 100644 --- a/drivers/net/znet.c +++ b/drivers/net/znet.c @@ -128,7 +128,6 @@ MODULE_LICENSE("GPL"); struct znet_private { int rx_dma, tx_dma; - struct net_device_stats stats; spinlock_t lock; short sia_base, sia_size, io_size; struct i82593_conf_block i593_init; @@ -161,7 +160,6 @@ static int znet_send_packet(struct sk_buff *skb, struct net_device *dev); static irqreturn_t znet_interrupt(int irq, void *dev_id); static void znet_rx(struct net_device *dev); static int znet_close(struct net_device *dev); -static struct net_device_stats *net_get_stats(struct net_device *dev); static void hardware_init(struct net_device *dev); static void update_stop_hit(short ioaddr, unsigned short rx_stop_offset); static void znet_tx_timeout (struct net_device *dev); @@ -445,7 +443,6 @@ static int __init znet_probe (void) dev->open = &znet_open; dev->hard_start_xmit = &znet_send_packet; dev->stop = &znet_close; - dev->get_stats = net_get_stats; dev->set_multicast_list = &znet_set_multicast_list; dev->tx_timeout = znet_tx_timeout; dev->watchdog_timeo = TX_TIMEOUT; @@ -564,7 +561,7 @@ static int znet_send_packet(struct sk_buff *skb, struct net_device *dev) ushort *tx_link = znet->tx_cur - 1; ushort rnd_len = (length + 1)>>1; - znet->stats.tx_bytes+=length; + dev->stats.tx_bytes+=length; if (znet->tx_cur >= znet->tx_end) znet->tx_cur = znet->tx_start; @@ -639,20 +636,20 @@ static irqreturn_t znet_interrupt(int irq, void *dev_id) tx_status = inw(ioaddr); /* It's undocumented, but tx_status seems to match the i82586. */ if (tx_status & TX_OK) { - znet->stats.tx_packets++; - znet->stats.collisions += tx_status & TX_NCOL_MASK; + dev->stats.tx_packets++; + dev->stats.collisions += tx_status & TX_NCOL_MASK; } else { if (tx_status & (TX_LOST_CTS | TX_LOST_CRS)) - znet->stats.tx_carrier_errors++; + dev->stats.tx_carrier_errors++; if (tx_status & TX_UND_RUN) - znet->stats.tx_fifo_errors++; + dev->stats.tx_fifo_errors++; if (!(tx_status & TX_HRT_BEAT)) - znet->stats.tx_heartbeat_errors++; + dev->stats.tx_heartbeat_errors++; if (tx_status & TX_MAX_COL) - znet->stats.tx_aborted_errors++; + dev->stats.tx_aborted_errors++; /* ...and the catch-all. */ if ((tx_status | (TX_LOST_CRS | TX_LOST_CTS | TX_UND_RUN | TX_HRT_BEAT | TX_MAX_COL)) != (TX_LOST_CRS | TX_LOST_CTS | TX_UND_RUN | TX_HRT_BEAT | TX_MAX_COL)) - znet->stats.tx_errors++; + dev->stats.tx_errors++; /* Transceiver may be stuck if cable * was removed while emiting a @@ -748,19 +745,19 @@ static void znet_rx(struct net_device *dev) this_rfp_ptr[-3]<<1); /* Once again we must assume that the i82586 docs apply. */ if ( ! (status & RX_RCV_OK)) { /* There was an error. */ - znet->stats.rx_errors++; - if (status & RX_CRC_ERR) znet->stats.rx_crc_errors++; - if (status & RX_ALG_ERR) znet->stats.rx_frame_errors++; + dev->stats.rx_errors++; + if (status & RX_CRC_ERR) dev->stats.rx_crc_errors++; + if (status & RX_ALG_ERR) dev->stats.rx_frame_errors++; #if 0 - if (status & 0x0200) znet->stats.rx_over_errors++; /* Wrong. */ - if (status & 0x0100) znet->stats.rx_fifo_errors++; + if (status & 0x0200) dev->stats.rx_over_errors++; /* Wrong. */ + if (status & 0x0100) dev->stats.rx_fifo_errors++; #else /* maz : Wild guess... */ - if (status & RX_OVRRUN) znet->stats.rx_over_errors++; + if (status & RX_OVRRUN) dev->stats.rx_over_errors++; #endif - if (status & RX_SRT_FRM) znet->stats.rx_length_errors++; + if (status & RX_SRT_FRM) dev->stats.rx_length_errors++; } else if (pkt_len > 1536) { - znet->stats.rx_length_errors++; + dev->stats.rx_length_errors++; } else { /* Malloc up new buffer. */ struct sk_buff *skb; @@ -769,7 +766,7 @@ static void znet_rx(struct net_device *dev) if (skb == NULL) { if (znet_debug) printk(KERN_WARNING "%s: Memory squeeze, dropping packet.\n", dev->name); - znet->stats.rx_dropped++; + dev->stats.rx_dropped++; break; } @@ -789,8 +786,8 @@ static void znet_rx(struct net_device *dev) skb->protocol=eth_type_trans(skb,dev); netif_rx(skb); dev->last_rx = jiffies; - znet->stats.rx_packets++; - znet->stats.rx_bytes += pkt_len; + dev->stats.rx_packets++; + dev->stats.rx_bytes += pkt_len; } znet->rx_cur = this_rfp_ptr; if (znet->rx_cur >= znet->rx_end) @@ -827,15 +824,6 @@ static int znet_close(struct net_device *dev) return 0; } -/* Get the current statistics. This may be called with the card open or - closed. */ -static struct net_device_stats *net_get_stats(struct net_device *dev) -{ - struct znet_private *znet = dev->priv; - - return &znet->stats; -} - static void show_dma(struct net_device *dev) { short ioaddr = dev->base_addr; diff --git a/include/linux/if_eql.h b/include/linux/if_eql.h index b68752fdc5c4..79c4f268410d 100644 --- a/include/linux/if_eql.h +++ b/include/linux/if_eql.h @@ -58,7 +58,6 @@ typedef struct equalizer { slave_queue_t queue; int min_slaves; int max_slaves; - struct net_device_stats stats; struct timer_list timer; } equalizer_t; diff --git a/include/linux/if_shaper.h b/include/linux/if_shaper.h index 68c896a36a34..51574743aa1b 100644 --- a/include/linux/if_shaper.h +++ b/include/linux/if_shaper.h @@ -24,7 +24,6 @@ struct shaper unsigned long recovery; /* Time we can next clock a packet out on an empty queue */ spinlock_t lock; - struct net_device_stats stats; struct net_device *dev; int (*hard_start_xmit) (struct sk_buff *skb, struct net_device *dev); diff --git a/include/linux/if_tun.h b/include/linux/if_tun.h index 42eb6945b93e..33e489d5bb33 100644 --- a/include/linux/if_tun.h +++ b/include/linux/if_tun.h @@ -42,7 +42,6 @@ struct tun_struct { struct sk_buff_head readq; struct net_device *dev; - struct net_device_stats stats; struct fasync_struct *fasync; -- cgit v1.2.3 From 22dd74950172dc8979576e2bef3b439f20ef0b05 Mon Sep 17 00:00:00 2001 From: Jamal Hadi Salim Date: Sun, 16 Sep 2007 14:40:49 -0700 Subject: [NET]: migrate HARD_TX_LOCK to header file HARD_TX_LOCK micro is a nice aggregation that could be used in other spots. move it to netdevice.h Also makes sure the previously superflous cpu arguement is used. Thanks to DaveM for the suggestions. Signed-off-by: Jamal Hadi Salim Signed-off-by: David S. Miller --- include/linux/netdevice.h | 21 +++++++++++++++++++-- net/core/dev.c | 12 ------------ 2 files changed, 19 insertions(+), 14 deletions(-) (limited to 'include/linux') diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index de387c5400b3..96964fb7478b 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -1265,10 +1265,15 @@ static inline void netif_rx_complete(struct net_device *dev, * * Get network device transmit lock */ -static inline void netif_tx_lock(struct net_device *dev) +static inline void __netif_tx_lock(struct net_device *dev, int cpu) { spin_lock(&dev->_xmit_lock); - dev->xmit_lock_owner = smp_processor_id(); + dev->xmit_lock_owner = cpu; +} + +static inline void netif_tx_lock(struct net_device *dev) +{ + __netif_tx_lock(dev, smp_processor_id()); } static inline void netif_tx_lock_bh(struct net_device *dev) @@ -1297,6 +1302,18 @@ static inline void netif_tx_unlock_bh(struct net_device *dev) spin_unlock_bh(&dev->_xmit_lock); } +#define HARD_TX_LOCK(dev, cpu) { \ + if ((dev->features & NETIF_F_LLTX) == 0) { \ + __netif_tx_lock(dev, cpu); \ + } \ +} + +#define HARD_TX_UNLOCK(dev) { \ + if ((dev->features & NETIF_F_LLTX) == 0) { \ + netif_tx_unlock(dev); \ + } \ +} + static inline void netif_tx_disable(struct net_device *dev) { netif_tx_lock_bh(dev); diff --git a/net/core/dev.c b/net/core/dev.c index 666c112efb55..e9a6d93a194f 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -1574,18 +1574,6 @@ out_kfree_skb: return 0; } -#define HARD_TX_LOCK(dev, cpu) { \ - if ((dev->features & NETIF_F_LLTX) == 0) { \ - netif_tx_lock(dev); \ - } \ -} - -#define HARD_TX_UNLOCK(dev) { \ - if ((dev->features & NETIF_F_LLTX) == 0) { \ - netif_tx_unlock(dev); \ - } \ -} - /** * dev_queue_xmit - transmit a buffer * @skb: buffer to transmit -- cgit v1.2.3 From ad7379d49458a863c520a73a3c36441c572f850e Mon Sep 17 00:00:00 2001 From: "Eric W. Biederman" Date: Sun, 16 Sep 2007 15:33:32 -0700 Subject: [NET]: Fix the prototype of call_netdevice_notifiers. This replaces the void * parameter with a struct net_device * which is what is actually required. Signed-off-by: Eric W. Biederman Signed-off-by: David S. Miller --- include/linux/netdevice.h | 2 +- net/core/dev.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'include/linux') diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 96964fb7478b..cf89ce677e41 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -792,7 +792,7 @@ extern void free_netdev(struct net_device *dev); extern void synchronize_net(void); extern int register_netdevice_notifier(struct notifier_block *nb); extern int unregister_netdevice_notifier(struct notifier_block *nb); -extern int call_netdevice_notifiers(unsigned long val, void *v); +extern int call_netdevice_notifiers(unsigned long val, struct net_device *dev); extern struct net_device *dev_get_by_index(struct net *net, int ifindex); extern struct net_device *__dev_get_by_index(struct net *net, int ifindex); extern int dev_restart(struct net_device *dev); diff --git a/net/core/dev.c b/net/core/dev.c index e9a6d93a194f..b517d36e653e 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -1206,9 +1206,9 @@ int unregister_netdevice_notifier(struct notifier_block *nb) * are as for raw_notifier_call_chain(). */ -int call_netdevice_notifiers(unsigned long val, void *v) +int call_netdevice_notifiers(unsigned long val, struct net_device *dev) { - return raw_notifier_call_chain(&netdev_chain, val, v); + return raw_notifier_call_chain(&netdev_chain, val, dev); } /* When > 0 there are consumers of rx skb time stamps */ -- cgit v1.2.3 From 131a47e31ab1a9defd50ff16b04008ab94c21c0d Mon Sep 17 00:00:00 2001 From: Vlad Yasevich Date: Sun, 16 Sep 2007 15:53:56 -0700 Subject: [SCTP]: Implement the Supported Extensions Parameter SCTP Supported Extenions parameter is specified in Section 4.2.7 of the ADD-IP draft (soon to be RFC). The parameter is encoded as: 0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Parameter Type = 0x8008 | Parameter Length | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | CHUNK TYPE 1 | CHUNK TYPE 2 | CHUNK TYPE 3 | CHUNK TYPE 4 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | .... | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | CHUNK TYPE N | PAD | PAD | PAD | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ It contains a list of chunks that a particular SCTP extension uses. Current extensions supported are Partial Reliability (FWD-TSN) and ADD-IP (ASCONF and ASCONF-ACK). When implementing new extensions (AUTH, PKT-DROP, etc..), new chunks need to be added to this parameter. Parameter processing would be modified to negotiate support for these new features. Signed-off-by: Vlad Yasevich Signed-off-by: David S. Miller --- include/linux/sctp.h | 9 +++++ include/net/sctp/structs.h | 1 + net/sctp/sm_make_chunk.c | 91 +++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 99 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/sctp.h b/include/linux/sctp.h index d70df61a029f..f4d717b72ddd 100644 --- a/include/linux/sctp.h +++ b/include/linux/sctp.h @@ -180,6 +180,9 @@ typedef enum { SCTP_PARAM_SUPPORTED_ADDRESS_TYPES = __constant_htons(12), SCTP_PARAM_ECN_CAPABLE = __constant_htons(0x8000), + /* Add-IP: Supported Extensions, Section 4.2 */ + SCTP_PARAM_SUPPORTED_EXT = __constant_htons(0x8008), + /* PR-SCTP Sec 3.1 */ SCTP_PARAM_FWD_TSN_SUPPORT = __constant_htons(0xc000), @@ -296,6 +299,12 @@ typedef struct sctp_adaptation_ind_param { __be32 adaptation_ind; } __attribute__((packed)) sctp_adaptation_ind_param_t; +/* ADDIP Section 4.2.7 Supported Extensions Parameter */ +typedef struct sctp_supported_ext_param { + struct sctp_paramhdr param_hdr; + __u8 chunks[0]; +} __attribute__((packed)) sctp_supported_ext_param_t; + /* RFC 2960. Section 3.3.3 Initiation Acknowledgement (INIT ACK) (2): * The INIT ACK chunk is used to acknowledge the initiation of an SCTP * association. diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h index 67c91d01b635..b4812a2d3bb0 100644 --- a/include/net/sctp/structs.h +++ b/include/net/sctp/structs.h @@ -440,6 +440,7 @@ union sctp_params { struct sctp_ipv6addr_param *v6; union sctp_addr_param *addr; struct sctp_adaptation_ind_param *aind; + struct sctp_supported_ext_param *ext; }; /* RFC 2960. Section 3.3.5 Heartbeat. diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c index d84e575f7409..71cc204a9ea5 100644 --- a/net/sctp/sm_make_chunk.c +++ b/net/sctp/sm_make_chunk.c @@ -179,6 +179,9 @@ struct sctp_chunk *sctp_make_init(const struct sctp_association *asoc, sctp_supported_addrs_param_t sat; __be16 types[2]; sctp_adaptation_ind_param_t aiparam; + sctp_supported_ext_param_t ext_param; + int num_ext = 0; + __u8 extensions[3]; /* RFC 2960 3.3.2 Initiation (INIT) (1) * @@ -202,11 +205,31 @@ struct sctp_chunk *sctp_make_init(const struct sctp_association *asoc, chunksize = sizeof(init) + addrs_len + SCTP_SAT_LEN(num_types); chunksize += sizeof(ecap_param); - if (sctp_prsctp_enable) + if (sctp_prsctp_enable) { chunksize += sizeof(prsctp_param); + extensions[num_ext] = SCTP_CID_FWD_TSN; + num_ext += 1; + } + /* ADDIP: Section 4.2.7: + * An implementation supporting this extension [ADDIP] MUST list + * the ASCONF,the ASCONF-ACK, and the AUTH chunks in its INIT and + * INIT-ACK parameters. + * XXX: We don't support AUTH just yet, so don't list it. AUTH + * support should add it. + */ + if (sctp_addip_enable) { + extensions[num_ext] = SCTP_CID_ASCONF; + extensions[num_ext+1] = SCTP_CID_ASCONF_ACK; + num_ext += 2; + } + chunksize += sizeof(aiparam); chunksize += vparam_len; + /* If we have any extensions to report, account for that */ + if (num_ext) + chunksize += sizeof(sctp_supported_ext_param_t) + num_ext; + /* RFC 2960 3.3.2 Initiation (INIT) (1) * * Note 3: An INIT chunk MUST NOT contain more than one Host @@ -241,12 +264,27 @@ struct sctp_chunk *sctp_make_init(const struct sctp_association *asoc, sctp_addto_chunk(retval, num_types * sizeof(__u16), &types); sctp_addto_chunk(retval, sizeof(ecap_param), &ecap_param); + + /* Add the supported extensions paramter. Be nice and add this + * fist before addiding the parameters for the extensions themselves + */ + if (num_ext) { + ext_param.param_hdr.type = SCTP_PARAM_SUPPORTED_EXT; + ext_param.param_hdr.length = + htons(sizeof(sctp_supported_ext_param_t) + num_ext); + sctp_addto_chunk(retval, sizeof(sctp_supported_ext_param_t), + &ext_param); + sctp_addto_chunk(retval, num_ext, extensions); + } + if (sctp_prsctp_enable) sctp_addto_chunk(retval, sizeof(prsctp_param), &prsctp_param); + aiparam.param_hdr.type = SCTP_PARAM_ADAPTATION_LAYER_IND; aiparam.param_hdr.length = htons(sizeof(aiparam)); aiparam.adaptation_ind = htonl(sp->adaptation_ind); sctp_addto_chunk(retval, sizeof(aiparam), &aiparam); + nodata: kfree(addrs.v); return retval; @@ -264,6 +302,9 @@ struct sctp_chunk *sctp_make_init_ack(const struct sctp_association *asoc, int cookie_len; size_t chunksize; sctp_adaptation_ind_param_t aiparam; + sctp_supported_ext_param_t ext_param; + int num_ext = 0; + __u8 extensions[3]; retval = NULL; @@ -294,9 +335,19 @@ struct sctp_chunk *sctp_make_init_ack(const struct sctp_association *asoc, chunksize += sizeof(ecap_param); /* Tell peer that we'll do PR-SCTP only if peer advertised. */ - if (asoc->peer.prsctp_capable) + if (asoc->peer.prsctp_capable) { chunksize += sizeof(prsctp_param); + extensions[num_ext] = SCTP_CID_FWD_TSN; + num_ext += 1; + } + if (sctp_addip_enable) { + extensions[num_ext] = SCTP_CID_ASCONF; + extensions[num_ext+1] = SCTP_CID_ASCONF_ACK; + num_ext += 2; + } + + chunksize += sizeof(ext_param) + num_ext; chunksize += sizeof(aiparam); /* Now allocate and fill out the chunk. */ @@ -314,6 +365,14 @@ struct sctp_chunk *sctp_make_init_ack(const struct sctp_association *asoc, sctp_addto_chunk(retval, cookie_len, cookie); if (asoc->peer.ecn_capable) sctp_addto_chunk(retval, sizeof(ecap_param), &ecap_param); + if (num_ext) { + ext_param.param_hdr.type = SCTP_PARAM_SUPPORTED_EXT; + ext_param.param_hdr.length = + htons(sizeof(sctp_supported_ext_param_t) + num_ext); + sctp_addto_chunk(retval, sizeof(sctp_supported_ext_param_t), + &ext_param); + sctp_addto_chunk(retval, num_ext, extensions); + } if (asoc->peer.prsctp_capable) sctp_addto_chunk(retval, sizeof(prsctp_param), &prsctp_param); @@ -1664,6 +1723,28 @@ static int sctp_process_hn_param(const struct sctp_association *asoc, return 0; } +static void sctp_process_ext_param(struct sctp_association *asoc, + union sctp_params param) +{ + __u16 num_ext = ntohs(param.p->length) - sizeof(sctp_paramhdr_t); + int i; + + for (i = 0; i < num_ext; i++) { + switch (param.ext->chunks[i]) { + case SCTP_CID_FWD_TSN: + if (sctp_prsctp_enable && + !asoc->peer.prsctp_capable) + asoc->peer.prsctp_capable = 1; + break; + case SCTP_CID_ASCONF: + case SCTP_CID_ASCONF_ACK: + /* don't need to do anything for ASCONF */ + default: + break; + } + } +} + /* RFC 3.2.1 & the Implementers Guide 2.2. * * The Parameter Types are encoded such that the @@ -1780,11 +1861,13 @@ static int sctp_verify_param(const struct sctp_association *asoc, case SCTP_PARAM_UNRECOGNIZED_PARAMETERS: case SCTP_PARAM_ECN_CAPABLE: case SCTP_PARAM_ADAPTATION_LAYER_IND: + case SCTP_PARAM_SUPPORTED_EXT: break; case SCTP_PARAM_HOST_NAME_ADDRESS: /* Tell the peer, we won't support this param. */ return sctp_process_hn_param(asoc, param, chunk, err_chunk); + case SCTP_PARAM_FWD_TSN_SUPPORT: if (sctp_prsctp_enable) break; @@ -2129,6 +2212,10 @@ static int sctp_process_param(struct sctp_association *asoc, asoc->peer.adaptation_ind = param.aind->adaptation_ind; break; + case SCTP_PARAM_SUPPORTED_EXT: + sctp_process_ext_param(asoc, param); + break; + case SCTP_PARAM_FWD_TSN_SUPPORT: if (sctp_prsctp_enable) { asoc->peer.prsctp_capable = 1; -- cgit v1.2.3 From 14878f75abd5bf1d38becb405801cd491ee215dc Mon Sep 17 00:00:00 2001 From: David L Stevens Date: Sun, 16 Sep 2007 16:52:35 -0700 Subject: [IPV6]: Add ICMPMsgStats MIB (RFC 4293) [rev 2] Background: RFC 4293 deprecates existing individual, named ICMP type counters to be replaced with the ICMPMsgStatsTable. This table includes entries for both IPv4 and IPv6, and requires counting of all ICMP types, whether or not the machine implements the type. These patches "remove" (but not really) the existing counters, and replace them with the ICMPMsgStats tables for v4 and v6. It includes the named counters in the /proc places they were, but gets the values for them from the new tables. It also counts packets generated from raw socket output (e.g., OutEchoes, MLD queries, RA's from radvd, etc). Changes: 1) create icmpmsg_statistics mib 2) create icmpv6msg_statistics mib 3) modify existing counters to use these 4) modify /proc/net/snmp to add "IcmpMsg" with all ICMP types listed by number for easy SNMP parsing 5) modify /proc/net/snmp printing for "Icmp" to get the named data from new counters. [new to 2nd revision] 6) support per-interface ICMP stats 7) use common macro for per-device stat macros Signed-off-by: David L Stevens Signed-off-by: David S. Miller --- include/linux/snmp.h | 27 ++------------- include/net/if_inet6.h | 1 + include/net/ipv6.h | 67 ++++++++++++++++++------------------ include/net/snmp.h | 6 ++++ net/ipv6/addrconf.c | 7 ++++ net/ipv6/af_inet6.c | 5 +++ net/ipv6/icmp.c | 12 ++----- net/ipv6/ip6_output.c | 7 ++++ net/ipv6/mcast.c | 12 +++---- net/ipv6/ndisc.c | 21 ++++++------ net/ipv6/proc.c | 92 +++++++++++++++++++++++++++++++------------------- 11 files changed, 135 insertions(+), 122 deletions(-) (limited to 'include/linux') diff --git a/include/linux/snmp.h b/include/linux/snmp.h index d24c55473821..86977e31548a 100644 --- a/include/linux/snmp.h +++ b/include/linux/snmp.h @@ -91,35 +91,12 @@ enum ICMP6_MIB_NUM = 0, ICMP6_MIB_INMSGS, /* InMsgs */ ICMP6_MIB_INERRORS, /* InErrors */ - ICMP6_MIB_INDESTUNREACHS, /* InDestUnreachs */ - ICMP6_MIB_INPKTTOOBIGS, /* InPktTooBigs */ - ICMP6_MIB_INTIMEEXCDS, /* InTimeExcds */ - ICMP6_MIB_INPARMPROBLEMS, /* InParmProblems */ - ICMP6_MIB_INECHOS, /* InEchos */ - ICMP6_MIB_INECHOREPLIES, /* InEchoReplies */ - ICMP6_MIB_INGROUPMEMBQUERIES, /* InGroupMembQueries */ - ICMP6_MIB_INGROUPMEMBRESPONSES, /* InGroupMembResponses */ - ICMP6_MIB_INGROUPMEMBREDUCTIONS, /* InGroupMembReductions */ - ICMP6_MIB_INROUTERSOLICITS, /* InRouterSolicits */ - ICMP6_MIB_INROUTERADVERTISEMENTS, /* InRouterAdvertisements */ - ICMP6_MIB_INNEIGHBORSOLICITS, /* InNeighborSolicits */ - ICMP6_MIB_INNEIGHBORADVERTISEMENTS, /* InNeighborAdvertisements */ - ICMP6_MIB_INREDIRECTS, /* InRedirects */ ICMP6_MIB_OUTMSGS, /* OutMsgs */ - ICMP6_MIB_OUTDESTUNREACHS, /* OutDestUnreachs */ - ICMP6_MIB_OUTPKTTOOBIGS, /* OutPktTooBigs */ - ICMP6_MIB_OUTTIMEEXCDS, /* OutTimeExcds */ - ICMP6_MIB_OUTPARMPROBLEMS, /* OutParmProblems */ - ICMP6_MIB_OUTECHOREPLIES, /* OutEchoReplies */ - ICMP6_MIB_OUTROUTERSOLICITS, /* OutRouterSolicits */ - ICMP6_MIB_OUTNEIGHBORSOLICITS, /* OutNeighborSolicits */ - ICMP6_MIB_OUTNEIGHBORADVERTISEMENTS, /* OutNeighborAdvertisements */ - ICMP6_MIB_OUTREDIRECTS, /* OutRedirects */ - ICMP6_MIB_OUTGROUPMEMBRESPONSES, /* OutGroupMembResponses */ - ICMP6_MIB_OUTGROUPMEMBREDUCTIONS, /* OutGroupMembReductions */ __ICMP6_MIB_MAX }; +#define __ICMP6MSG_MIB_MAX 512 /* Out+In for all 8-bit ICMPv6 types */ + /* tcp mib definitions */ /* * RFC 1213: MIB-II TCP group diff --git a/include/net/if_inet6.h b/include/net/if_inet6.h index 3ec7d07346d6..448eccb20638 100644 --- a/include/net/if_inet6.h +++ b/include/net/if_inet6.h @@ -154,6 +154,7 @@ struct ipv6_devstat { struct proc_dir_entry *proc_dir_entry; DEFINE_SNMP_STAT(struct ipstats_mib, ipv6); DEFINE_SNMP_STAT(struct icmpv6_mib, icmpv6); + DEFINE_SNMP_STAT(struct icmpv6msg_mib, icmpv6msg); }; struct inet6_dev diff --git a/include/net/ipv6.h b/include/net/ipv6.h index 9573c8d19153..31b3f1b45a2b 100644 --- a/include/net/ipv6.h +++ b/include/net/ipv6.h @@ -112,45 +112,28 @@ struct frag_hdr { extern int sysctl_ipv6_bindv6only; extern int sysctl_mld_max_msf; -/* MIBs */ -DECLARE_SNMP_STAT(struct ipstats_mib, ipv6_statistics); -#define IP6_INC_STATS(idev,field) ({ \ +#define _DEVINC(statname, modifier, idev, field) \ +({ \ struct inet6_dev *_idev = (idev); \ if (likely(_idev != NULL)) \ - SNMP_INC_STATS(_idev->stats.ipv6, field); \ - SNMP_INC_STATS(ipv6_statistics, field); \ -}) -#define IP6_INC_STATS_BH(idev,field) ({ \ - struct inet6_dev *_idev = (idev); \ - if (likely(_idev != NULL)) \ - SNMP_INC_STATS_BH(_idev->stats.ipv6, field); \ - SNMP_INC_STATS_BH(ipv6_statistics, field); \ -}) -#define IP6_INC_STATS_USER(idev,field) ({ \ - struct inet6_dev *_idev = (idev); \ - if (likely(_idev != NULL)) \ - SNMP_INC_STATS_USER(_idev->stats.ipv6, field); \ - SNMP_INC_STATS_USER(ipv6_statistics, field); \ + SNMP_INC_STATS##modifier((_idev)->stats.statname, (field)); \ + SNMP_INC_STATS##modifier(statname##_statistics, (field)); \ }) + +/* MIBs */ +DECLARE_SNMP_STAT(struct ipstats_mib, ipv6_statistics); + +#define IP6_INC_STATS(idev,field) _DEVINC(ipv6, , idev, field) +#define IP6_INC_STATS_BH(idev,field) _DEVINC(ipv6, _BH, idev, field) +#define IP6_INC_STATS_USER(idev,field) _DEVINC(ipv6, _USER, idev, field) + DECLARE_SNMP_STAT(struct icmpv6_mib, icmpv6_statistics); -#define ICMP6_INC_STATS(idev, field) ({ \ - struct inet6_dev *_idev = (idev); \ - if (likely(_idev != NULL)) \ - SNMP_INC_STATS(idev->stats.icmpv6, field); \ - SNMP_INC_STATS(icmpv6_statistics, field); \ -}) -#define ICMP6_INC_STATS_BH(idev, field) ({ \ - struct inet6_dev *_idev = (idev); \ - if (likely(_idev != NULL)) \ - SNMP_INC_STATS_BH((_idev)->stats.icmpv6, field); \ - SNMP_INC_STATS_BH(icmpv6_statistics, field); \ -}) -#define ICMP6_INC_STATS_USER(idev, field) ({ \ - struct inet6_dev *_idev = (idev); \ - if (likely(_idev != NULL)) \ - SNMP_INC_STATS_USER(_idev->stats.icmpv6, field); \ - SNMP_INC_STATS_USER(icmpv6_statistics, field); \ -}) +DECLARE_SNMP_STAT(struct icmpv6msg_mib, icmpv6msg_statistics); + +#define ICMP6_INC_STATS(idev, field) _DEVINC(icmpv6, , idev, field) +#define ICMP6_INC_STATS_BH(idev, field) _DEVINC(icmpv6, _BH, idev, field) +#define ICMP6_INC_STATS_USER(idev, field) _DEVINC(icmpv6, _USER, idev, field) + #define ICMP6_INC_STATS_OFFSET_BH(idev, field, offset) ({ \ struct inet6_dev *_idev = idev; \ __typeof__(offset) _offset = (offset); \ @@ -158,6 +141,20 @@ DECLARE_SNMP_STAT(struct icmpv6_mib, icmpv6_statistics); SNMP_INC_STATS_OFFSET_BH(_idev->stats.icmpv6, field, _offset); \ SNMP_INC_STATS_OFFSET_BH(icmpv6_statistics, field, _offset); \ }) + +#define ICMP6MSGOUT_INC_STATS(idev, field) \ + _DEVINC(icmpv6msg, , idev, field +256) +#define ICMP6MSGOUT_INC_STATS_BH(idev, field) \ + _DEVINC(icmpv6msg, _BH, idev, field +256) +#define ICMP6MSGOUT_INC_STATS_USER(idev, field) \ + _DEVINC(icmpv6msg, _USER, idev, field +256) +#define ICMP6MSGIN_INC_STATS(idev, field) \ + _DEVINC(icmpv6msg, , idev, field) +#define ICMP6MSGIN_INC_STATS_BH(idev, field) \ + _DEVINC(icmpv6msg, _BH, idev, field) +#define ICMP6MSGIN_INC_STATS_USER(idev, field) \ + _DEVINC(icmpv6msg, _USER, idev, field) + DECLARE_SNMP_STAT(struct udp_mib, udp_stats_in6); DECLARE_SNMP_STAT(struct udp_mib, udplite_stats_in6); #define UDP6_INC_STATS_BH(field, is_udplite) do { \ diff --git a/include/net/snmp.h b/include/net/snmp.h index 464970e39ec0..a566e11d2f98 100644 --- a/include/net/snmp.h +++ b/include/net/snmp.h @@ -88,6 +88,12 @@ struct icmpv6_mib { unsigned long mibs[ICMP6_MIB_MAX]; } __SNMP_MIB_ALIGN__; +#define ICMP6MSG_MIB_MAX __ICMP6MSG_MIB_MAX +struct icmpv6msg_mib { + unsigned long mibs[ICMP6MSG_MIB_MAX]; +} __SNMP_MIB_ALIGN__; + + /* TCP */ #define TCP_MIB_MAX __TCP_MIB_MAX struct tcp_mib { diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index a68c626567f2..9c2e94f1c637 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -261,9 +261,15 @@ static int snmp6_alloc_dev(struct inet6_dev *idev) sizeof(struct icmpv6_mib), __alignof__(struct icmpv6_mib)) < 0) goto err_icmp; + if (snmp_mib_init((void **)idev->stats.icmpv6msg, + sizeof(struct icmpv6msg_mib), + __alignof__(struct icmpv6msg_mib)) < 0) + goto err_icmpmsg; return 0; +err_icmpmsg: + snmp_mib_free((void **)idev->stats.icmpv6); err_icmp: snmp_mib_free((void **)idev->stats.ipv6); err_ip: @@ -272,6 +278,7 @@ err_ip: static int snmp6_free_dev(struct inet6_dev *idev) { + snmp_mib_free((void **)idev->stats.icmpv6msg); snmp_mib_free((void **)idev->stats.icmpv6); snmp_mib_free((void **)idev->stats.ipv6); return 0; diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c index e5c5aad44bb1..bc929381fa46 100644 --- a/net/ipv6/af_inet6.c +++ b/net/ipv6/af_inet6.c @@ -719,6 +719,9 @@ static int __init init_ipv6_mibs(void) if (snmp_mib_init((void **)icmpv6_statistics, sizeof (struct icmpv6_mib), __alignof__(struct icmpv6_mib)) < 0) goto err_icmp_mib; + if (snmp_mib_init((void **)icmpv6msg_statistics, + sizeof (struct icmpv6msg_mib), __alignof__(struct icmpv6_mib)) < 0) + goto err_icmpmsg_mib; if (snmp_mib_init((void **)udp_stats_in6, sizeof (struct udp_mib), __alignof__(struct udp_mib)) < 0) goto err_udp_mib; @@ -730,6 +733,8 @@ static int __init init_ipv6_mibs(void) err_udplite_mib: snmp_mib_free((void **)udp_stats_in6); err_udp_mib: + snmp_mib_free((void **)icmpv6msg_statistics); +err_icmpmsg_mib: snmp_mib_free((void **)icmpv6_statistics); err_icmp_mib: snmp_mib_free((void **)ipv6_statistics); diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c index 6a6714d154ed..47b8ce232e84 100644 --- a/net/ipv6/icmp.c +++ b/net/ipv6/icmp.c @@ -69,6 +69,8 @@ DEFINE_SNMP_STAT(struct icmpv6_mib, icmpv6_statistics) __read_mostly; EXPORT_SYMBOL(icmpv6_statistics); +DEFINE_SNMP_STAT(struct icmpv6msg_mib, icmpv6msg_statistics) __read_mostly; +EXPORT_SYMBOL(icmpv6msg_statistics); /* * The ICMP socket(s). This is the most convenient way to flow control @@ -456,8 +458,6 @@ void icmpv6_send(struct sk_buff *skb, int type, int code, __u32 info, } err = icmpv6_push_pending_frames(sk, &fl, &tmp_hdr, len + sizeof(struct icmp6hdr)); - if (type >= ICMPV6_DEST_UNREACH && type <= ICMPV6_PARAMPROB) - ICMP6_INC_STATS_OFFSET_BH(idev, ICMP6_MIB_OUTDESTUNREACHS, type - ICMPV6_DEST_UNREACH); ICMP6_INC_STATS_BH(idev, ICMP6_MIB_OUTMSGS); out_put: @@ -547,9 +547,6 @@ static void icmpv6_echo_reply(struct sk_buff *skb) } err = icmpv6_push_pending_frames(sk, &fl, &tmp_hdr, skb->len + sizeof(struct icmp6hdr)); - ICMP6_INC_STATS_BH(idev, ICMP6_MIB_OUTECHOREPLIES); - ICMP6_INC_STATS_BH(idev, ICMP6_MIB_OUTMSGS); - out_put: if (likely(idev != NULL)) in6_dev_put(idev); @@ -656,10 +653,7 @@ static int icmpv6_rcv(struct sk_buff **pskb) type = hdr->icmp6_type; - if (type >= ICMPV6_DEST_UNREACH && type <= ICMPV6_PARAMPROB) - ICMP6_INC_STATS_OFFSET_BH(idev, ICMP6_MIB_INDESTUNREACHS, type - ICMPV6_DEST_UNREACH); - else if (type >= ICMPV6_ECHO_REQUEST && type <= NDISC_REDIRECT) - ICMP6_INC_STATS_OFFSET_BH(idev, ICMP6_MIB_INECHOS, type - ICMPV6_ECHO_REQUEST); + ICMP6MSGIN_INC_STATS_BH(idev, type); switch (type) { case ICMPV6_ECHO_REQUEST: diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index e46d4683eab0..011082ed921a 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c @@ -1399,6 +1399,13 @@ int ip6_push_pending_frames(struct sock *sk) skb->dst = dst_clone(&rt->u.dst); IP6_INC_STATS(rt->rt6i_idev, IPSTATS_MIB_OUTREQUESTS); + if (proto == IPPROTO_ICMPV6) { + struct inet6_dev *idev = ip6_dst_idev(skb->dst); + + ICMP6MSGOUT_INC_STATS_BH(idev, icmp6_hdr(skb)->icmp6_type); + ICMP6_INC_STATS_BH(idev, ICMP6_MIB_OUTMSGS); + } + err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, skb->dst->dev, dst_output); if (err) { if (err > 0) diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c index e2ab43c989d4..86d908b1caea 100644 --- a/net/ipv6/mcast.c +++ b/net/ipv6/mcast.c @@ -1479,10 +1479,11 @@ static void mld_sendpack(struct sk_buff *skb) err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, skb->dev, mld_dev_queue_xmit); if (!err) { - ICMP6_INC_STATS(idev,ICMP6_MIB_OUTMSGS); - IP6_INC_STATS(idev, IPSTATS_MIB_OUTMCASTPKTS); + ICMP6MSGOUT_INC_STATS_BH(idev, ICMPV6_MLD2_REPORT); + ICMP6_INC_STATS_BH(idev, ICMP6_MIB_OUTMSGS); + IP6_INC_STATS_BH(idev, IPSTATS_MIB_OUTMCASTPKTS); } else - IP6_INC_STATS(idev, IPSTATS_MIB_OUTDISCARDS); + IP6_INC_STATS_BH(idev, IPSTATS_MIB_OUTDISCARDS); if (likely(idev != NULL)) in6_dev_put(idev); @@ -1822,10 +1823,7 @@ static void igmp6_send(struct in6_addr *addr, struct net_device *dev, int type) err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, skb->dev, mld_dev_queue_xmit); if (!err) { - if (type == ICMPV6_MGM_REDUCTION) - ICMP6_INC_STATS(idev, ICMP6_MIB_OUTGROUPMEMBREDUCTIONS); - else - ICMP6_INC_STATS(idev, ICMP6_MIB_OUTGROUPMEMBRESPONSES); + ICMP6MSGOUT_INC_STATS(idev, type); ICMP6_INC_STATS(idev, ICMP6_MIB_OUTMSGS); IP6_INC_STATS(idev, IPSTATS_MIB_OUTMCASTPKTS); } else diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c index d2d44dc22f19..7ea5a502ca08 100644 --- a/net/ipv6/ndisc.c +++ b/net/ipv6/ndisc.c @@ -431,7 +431,7 @@ static void __ndisc_send(struct net_device *dev, struct neighbour *neigh, struct in6_addr *daddr, struct in6_addr *saddr, struct icmp6hdr *icmp6h, struct in6_addr *target, - int llinfo, int icmp6_mib_outnd) + int llinfo) { struct flowi fl; struct dst_entry *dst; @@ -441,9 +441,11 @@ static void __ndisc_send(struct net_device *dev, struct inet6_dev *idev; int len; int err; - u8 *opt; + u8 *opt, type; + + type = icmp6h->icmp6_type; - ndisc_flow_init(&fl, icmp6h->icmp6_type, saddr, daddr, + ndisc_flow_init(&fl, type, saddr, daddr, dev->ifindex); dst = ndisc_dst_alloc(dev, neigh, daddr, ip6_output); @@ -504,7 +506,7 @@ static void __ndisc_send(struct net_device *dev, err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, dst->dev, dst_output); if (!err) { - ICMP6_INC_STATS(idev, icmp6_mib_outnd); + ICMP6MSGOUT_INC_STATS(idev, type); ICMP6_INC_STATS(idev, ICMP6_MIB_OUTMSGS); } @@ -542,8 +544,7 @@ static void ndisc_send_na(struct net_device *dev, struct neighbour *neigh, __ndisc_send(dev, neigh, daddr, src_addr, &icmp6h, solicited_addr, - inc_opt ? ND_OPT_TARGET_LL_ADDR : 0, - ICMP6_MIB_OUTNEIGHBORADVERTISEMENTS); + inc_opt ? ND_OPT_TARGET_LL_ADDR : 0); } void ndisc_send_ns(struct net_device *dev, struct neighbour *neigh, @@ -564,8 +565,7 @@ void ndisc_send_ns(struct net_device *dev, struct neighbour *neigh, __ndisc_send(dev, neigh, daddr, saddr, &icmp6h, solicit, - !ipv6_addr_any(saddr) ? ND_OPT_SOURCE_LL_ADDR : 0, - ICMP6_MIB_OUTNEIGHBORSOLICITS); + !ipv6_addr_any(saddr) ? ND_OPT_SOURCE_LL_ADDR : 0); } void ndisc_send_rs(struct net_device *dev, struct in6_addr *saddr, @@ -599,8 +599,7 @@ void ndisc_send_rs(struct net_device *dev, struct in6_addr *saddr, #endif __ndisc_send(dev, NULL, daddr, saddr, &icmp6h, NULL, - send_sllao ? ND_OPT_SOURCE_LL_ADDR : 0, - ICMP6_MIB_OUTROUTERSOLICITS); + send_sllao ? ND_OPT_SOURCE_LL_ADDR : 0); } @@ -1455,7 +1454,7 @@ void ndisc_send_redirect(struct sk_buff *skb, struct neighbour *neigh, IP6_INC_STATS(idev, IPSTATS_MIB_OUTREQUESTS); err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, buff, NULL, dst->dev, dst_output); if (!err) { - ICMP6_INC_STATS(idev, ICMP6_MIB_OUTREDIRECTS); + ICMP6MSGOUT_INC_STATS(idev, NDISC_REDIRECT); ICMP6_INC_STATS(idev, ICMP6_MIB_OUTMSGS); } diff --git a/net/ipv6/proc.c b/net/ipv6/proc.c index a712a2289484..db945018579e 100644 --- a/net/ipv6/proc.c +++ b/net/ipv6/proc.c @@ -86,47 +86,33 @@ static struct snmp_mib snmp6_ipstats_list[] = { }; static struct snmp_mib snmp6_icmp6_list[] = { -/* icmpv6 mib according to RFC 2466 - - Exceptions: {In|Out}AdminProhibs are removed, because I see - no good reasons to account them separately - of another dest.unreachs. - OutErrs is zero identically. - OutEchos too. - OutRouterAdvertisements too. - OutGroupMembQueries too. - */ +/* icmpv6 mib according to RFC 2466 */ SNMP_MIB_ITEM("Icmp6InMsgs", ICMP6_MIB_INMSGS), SNMP_MIB_ITEM("Icmp6InErrors", ICMP6_MIB_INERRORS), - SNMP_MIB_ITEM("Icmp6InDestUnreachs", ICMP6_MIB_INDESTUNREACHS), - SNMP_MIB_ITEM("Icmp6InPktTooBigs", ICMP6_MIB_INPKTTOOBIGS), - SNMP_MIB_ITEM("Icmp6InTimeExcds", ICMP6_MIB_INTIMEEXCDS), - SNMP_MIB_ITEM("Icmp6InParmProblems", ICMP6_MIB_INPARMPROBLEMS), - SNMP_MIB_ITEM("Icmp6InEchos", ICMP6_MIB_INECHOS), - SNMP_MIB_ITEM("Icmp6InEchoReplies", ICMP6_MIB_INECHOREPLIES), - SNMP_MIB_ITEM("Icmp6InGroupMembQueries", ICMP6_MIB_INGROUPMEMBQUERIES), - SNMP_MIB_ITEM("Icmp6InGroupMembResponses", ICMP6_MIB_INGROUPMEMBRESPONSES), - SNMP_MIB_ITEM("Icmp6InGroupMembReductions", ICMP6_MIB_INGROUPMEMBREDUCTIONS), - SNMP_MIB_ITEM("Icmp6InRouterSolicits", ICMP6_MIB_INROUTERSOLICITS), - SNMP_MIB_ITEM("Icmp6InRouterAdvertisements", ICMP6_MIB_INROUTERADVERTISEMENTS), - SNMP_MIB_ITEM("Icmp6InNeighborSolicits", ICMP6_MIB_INNEIGHBORSOLICITS), - SNMP_MIB_ITEM("Icmp6InNeighborAdvertisements", ICMP6_MIB_INNEIGHBORADVERTISEMENTS), - SNMP_MIB_ITEM("Icmp6InRedirects", ICMP6_MIB_INREDIRECTS), SNMP_MIB_ITEM("Icmp6OutMsgs", ICMP6_MIB_OUTMSGS), - SNMP_MIB_ITEM("Icmp6OutDestUnreachs", ICMP6_MIB_OUTDESTUNREACHS), - SNMP_MIB_ITEM("Icmp6OutPktTooBigs", ICMP6_MIB_OUTPKTTOOBIGS), - SNMP_MIB_ITEM("Icmp6OutTimeExcds", ICMP6_MIB_OUTTIMEEXCDS), - SNMP_MIB_ITEM("Icmp6OutParmProblems", ICMP6_MIB_OUTPARMPROBLEMS), - SNMP_MIB_ITEM("Icmp6OutEchoReplies", ICMP6_MIB_OUTECHOREPLIES), - SNMP_MIB_ITEM("Icmp6OutRouterSolicits", ICMP6_MIB_OUTROUTERSOLICITS), - SNMP_MIB_ITEM("Icmp6OutNeighborSolicits", ICMP6_MIB_OUTNEIGHBORSOLICITS), - SNMP_MIB_ITEM("Icmp6OutNeighborAdvertisements", ICMP6_MIB_OUTNEIGHBORADVERTISEMENTS), - SNMP_MIB_ITEM("Icmp6OutRedirects", ICMP6_MIB_OUTREDIRECTS), - SNMP_MIB_ITEM("Icmp6OutGroupMembResponses", ICMP6_MIB_OUTGROUPMEMBRESPONSES), - SNMP_MIB_ITEM("Icmp6OutGroupMembReductions", ICMP6_MIB_OUTGROUPMEMBREDUCTIONS), SNMP_MIB_SENTINEL }; +/* RFC 4293 v6 ICMPMsgStatsTable; named items for RFC 2466 compatibility */ +static char *icmp6type2name[256] = { + [ICMPV6_DEST_UNREACH] = "DestUnreachs", + [ICMPV6_PKT_TOOBIG] = "PktTooBigs", + [ICMPV6_TIME_EXCEED] = "TimeExcds", + [ICMPV6_PARAMPROB] = "ParmProblems", + [ICMPV6_ECHO_REQUEST] = "EchoRequest", + [ICMPV6_ECHO_REPLY] = "EchoReplies", + [ICMPV6_MGM_QUERY] = "GroupMembQueries", + [ICMPV6_MGM_REPORT] = "GroupMembResponses", + [ICMPV6_MGM_REDUCTION] = "GroupMembReductions", + [ICMPV6_MLD2_REPORT] = "MLDv2Reports", + [NDISC_ROUTER_ADVERTISEMENT] = "RouterAdvertisements", + [NDISC_ROUTER_SOLICITATION] = "RouterSolicits", + [NDISC_NEIGHBOUR_ADVERTISEMENT] = "NeighborAdvertisements", + [NDISC_NEIGHBOUR_SOLICITATION] = "NeighborSolicits", + [NDISC_REDIRECT] = "NeighborRedirects", +}; + + static struct snmp_mib snmp6_udp6_list[] = { SNMP_MIB_ITEM("Udp6InDatagrams", UDP_MIB_INDATAGRAMS), SNMP_MIB_ITEM("Udp6NoPorts", UDP_MIB_NOPORTS), @@ -143,6 +129,40 @@ static struct snmp_mib snmp6_udplite6_list[] = { SNMP_MIB_SENTINEL }; +static void snmp6_seq_show_icmpv6msg(struct seq_file *seq, void **mib) +{ + static char name[32]; + int i; + + /* print by name -- deprecated items */ + for (i = 0; i < ICMP6MSG_MIB_MAX; i++) { + int icmptype; + char *p; + + icmptype = i & 0xff; + p = icmp6type2name[icmptype]; + if (!p) /* don't print un-named types here */ + continue; + (void) snprintf(name, sizeof(name)-1, "Icmp6%s%s", + i & 0x100 ? "Out" : "In", p); + seq_printf(seq, "%-32s\t%lu\n", name, + snmp_fold_field(mib, i)); + } + + /* print by number (nonzero only) - ICMPMsgStat format */ + for (i = 0; i < ICMP6MSG_MIB_MAX; i++) { + unsigned long val; + + val = snmp_fold_field(mib, i); + if (!val) + continue; + (void) snprintf(name, sizeof(name)-1, "Icmp6%sType%u", + i & 0x100 ? "Out" : "In", i & 0xff); + seq_printf(seq, "%-32s\t%lu\n", name, val); + } + return; +} + static inline void snmp6_seq_show_item(struct seq_file *seq, void **mib, struct snmp_mib *itemlist) { @@ -160,9 +180,11 @@ static int snmp6_seq_show(struct seq_file *seq, void *v) seq_printf(seq, "%-32s\t%u\n", "ifIndex", idev->dev->ifindex); snmp6_seq_show_item(seq, (void **)idev->stats.ipv6, snmp6_ipstats_list); snmp6_seq_show_item(seq, (void **)idev->stats.icmpv6, snmp6_icmp6_list); + snmp6_seq_show_icmpv6msg(seq, (void **)idev->stats.icmpv6msg); } else { snmp6_seq_show_item(seq, (void **)ipv6_statistics, snmp6_ipstats_list); snmp6_seq_show_item(seq, (void **)icmpv6_statistics, snmp6_icmp6_list); + snmp6_seq_show_icmpv6msg(seq, (void **)icmpv6msg_statistics); snmp6_seq_show_item(seq, (void **)udp_stats_in6, snmp6_udp6_list); snmp6_seq_show_item(seq, (void **)udplite_stats_in6, snmp6_udplite6_list); } -- cgit v1.2.3 From 96793b482540f3a26e2188eaf75cb56b7829d3e3 Mon Sep 17 00:00:00 2001 From: David L Stevens Date: Mon, 17 Sep 2007 09:57:33 -0700 Subject: [IPV4]: Add ICMPMsgStats MIB (RFC 4293) Background: RFC 4293 deprecates existing individual, named ICMP type counters to be replaced with the ICMPMsgStatsTable. This table includes entries for both IPv4 and IPv6, and requires counting of all ICMP types, whether or not the machine implements the type. These patches "remove" (but not really) the existing counters, and replace them with the ICMPMsgStats tables for v4 and v6. It includes the named counters in the /proc places they were, but gets the values for them from the new tables. It also counts packets generated from raw socket output (e.g., OutEchoes, MLD queries, RA's from radvd, etc). Changes: 1) create icmpmsg_statistics mib 2) create icmpv6msg_statistics mib 3) modify existing counters to use these 4) modify /proc/net/snmp to add "IcmpMsg" with all ICMP types listed by number for easy SNMP parsing 5) modify /proc/net/snmp printing for "Icmp" to get the named data from new counters. Signed-off-by: David L Stevens Signed-off-by: David S. Miller --- include/linux/snmp.h | 2 + include/net/icmp.h | 8 ++++ include/net/snmp.h | 5 +++ net/ipv4/af_inet.c | 6 +++ net/ipv4/icmp.c | 53 +++-------------------- net/ipv4/ip_output.c | 4 ++ net/ipv4/proc.c | 120 ++++++++++++++++++++++++++++++++++++++------------- net/ipv4/raw.c | 3 ++ 8 files changed, 123 insertions(+), 78 deletions(-) (limited to 'include/linux') diff --git a/include/linux/snmp.h b/include/linux/snmp.h index 86977e31548a..d8fd3ec4148a 100644 --- a/include/linux/snmp.h +++ b/include/linux/snmp.h @@ -82,6 +82,8 @@ enum __ICMP_MIB_MAX }; +#define __ICMPMSG_MIB_MAX 512 /* Out+In for all 8-bit ICMP types */ + /* icmp6 mib definitions */ /* * RFC 2466: ICMPv6-MIB diff --git a/include/net/icmp.h b/include/net/icmp.h index dc09474efcf3..9f7ef3c8baef 100644 --- a/include/net/icmp.h +++ b/include/net/icmp.h @@ -30,9 +30,16 @@ struct icmp_err { extern struct icmp_err icmp_err_convert[]; DECLARE_SNMP_STAT(struct icmp_mib, icmp_statistics); +DECLARE_SNMP_STAT(struct icmpmsg_mib, icmpmsg_statistics); #define ICMP_INC_STATS(field) SNMP_INC_STATS(icmp_statistics, field) #define ICMP_INC_STATS_BH(field) SNMP_INC_STATS_BH(icmp_statistics, field) #define ICMP_INC_STATS_USER(field) SNMP_INC_STATS_USER(icmp_statistics, field) +#define ICMPMSGOUT_INC_STATS(field) SNMP_INC_STATS(icmpmsg_statistics, field+256) +#define ICMPMSGOUT_INC_STATS_BH(field) SNMP_INC_STATS_BH(icmpmsg_statistics, field+256) +#define ICMPMSGOUT_INC_STATS_USER(field) SNMP_INC_STATS_USER(icmpmsg_statistics, field+256) +#define ICMPMSGIN_INC_STATS(field) SNMP_INC_STATS(icmpmsg_statistics, field) +#define ICMPMSGIN_INC_STATS_BH(field) SNMP_INC_STATS_BH(icmpmsg_statistics, field) +#define ICMPMSGIN_INC_STATS_USER(field) SNMP_INC_STATS_USER(icmpmsg_statistics, field) struct dst_entry; struct net_proto_family; @@ -42,6 +49,7 @@ extern void icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info); extern int icmp_rcv(struct sk_buff *skb); extern int icmp_ioctl(struct sock *sk, int cmd, unsigned long arg); extern void icmp_init(struct net_proto_family *ops); +extern void icmp_out_count(unsigned char type); /* Move into dst.h ? */ extern int xrlim_allow(struct dst_entry *dst, int timeout); diff --git a/include/net/snmp.h b/include/net/snmp.h index a566e11d2f98..ea206bff0dc4 100644 --- a/include/net/snmp.h +++ b/include/net/snmp.h @@ -82,6 +82,11 @@ struct icmp_mib { unsigned long mibs[ICMP_MIB_MAX]; } __SNMP_MIB_ALIGN__; +#define ICMPMSG_MIB_MAX __ICMPMSG_MIB_MAX +struct icmpmsg_mib { + unsigned long mibs[ICMPMSG_MIB_MAX]; +} __SNMP_MIB_ALIGN__; + /* ICMP6 (IPv6-ICMP) */ #define ICMP6_MIB_MAX __ICMP6_MIB_MAX struct icmpv6_mib { diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c index e594a2c89661..621b128897d7 100644 --- a/net/ipv4/af_inet.c +++ b/net/ipv4/af_inet.c @@ -1302,6 +1302,10 @@ static int __init init_ipv4_mibs(void) sizeof(struct icmp_mib), __alignof__(struct icmp_mib)) < 0) goto err_icmp_mib; + if (snmp_mib_init((void **)icmpmsg_statistics, + sizeof(struct icmpmsg_mib), + __alignof__(struct icmpmsg_mib)) < 0) + goto err_icmpmsg_mib; if (snmp_mib_init((void **)tcp_statistics, sizeof(struct tcp_mib), __alignof__(struct tcp_mib)) < 0) @@ -1324,6 +1328,8 @@ err_udplite_mib: err_udp_mib: snmp_mib_free((void **)tcp_statistics); err_tcp_mib: + snmp_mib_free((void **)icmpmsg_statistics); +err_icmpmsg_mib: snmp_mib_free((void **)icmp_statistics); err_icmp_mib: snmp_mib_free((void **)ip_statistics); diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c index 68a22670f597..272c69e106e9 100644 --- a/net/ipv4/icmp.c +++ b/net/ipv4/icmp.c @@ -115,6 +115,7 @@ struct icmp_bxm { * Statistics */ DEFINE_SNMP_STAT(struct icmp_mib, icmp_statistics) __read_mostly; +DEFINE_SNMP_STAT(struct icmpmsg_mib, icmpmsg_statistics) __read_mostly; /* An array of errno for error messages from dest unreach. */ /* RFC 1122: 3.2.2.1 States that NET_UNREACH, HOST_UNREACH and SR_FAILED MUST be considered 'transient errs'. */ @@ -214,8 +215,6 @@ int sysctl_icmp_errors_use_inbound_ifaddr __read_mostly; */ struct icmp_control { - int output_entry; /* Field for increment on output */ - int input_entry; /* Field for increment on input */ void (*handler)(struct sk_buff *skb); short error; /* This ICMP is classed as an error message */ }; @@ -316,12 +315,10 @@ out: /* * Maintain the counters used in the SNMP statistics for outgoing ICMP */ -static void icmp_out_count(int type) +void icmp_out_count(unsigned char type) { - if (type <= NR_ICMP_TYPES) { - ICMP_INC_STATS(icmp_pointers[type].output_entry); - ICMP_INC_STATS(ICMP_MIB_OUTMSGS); - } + ICMPMSGOUT_INC_STATS(type); + ICMP_INC_STATS(ICMP_MIB_OUTMSGS); } /* @@ -390,7 +387,6 @@ static void icmp_reply(struct icmp_bxm *icmp_param, struct sk_buff *skb) return; icmp_param->data.icmph.checksum = 0; - icmp_out_count(icmp_param->data.icmph.type); inet->tos = ip_hdr(skb)->tos; daddr = ipc.addr = rt->rt_src; @@ -952,6 +948,7 @@ int icmp_rcv(struct sk_buff *skb) icmph = icmp_hdr(skb); + ICMPMSGIN_INC_STATS_BH(icmph->type); /* * 18 is the highest 'known' ICMP type. Anything else is a mystery * @@ -986,7 +983,6 @@ int icmp_rcv(struct sk_buff *skb) } } - ICMP_INC_STATS_BH(icmp_pointers[icmph->type].input_entry); icmp_pointers[icmph->type].handler(skb); drop: @@ -1002,109 +998,71 @@ error: */ static const struct icmp_control icmp_pointers[NR_ICMP_TYPES + 1] = { [ICMP_ECHOREPLY] = { - .output_entry = ICMP_MIB_OUTECHOREPS, - .input_entry = ICMP_MIB_INECHOREPS, .handler = icmp_discard, }, [1] = { - .output_entry = ICMP_MIB_DUMMY, - .input_entry = ICMP_MIB_INERRORS, .handler = icmp_discard, .error = 1, }, [2] = { - .output_entry = ICMP_MIB_DUMMY, - .input_entry = ICMP_MIB_INERRORS, .handler = icmp_discard, .error = 1, }, [ICMP_DEST_UNREACH] = { - .output_entry = ICMP_MIB_OUTDESTUNREACHS, - .input_entry = ICMP_MIB_INDESTUNREACHS, .handler = icmp_unreach, .error = 1, }, [ICMP_SOURCE_QUENCH] = { - .output_entry = ICMP_MIB_OUTSRCQUENCHS, - .input_entry = ICMP_MIB_INSRCQUENCHS, .handler = icmp_unreach, .error = 1, }, [ICMP_REDIRECT] = { - .output_entry = ICMP_MIB_OUTREDIRECTS, - .input_entry = ICMP_MIB_INREDIRECTS, .handler = icmp_redirect, .error = 1, }, [6] = { - .output_entry = ICMP_MIB_DUMMY, - .input_entry = ICMP_MIB_INERRORS, .handler = icmp_discard, .error = 1, }, [7] = { - .output_entry = ICMP_MIB_DUMMY, - .input_entry = ICMP_MIB_INERRORS, .handler = icmp_discard, .error = 1, }, [ICMP_ECHO] = { - .output_entry = ICMP_MIB_OUTECHOS, - .input_entry = ICMP_MIB_INECHOS, .handler = icmp_echo, }, [9] = { - .output_entry = ICMP_MIB_DUMMY, - .input_entry = ICMP_MIB_INERRORS, .handler = icmp_discard, .error = 1, }, [10] = { - .output_entry = ICMP_MIB_DUMMY, - .input_entry = ICMP_MIB_INERRORS, .handler = icmp_discard, .error = 1, }, [ICMP_TIME_EXCEEDED] = { - .output_entry = ICMP_MIB_OUTTIMEEXCDS, - .input_entry = ICMP_MIB_INTIMEEXCDS, .handler = icmp_unreach, .error = 1, }, [ICMP_PARAMETERPROB] = { - .output_entry = ICMP_MIB_OUTPARMPROBS, - .input_entry = ICMP_MIB_INPARMPROBS, .handler = icmp_unreach, .error = 1, }, [ICMP_TIMESTAMP] = { - .output_entry = ICMP_MIB_OUTTIMESTAMPS, - .input_entry = ICMP_MIB_INTIMESTAMPS, .handler = icmp_timestamp, }, [ICMP_TIMESTAMPREPLY] = { - .output_entry = ICMP_MIB_OUTTIMESTAMPREPS, - .input_entry = ICMP_MIB_INTIMESTAMPREPS, .handler = icmp_discard, }, [ICMP_INFO_REQUEST] = { - .output_entry = ICMP_MIB_DUMMY, - .input_entry = ICMP_MIB_DUMMY, .handler = icmp_discard, }, [ICMP_INFO_REPLY] = { - .output_entry = ICMP_MIB_DUMMY, - .input_entry = ICMP_MIB_DUMMY, .handler = icmp_discard, }, [ICMP_ADDRESS] = { - .output_entry = ICMP_MIB_OUTADDRMASKS, - .input_entry = ICMP_MIB_INADDRMASKS, .handler = icmp_address, }, [ICMP_ADDRESSREPLY] = { - .output_entry = ICMP_MIB_OUTADDRMASKREPS, - .input_entry = ICMP_MIB_INADDRMASKREPS, .handler = icmp_address_reply, }, }; @@ -1146,4 +1104,5 @@ void __init icmp_init(struct net_proto_family *ops) EXPORT_SYMBOL(icmp_err_convert); EXPORT_SYMBOL(icmp_send); EXPORT_SYMBOL(icmp_statistics); +EXPORT_SYMBOL(icmpmsg_statistics); EXPORT_SYMBOL(xrlim_allow); diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c index 0f1d7beacf78..77f67b7cb9bf 100644 --- a/net/ipv4/ip_output.c +++ b/net/ipv4/ip_output.c @@ -1261,6 +1261,10 @@ int ip_push_pending_frames(struct sock *sk) skb->priority = sk->sk_priority; skb->dst = dst_clone(&rt->u.dst); + if (iph->protocol == IPPROTO_ICMP) + icmp_out_count(((struct icmphdr *) + skb_transport_header(skb))->type); + /* Netfilter gets whole the not fragmented skb. */ err = NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, skb, NULL, skb->dst->dev, dst_output); diff --git a/net/ipv4/proc.c b/net/ipv4/proc.c index 95a8f8f2de71..2015148b41a8 100644 --- a/net/ipv4/proc.c +++ b/net/ipv4/proc.c @@ -124,33 +124,30 @@ static const struct snmp_mib snmp4_ipextstats_list[] = { static const struct snmp_mib snmp4_icmp_list[] = { SNMP_MIB_ITEM("InMsgs", ICMP_MIB_INMSGS), SNMP_MIB_ITEM("InErrors", ICMP_MIB_INERRORS), - SNMP_MIB_ITEM("InDestUnreachs", ICMP_MIB_INDESTUNREACHS), - SNMP_MIB_ITEM("InTimeExcds", ICMP_MIB_INTIMEEXCDS), - SNMP_MIB_ITEM("InParmProbs", ICMP_MIB_INPARMPROBS), - SNMP_MIB_ITEM("InSrcQuenchs", ICMP_MIB_INSRCQUENCHS), - SNMP_MIB_ITEM("InRedirects", ICMP_MIB_INREDIRECTS), - SNMP_MIB_ITEM("InEchos", ICMP_MIB_INECHOS), - SNMP_MIB_ITEM("InEchoReps", ICMP_MIB_INECHOREPS), - SNMP_MIB_ITEM("InTimestamps", ICMP_MIB_INTIMESTAMPS), - SNMP_MIB_ITEM("InTimestampReps", ICMP_MIB_INTIMESTAMPREPS), - SNMP_MIB_ITEM("InAddrMasks", ICMP_MIB_INADDRMASKS), - SNMP_MIB_ITEM("InAddrMaskReps", ICMP_MIB_INADDRMASKREPS), SNMP_MIB_ITEM("OutMsgs", ICMP_MIB_OUTMSGS), SNMP_MIB_ITEM("OutErrors", ICMP_MIB_OUTERRORS), - SNMP_MIB_ITEM("OutDestUnreachs", ICMP_MIB_OUTDESTUNREACHS), - SNMP_MIB_ITEM("OutTimeExcds", ICMP_MIB_OUTTIMEEXCDS), - SNMP_MIB_ITEM("OutParmProbs", ICMP_MIB_OUTPARMPROBS), - SNMP_MIB_ITEM("OutSrcQuenchs", ICMP_MIB_OUTSRCQUENCHS), - SNMP_MIB_ITEM("OutRedirects", ICMP_MIB_OUTREDIRECTS), - SNMP_MIB_ITEM("OutEchos", ICMP_MIB_OUTECHOS), - SNMP_MIB_ITEM("OutEchoReps", ICMP_MIB_OUTECHOREPS), - SNMP_MIB_ITEM("OutTimestamps", ICMP_MIB_OUTTIMESTAMPS), - SNMP_MIB_ITEM("OutTimestampReps", ICMP_MIB_OUTTIMESTAMPREPS), - SNMP_MIB_ITEM("OutAddrMasks", ICMP_MIB_OUTADDRMASKS), - SNMP_MIB_ITEM("OutAddrMaskReps", ICMP_MIB_OUTADDRMASKREPS), SNMP_MIB_SENTINEL }; +static struct { + char *name; + int index; +} icmpmibmap[] = { + { "DestUnreachs", ICMP_DEST_UNREACH }, + { "TimeExcds", ICMP_TIME_EXCEEDED }, + { "ParmProbs", ICMP_PARAMETERPROB }, + { "SrcQuenchs", ICMP_SOURCE_QUENCH }, + { "Redirects", ICMP_REDIRECT }, + { "Echos", ICMP_ECHO }, + { "EchoReps", ICMP_ECHOREPLY }, + { "Timestamps", ICMP_TIMESTAMP }, + { "TimestampReps", ICMP_TIMESTAMPREPLY }, + { "AddrMasks", ICMP_ADDRESS }, + { "AddrMaskReps", ICMP_ADDRESSREPLY }, + { 0, 0 } +}; + + static const struct snmp_mib snmp4_tcp_list[] = { SNMP_MIB_ITEM("RtoAlgorithm", TCP_MIB_RTOALGORITHM), SNMP_MIB_ITEM("RtoMin", TCP_MIB_RTOMIN), @@ -251,6 +248,72 @@ static const struct snmp_mib snmp4_net_list[] = { SNMP_MIB_SENTINEL }; +static void icmpmsg_put(struct seq_file *seq) +{ +#define PERLINE 16 + + int j, i, count; + static int out[PERLINE]; + + count = 0; + for (i = 0; i < ICMPMSG_MIB_MAX; i++) { + + if (snmp_fold_field((void **) icmpmsg_statistics, i)) + out[count++] = i; + if (count < PERLINE) + continue; + + seq_printf(seq, "\nIcmpMsg:"); + for (j = 0; j < PERLINE; ++j) + seq_printf(seq, " %sType%u", i & 0x100 ? "Out" : "In", + i & 0xff); + seq_printf(seq, "\nIcmpMsg: "); + for (j = 0; j < PERLINE; ++j) + seq_printf(seq, " %lu", + snmp_fold_field((void **) icmpmsg_statistics, + out[j])); + seq_putc(seq, '\n'); + } + if (count) { + seq_printf(seq, "\nIcmpMsg:"); + for (j = 0; j < count; ++j) + seq_printf(seq, " %sType%u", out[j] & 0x100 ? "Out" : + "In", out[j] & 0xff); + seq_printf(seq, "\nIcmpMsg:"); + for (j = 0; j < count; ++j) + seq_printf(seq, " %lu", snmp_fold_field((void **) + icmpmsg_statistics, out[j])); + } + +#undef PERLINE +} + +static void icmp_put(struct seq_file *seq) +{ + int i; + + seq_puts(seq, "\nIcmp: InMsgs InErrors"); + for (i=0; icmpmibmap[i].name != NULL; i++) + seq_printf(seq, " In%s", icmpmibmap[i].name); + seq_printf(seq, " OutMsgs OutErrors"); + for (i=0; icmpmibmap[i].name != NULL; i++) + seq_printf(seq, " Out%s", icmpmibmap[i].name); + seq_printf(seq, "\nIcmp: %lu %lu", + snmp_fold_field((void **) icmp_statistics, ICMP_MIB_INMSGS), + snmp_fold_field((void **) icmp_statistics, ICMP_MIB_INERRORS)); + for (i=0; icmpmibmap[i].name != NULL; i++) + seq_printf(seq, " %lu", + snmp_fold_field((void **) icmpmsg_statistics, + icmpmibmap[i].index)); + seq_printf(seq, " %lu %lu", + snmp_fold_field((void **) icmp_statistics, ICMP_MIB_OUTMSGS), + snmp_fold_field((void **) icmp_statistics, ICMP_MIB_OUTERRORS)); + for (i=0; icmpmibmap[i].name != NULL; i++) + seq_printf(seq, " %lu", + snmp_fold_field((void **) icmpmsg_statistics, + icmpmibmap[i].index)); +} + /* * Called from the PROCfs module. This outputs /proc/net/snmp. */ @@ -271,15 +334,8 @@ static int snmp_seq_show(struct seq_file *seq, void *v) snmp_fold_field((void **)ip_statistics, snmp4_ipstats_list[i].entry)); - seq_puts(seq, "\nIcmp:"); - for (i = 0; snmp4_icmp_list[i].name != NULL; i++) - seq_printf(seq, " %s", snmp4_icmp_list[i].name); - - seq_puts(seq, "\nIcmp:"); - for (i = 0; snmp4_icmp_list[i].name != NULL; i++) - seq_printf(seq, " %lu", - snmp_fold_field((void **)icmp_statistics, - snmp4_icmp_list[i].entry)); + icmp_put(seq); /* RFC 2011 compatibility */ + icmpmsg_put(seq); seq_puts(seq, "\nTcp:"); for (i = 0; snmp4_tcp_list[i].name != NULL; i++) @@ -336,6 +392,8 @@ static const struct file_operations snmp_seq_fops = { .release = single_release, }; + + /* * Output /proc/net/netstat */ diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c index 216e01b0f44a..07070c7067f3 100644 --- a/net/ipv4/raw.c +++ b/net/ipv4/raw.c @@ -314,6 +314,9 @@ static int raw_send_hdrinc(struct sock *sk, void *from, size_t length, iph->check = ip_fast_csum((unsigned char *)iph, iph->ihl); } + if (iph->protocol == IPPROTO_ICMP) + icmp_out_count(((struct icmphdr *) + skb_transport_header(skb))->type); err = NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, skb, NULL, rt->u.dst.dev, dst_output); -- cgit v1.2.3 From f7b0e93ba1a484700bd1b0e36bdaddaf4eb51b0b Mon Sep 17 00:00:00 2001 From: Vlad Yasevich Date: Sun, 16 Sep 2007 19:26:06 -0700 Subject: [SCTP]: protocol definitions for SCTP-AUTH implementation Signed-off-by: Vlad Yasevich Signed-off-by: David S. Miller --- include/linux/sctp.h | 100 ++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 99 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/sctp.h b/include/linux/sctp.h index f4d717b72ddd..5eb38cc0e5a4 100644 --- a/include/linux/sctp.h +++ b/include/linux/sctp.h @@ -102,6 +102,9 @@ typedef enum { SCTP_CID_ECN_CWR = 13, SCTP_CID_SHUTDOWN_COMPLETE = 14, + /* AUTH Extension Section 4.1 */ + SCTP_CID_AUTH = 0x0F, + /* PR-SCTP Sec 3.2 */ SCTP_CID_FWD_TSN = 0xC0, @@ -180,6 +183,11 @@ typedef enum { SCTP_PARAM_SUPPORTED_ADDRESS_TYPES = __constant_htons(12), SCTP_PARAM_ECN_CAPABLE = __constant_htons(0x8000), + /* AUTH Extension Section 3 */ + SCTP_PARAM_RANDOM = __constant_htons(0x8002), + SCTP_PARAM_CHUNKS = __constant_htons(0x8003), + SCTP_PARAM_HMAC_ALGO = __constant_htons(0x8004), + /* Add-IP: Supported Extensions, Section 4.2 */ SCTP_PARAM_SUPPORTED_EXT = __constant_htons(0x8008), @@ -305,6 +313,24 @@ typedef struct sctp_supported_ext_param { __u8 chunks[0]; } __attribute__((packed)) sctp_supported_ext_param_t; +/* AUTH Section 3.1 Random */ +typedef struct sctp_random_param { + sctp_paramhdr_t param_hdr; + __u8 random_val[0]; +} __attribute__((packed)) sctp_random_param_t; + +/* AUTH Section 3.2 Chunk List */ +typedef struct sctp_chunks_param { + sctp_paramhdr_t param_hdr; + __u8 chunks[0]; +} __attribute__((packed)) sctp_chunks_param_t; + +/* AUTH Section 3.3 HMAC Algorithm */ +typedef struct sctp_hmac_algo_param { + sctp_paramhdr_t param_hdr; + __be16 hmac_ids[0]; +} __attribute__((packed)) sctp_hmac_algo_param_t; + /* RFC 2960. Section 3.3.3 Initiation Acknowledgement (INIT ACK) (2): * The INIT ACK chunk is used to acknowledge the initiation of an SCTP * association. @@ -471,7 +497,19 @@ typedef enum { SCTP_ERROR_RSRC_LOW = __constant_htons(0x0101), SCTP_ERROR_DEL_SRC_IP = __constant_htons(0x0102), SCTP_ERROR_ASCONF_ACK = __constant_htons(0x0103), - SCTP_ERROR_REQ_REFUSED = __constant_htons(0x0104) + SCTP_ERROR_REQ_REFUSED = __constant_htons(0x0104), + + /* AUTH Section 4. New Error Cause + * + * This section defines a new error cause that will be sent if an AUTH + * chunk is received with an unsupported HMAC identifier. + * illustrates the new error cause. + * + * Cause Code Error Cause Name + * -------------------------------------------------------------- + * 0x0105 Unsupported HMAC Identifier + */ + SCTP_ERROR_UNSUP_HMAC = __constant_htons(0x0105) } sctp_error_t; @@ -609,4 +647,64 @@ typedef struct sctp_addip_chunk { sctp_addiphdr_t addip_hdr; } __attribute__((packed)) sctp_addip_chunk_t; +/* AUTH + * Section 4.1 Authentication Chunk (AUTH) + * + * This chunk is used to hold the result of the HMAC calculation. + * + * 0 1 2 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Type = 0x0F | Flags=0 | Length | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Shared Key Identifier | HMAC Identifier | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | | + * \ HMAC / + * / \ + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * + * Type: 1 byte (unsigned integer) + * This value MUST be set to 0x0F for all AUTH-chunks. + * + * Flags: 1 byte (unsigned integer) + * Set to zero on transmit and ignored on receipt. + * + * Length: 2 bytes (unsigned integer) + * This value holds the length of the HMAC in bytes plus 8. + * + * Shared Key Identifier: 2 bytes (unsigned integer) + * This value describes which endpoint pair shared key is used. + * + * HMAC Identifier: 2 bytes (unsigned integer) + * This value describes which message digest is being used. Table 2 + * shows the currently defined values. + * + * The following Table 2 shows the currently defined values for HMAC + * identifiers. + * + * +-----------------+--------------------------+ + * | HMAC Identifier | Message Digest Algorithm | + * +-----------------+--------------------------+ + * | 0 | Reserved | + * | 1 | SHA-1 defined in [8] | + * | 2 | Reserved | + * | 3 | SHA-256 defined in [8] | + * +-----------------+--------------------------+ + * + * + * HMAC: n bytes (unsigned integer) This hold the result of the HMAC + * calculation. + */ +typedef struct sctp_authhdr { + __be16 shkey_id; + __be16 hmac_id; + __u8 hmac[0]; +} __attribute__((packed)) sctp_authhdr_t; + +typedef struct sctp_auth_chunk { + sctp_chunkhdr_t chunk_hdr; + sctp_authhdr_t auth_hdr; +} __attribute__((packed)) sctp_auth_chunk_t; + #endif /* __LINUX_SCTP_H__ */ -- cgit v1.2.3 From 1202d6ff356cc66dc8d2b85546eb4f187f9e1f25 Mon Sep 17 00:00:00 2001 From: Francois Romieu Date: Mon, 17 Sep 2007 17:13:55 -0700 Subject: [IPG]: add IP1000A driver to kernel tree Signed-off-by: Jesse Huang Signed-off-by: Stefan Lippers-Hollmann Signed-off-by: Francois Romieu Signed-off-by: Andrew Morton Signed-off-by: David S. Miller --- MAINTAINERS | 10 + drivers/net/Kconfig | 9 + drivers/net/Makefile | 1 + drivers/net/ipg.c | 2326 +++++++++++++++++++++++++++++++++++++++++++++++ drivers/net/ipg.h | 856 +++++++++++++++++ include/linux/pci_ids.h | 2 + 6 files changed, 3204 insertions(+) create mode 100644 drivers/net/ipg.c create mode 100644 drivers/net/ipg.h (limited to 'include/linux') diff --git a/MAINTAINERS b/MAINTAINERS index c35eb125e1ca..27cd503cf0e4 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2081,6 +2081,16 @@ P: Juanjo Ciarlante M: jjciarla@raiz.uncu.edu.ar S: Maintained +IP1000A 10/100/1000 GIGABIT ETHERNET DRIVER +P: Francois Romieu +M: romieu@fr.zoreil.com +P: Sorbica Shieh +M: sorbica@icplus.com.tw +P: Jesse Huang +M: jesse@icplus.com.tw +L: netdev@vger.kernel.org +S: Maintained + IPATH DRIVER: P: Arthur Jones M: infinipath@qlogic.com diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 76db0bc9452d..63ab05b5a87a 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -165,6 +165,15 @@ config NET_SB1000 If you don't have this card, of course say N. +config IP1000 + tristate "IP1000 Gigabit Ethernet support" + depends on PCI && EXPERIMENTAL + ---help--- + This driver supports IP1000 gigabit Ethernet cards. + + To compile this driver as a module, choose M here: the module + will be called ipg. This is recommended. + source "drivers/net/arcnet/Kconfig" source "drivers/net/phy/Kconfig" diff --git a/drivers/net/Makefile b/drivers/net/Makefile index c23ffdbe2599..2098647080a0 100644 --- a/drivers/net/Makefile +++ b/drivers/net/Makefile @@ -7,6 +7,7 @@ obj-$(CONFIG_E1000E) += e1000e/ obj-$(CONFIG_IBM_EMAC) += ibm_emac/ obj-$(CONFIG_IXGBE) += ixgbe/ obj-$(CONFIG_IXGB) += ixgb/ +obj-$(CONFIG_IP1000) += ipg.o obj-$(CONFIG_CHELSIO_T1) += chelsio/ obj-$(CONFIG_CHELSIO_T3) += cxgb3/ obj-$(CONFIG_EHEA) += ehea/ diff --git a/drivers/net/ipg.c b/drivers/net/ipg.c new file mode 100644 index 000000000000..dfdc96fcadec --- /dev/null +++ b/drivers/net/ipg.c @@ -0,0 +1,2326 @@ +/* + * ipg.c: Device Driver for the IP1000 Gigabit Ethernet Adapter + * + * Copyright (C) 2003, 2007 IC Plus Corp + * + * Original Author: + * + * Craig Rich + * Sundance Technology, Inc. + * www.sundanceti.com + * craig_rich@sundanceti.com + * + * Current Maintainer: + * + * Sorbica Shieh. + * http://www.icplus.com.tw + * sorbica@icplus.com.tw + * + * Jesse Huang + * http://www.icplus.com.tw + * jesse@icplus.com.tw + */ +#include +#include +#include +#include + +#define IPG_RX_RING_BYTES (sizeof(struct ipg_rx) * IPG_RFDLIST_LENGTH) +#define IPG_TX_RING_BYTES (sizeof(struct ipg_tx) * IPG_TFDLIST_LENGTH) +#define IPG_RESET_MASK \ + (IPG_AC_GLOBAL_RESET | IPG_AC_RX_RESET | IPG_AC_TX_RESET | \ + IPG_AC_DMA | IPG_AC_FIFO | IPG_AC_NETWORK | IPG_AC_HOST | \ + IPG_AC_AUTO_INIT) + +#define ipg_w32(val32,reg) iowrite32((val32), ioaddr + (reg)) +#define ipg_w16(val16,reg) iowrite16((val16), ioaddr + (reg)) +#define ipg_w8(val8,reg) iowrite8((val8), ioaddr + (reg)) + +#define ipg_r32(reg) ioread32(ioaddr + (reg)) +#define ipg_r16(reg) ioread16(ioaddr + (reg)) +#define ipg_r8(reg) ioread8(ioaddr + (reg)) + +#define JUMBO_FRAME_4k_ONLY +enum { + netdev_io_size = 128 +}; + +#include "ipg.h" +#define DRV_NAME "ipg" + +MODULE_AUTHOR("IC Plus Corp. 2003"); +MODULE_DESCRIPTION("IC Plus IP1000 Gigabit Ethernet Adapter Linux Driver " + DrvVer); +MODULE_LICENSE("GPL"); + +static const char *ipg_brand_name[] = { + "IC PLUS IP1000 1000/100/10 based NIC", + "Sundance Technology ST2021 based NIC", + "Tamarack Microelectronics TC9020/9021 based NIC", + "Tamarack Microelectronics TC9020/9021 based NIC", + "D-Link NIC", + "D-Link NIC IP1000A" +}; + +static struct pci_device_id ipg_pci_tbl[] __devinitdata = { + { PCI_VDEVICE(SUNDANCE, 0x1023), 0 }, + { PCI_VDEVICE(SUNDANCE, 0x2021), 1 }, + { PCI_VDEVICE(SUNDANCE, 0x1021), 2 }, + { PCI_VDEVICE(DLINK, 0x9021), 3 }, + { PCI_VDEVICE(DLINK, 0x4000), 4 }, + { PCI_VDEVICE(DLINK, 0x4020), 5 }, + { 0, } +}; + +MODULE_DEVICE_TABLE(pci, ipg_pci_tbl); + +static inline void __iomem *ipg_ioaddr(struct net_device *dev) +{ + struct ipg_nic_private *sp = netdev_priv(dev); + return sp->ioaddr; +} + +#ifdef IPG_DEBUG +static void ipg_dump_rfdlist(struct net_device *dev) +{ + struct ipg_nic_private *sp = netdev_priv(dev); + void __iomem *ioaddr = sp->ioaddr; + unsigned int i; + u32 offset; + + IPG_DEBUG_MSG("_dump_rfdlist\n"); + + printk(KERN_INFO "rx_current = %2.2x\n", sp->rx_current); + printk(KERN_INFO "rx_dirty = %2.2x\n", sp->rx_dirty); + printk(KERN_INFO "RFDList start address = %16.16lx\n", + (unsigned long) sp->rxd_map); + printk(KERN_INFO "RFDListPtr register = %8.8x%8.8x\n", + ipg_r32(IPG_RFDLISTPTR1), ipg_r32(IPG_RFDLISTPTR0)); + + for (i = 0; i < IPG_RFDLIST_LENGTH; i++) { + offset = (u32) &sp->rxd[i].next_desc - (u32) sp->rxd; + printk(KERN_INFO "%2.2x %4.4x RFDNextPtr = %16.16lx\n", i, + offset, (unsigned long) sp->rxd[i].next_desc); + offset = (u32) &sp->rxd[i].rfs - (u32) sp->rxd; + printk(KERN_INFO "%2.2x %4.4x RFS = %16.16lx\n", i, + offset, (unsigned long) sp->rxd[i].rfs); + offset = (u32) &sp->rxd[i].frag_info - (u32) sp->rxd; + printk(KERN_INFO "%2.2x %4.4x frag_info = %16.16lx\n", i, + offset, (unsigned long) sp->rxd[i].frag_info); + } +} + +static void ipg_dump_tfdlist(struct net_device *dev) +{ + struct ipg_nic_private *sp = netdev_priv(dev); + void __iomem *ioaddr = sp->ioaddr; + unsigned int i; + u32 offset; + + IPG_DEBUG_MSG("_dump_tfdlist\n"); + + printk(KERN_INFO "tx_current = %2.2x\n", sp->tx_current); + printk(KERN_INFO "tx_dirty = %2.2x\n", sp->tx_dirty); + printk(KERN_INFO "TFDList start address = %16.16lx\n", + (unsigned long) sp->txd_map); + printk(KERN_INFO "TFDListPtr register = %8.8x%8.8x\n", + ipg_r32(IPG_TFDLISTPTR1), ipg_r32(IPG_TFDLISTPTR0)); + + for (i = 0; i < IPG_TFDLIST_LENGTH; i++) { + offset = (u32) &sp->txd[i].next_desc - (u32) sp->txd; + printk(KERN_INFO "%2.2x %4.4x TFDNextPtr = %16.16lx\n", i, + offset, (unsigned long) sp->txd[i].next_desc); + + offset = (u32) &sp->txd[i].tfc - (u32) sp->txd; + printk(KERN_INFO "%2.2x %4.4x TFC = %16.16lx\n", i, + offset, (unsigned long) sp->txd[i].tfc); + offset = (u32) &sp->txd[i].frag_info - (u32) sp->txd; + printk(KERN_INFO "%2.2x %4.4x frag_info = %16.16lx\n", i, + offset, (unsigned long) sp->txd[i].frag_info); + } +} +#endif + +static void ipg_write_phy_ctl(void __iomem *ioaddr, u8 data) +{ + ipg_w8(IPG_PC_RSVD_MASK & data, PHY_CTRL); + ndelay(IPG_PC_PHYCTRLWAIT_NS); +} + +static void ipg_drive_phy_ctl_low_high(void __iomem *ioaddr, u8 data) +{ + ipg_write_phy_ctl(ioaddr, IPG_PC_MGMTCLK_LO | data); + ipg_write_phy_ctl(ioaddr, IPG_PC_MGMTCLK_HI | data); +} + +static void send_three_state(void __iomem *ioaddr, u8 phyctrlpolarity) +{ + phyctrlpolarity |= (IPG_PC_MGMTDATA & 0) | IPG_PC_MGMTDIR; + + ipg_drive_phy_ctl_low_high(ioaddr, phyctrlpolarity); +} + +static void send_end(void __iomem *ioaddr, u8 phyctrlpolarity) +{ + ipg_w8((IPG_PC_MGMTCLK_LO | (IPG_PC_MGMTDATA & 0) | IPG_PC_MGMTDIR | + phyctrlpolarity) & IPG_PC_RSVD_MASK, PHY_CTRL); +} + +static u16 read_phy_bit(void __iomem * ioaddr, u8 phyctrlpolarity) +{ + u16 bit_data; + + ipg_write_phy_ctl(ioaddr, IPG_PC_MGMTCLK_LO | phyctrlpolarity); + + bit_data = ((ipg_r8(PHY_CTRL) & IPG_PC_MGMTDATA) >> 1) & 1; + + ipg_write_phy_ctl(ioaddr, IPG_PC_MGMTCLK_HI | phyctrlpolarity); + + return bit_data; +} + +/* + * Read a register from the Physical Layer device located + * on the IPG NIC, using the IPG PHYCTRL register. + */ +static int mdio_read(struct net_device * dev, int phy_id, int phy_reg) +{ + void __iomem *ioaddr = ipg_ioaddr(dev); + /* + * The GMII mangement frame structure for a read is as follows: + * + * |Preamble|st|op|phyad|regad|ta| data |idle| + * |< 32 1s>|01|10|AAAAA|RRRRR|z0|DDDDDDDDDDDDDDDD|z | + * + * <32 1s> = 32 consecutive logic 1 values + * A = bit of Physical Layer device address (MSB first) + * R = bit of register address (MSB first) + * z = High impedance state + * D = bit of read data (MSB first) + * + * Transmission order is 'Preamble' field first, bits transmitted + * left to right (first to last). + */ + struct { + u32 field; + unsigned int len; + } p[] = { + { GMII_PREAMBLE, 32 }, /* Preamble */ + { GMII_ST, 2 }, /* ST */ + { GMII_READ, 2 }, /* OP */ + { phy_id, 5 }, /* PHYAD */ + { phy_reg, 5 }, /* REGAD */ + { 0x0000, 2 }, /* TA */ + { 0x0000, 16 }, /* DATA */ + { 0x0000, 1 } /* IDLE */ + }; + unsigned int i, j; + u8 polarity, data; + + polarity = ipg_r8(PHY_CTRL); + polarity &= (IPG_PC_DUPLEX_POLARITY | IPG_PC_LINK_POLARITY); + + /* Create the Preamble, ST, OP, PHYAD, and REGAD field. */ + for (j = 0; j < 5; j++) { + for (i = 0; i < p[j].len; i++) { + /* For each variable length field, the MSB must be + * transmitted first. Rotate through the field bits, + * starting with the MSB, and move each bit into the + * the 1st (2^1) bit position (this is the bit position + * corresponding to the MgmtData bit of the PhyCtrl + * register for the IPG). + * + * Example: ST = 01; + * + * First write a '0' to bit 1 of the PhyCtrl + * register, then write a '1' to bit 1 of the + * PhyCtrl register. + * + * To do this, right shift the MSB of ST by the value: + * [field length - 1 - #ST bits already written] + * then left shift this result by 1. + */ + data = (p[j].field >> (p[j].len - 1 - i)) << 1; + data &= IPG_PC_MGMTDATA; + data |= polarity | IPG_PC_MGMTDIR; + + ipg_drive_phy_ctl_low_high(ioaddr, data); + } + } + + send_three_state(ioaddr, polarity); + + read_phy_bit(ioaddr, polarity); + + /* + * For a read cycle, the bits for the next two fields (TA and + * DATA) are driven by the PHY (the IPG reads these bits). + */ + for (i = 0; i < p[6].len; i++) { + p[6].field |= + (read_phy_bit(ioaddr, polarity) << (p[6].len - 1 - i)); + } + + send_three_state(ioaddr, polarity); + send_three_state(ioaddr, polarity); + send_three_state(ioaddr, polarity); + send_end(ioaddr, polarity); + + /* Return the value of the DATA field. */ + return p[6].field; +} + +/* + * Write to a register from the Physical Layer device located + * on the IPG NIC, using the IPG PHYCTRL register. + */ +static void mdio_write(struct net_device *dev, int phy_id, int phy_reg, int val) +{ + void __iomem *ioaddr = ipg_ioaddr(dev); + /* + * The GMII mangement frame structure for a read is as follows: + * + * |Preamble|st|op|phyad|regad|ta| data |idle| + * |< 32 1s>|01|10|AAAAA|RRRRR|z0|DDDDDDDDDDDDDDDD|z | + * + * <32 1s> = 32 consecutive logic 1 values + * A = bit of Physical Layer device address (MSB first) + * R = bit of register address (MSB first) + * z = High impedance state + * D = bit of write data (MSB first) + * + * Transmission order is 'Preamble' field first, bits transmitted + * left to right (first to last). + */ + struct { + u32 field; + unsigned int len; + } p[] = { + { GMII_PREAMBLE, 32 }, /* Preamble */ + { GMII_ST, 2 }, /* ST */ + { GMII_WRITE, 2 }, /* OP */ + { phy_id, 5 }, /* PHYAD */ + { phy_reg, 5 }, /* REGAD */ + { 0x0002, 2 }, /* TA */ + { val & 0xffff, 16 }, /* DATA */ + { 0x0000, 1 } /* IDLE */ + }; + unsigned int i, j; + u8 polarity, data; + + polarity = ipg_r8(PHY_CTRL); + polarity &= (IPG_PC_DUPLEX_POLARITY | IPG_PC_LINK_POLARITY); + + /* Create the Preamble, ST, OP, PHYAD, and REGAD field. */ + for (j = 0; j < 7; j++) { + for (i = 0; i < p[j].len; i++) { + /* For each variable length field, the MSB must be + * transmitted first. Rotate through the field bits, + * starting with the MSB, and move each bit into the + * the 1st (2^1) bit position (this is the bit position + * corresponding to the MgmtData bit of the PhyCtrl + * register for the IPG). + * + * Example: ST = 01; + * + * First write a '0' to bit 1 of the PhyCtrl + * register, then write a '1' to bit 1 of the + * PhyCtrl register. + * + * To do this, right shift the MSB of ST by the value: + * [field length - 1 - #ST bits already written] + * then left shift this result by 1. + */ + data = (p[j].field >> (p[j].len - 1 - i)) << 1; + data &= IPG_PC_MGMTDATA; + data |= polarity | IPG_PC_MGMTDIR; + + ipg_drive_phy_ctl_low_high(ioaddr, data); + } + } + + /* The last cycle is a tri-state, so read from the PHY. */ + for (j = 7; j < 8; j++) { + for (i = 0; i < p[j].len; i++) { + ipg_write_phy_ctl(ioaddr, IPG_PC_MGMTCLK_LO | polarity); + + p[j].field |= ((ipg_r8(PHY_CTRL) & + IPG_PC_MGMTDATA) >> 1) << (p[j].len - 1 - i); + + ipg_write_phy_ctl(ioaddr, IPG_PC_MGMTCLK_HI | polarity); + } + } +} + +/* Set LED_Mode JES20040127EEPROM */ +static void ipg_set_led_mode(struct net_device *dev) +{ + struct ipg_nic_private *sp = netdev_priv(dev); + void __iomem *ioaddr = sp->ioaddr; + u32 mode; + + mode = ipg_r32(ASIC_CTRL); + mode &= ~(IPG_AC_LED_MODE_BIT_1 | IPG_AC_LED_MODE | IPG_AC_LED_SPEED); + + if ((sp->LED_Mode & 0x03) > 1) + mode |= IPG_AC_LED_MODE_BIT_1; /* Write Asic Control Bit 29 */ + + if ((sp->LED_Mode & 0x01) == 1) + mode |= IPG_AC_LED_MODE; /* Write Asic Control Bit 14 */ + + if ((sp->LED_Mode & 0x08) == 8) + mode |= IPG_AC_LED_SPEED; /* Write Asic Control Bit 27 */ + + ipg_w32(mode, ASIC_CTRL); +} + +/* Set PHYSet JES20040127EEPROM */ +static void ipg_set_phy_set(struct net_device *dev) +{ + struct ipg_nic_private *sp = netdev_priv(dev); + void __iomem *ioaddr = sp->ioaddr; + int physet; + + physet = ipg_r8(PHY_SET); + physet &= ~(IPG_PS_MEM_LENB9B | IPG_PS_MEM_LEN9 | IPG_PS_NON_COMPDET); + physet |= ((sp->LED_Mode & 0x70) >> 4); + ipg_w8(physet, PHY_SET); +} + +static int ipg_reset(struct net_device *dev, u32 resetflags) +{ + /* Assert functional resets via the IPG AsicCtrl + * register as specified by the 'resetflags' input + * parameter. + */ + void __iomem *ioaddr = ipg_ioaddr(dev); //JES20040127EEPROM: + unsigned int timeout_count = 0; + + IPG_DEBUG_MSG("_reset\n"); + + ipg_w32(ipg_r32(ASIC_CTRL) | resetflags, ASIC_CTRL); + + /* Delay added to account for problem with 10Mbps reset. */ + mdelay(IPG_AC_RESETWAIT); + + while (IPG_AC_RESET_BUSY & ipg_r32(ASIC_CTRL)) { + mdelay(IPG_AC_RESETWAIT); + if (++timeout_count > IPG_AC_RESET_TIMEOUT) + return -ETIME; + } + /* Set LED Mode in Asic Control JES20040127EEPROM */ + ipg_set_led_mode(dev); + + /* Set PHYSet Register Value JES20040127EEPROM */ + ipg_set_phy_set(dev); + return 0; +} + +/* Find the GMII PHY address. */ +static int ipg_find_phyaddr(struct net_device *dev) +{ + unsigned int phyaddr, i; + + for (i = 0; i < 32; i++) { + u32 status; + + /* Search for the correct PHY address among 32 possible. */ + phyaddr = (IPG_NIC_PHY_ADDRESS + i) % 32; + + /* 10/22/03 Grace change verify from GMII_PHY_STATUS to + GMII_PHY_ID1 + */ + + status = mdio_read(dev, phyaddr, MII_BMSR); + + if ((status != 0xFFFF) && (status != 0)) + return phyaddr; + } + + return 0x1f; +} + +/* + * Configure IPG based on result of IEEE 802.3 PHY + * auto-negotiation. + */ +static int ipg_config_autoneg(struct net_device *dev) +{ + struct ipg_nic_private *sp = netdev_priv(dev); + void __iomem *ioaddr = sp->ioaddr; + unsigned int txflowcontrol; + unsigned int rxflowcontrol; + unsigned int fullduplex; + unsigned int gig; + u32 mac_ctrl_val; + u32 asicctrl; + u8 phyctrl; + + IPG_DEBUG_MSG("_config_autoneg\n"); + + asicctrl = ipg_r32(ASIC_CTRL); + phyctrl = ipg_r8(PHY_CTRL); + mac_ctrl_val = ipg_r32(MAC_CTRL); + + /* Set flags for use in resolving auto-negotation, assuming + * non-1000Mbps, half duplex, no flow control. + */ + fullduplex = 0; + txflowcontrol = 0; + rxflowcontrol = 0; + gig = 0; + + /* To accomodate a problem in 10Mbps operation, + * set a global flag if PHY running in 10Mbps mode. + */ + sp->tenmbpsmode = 0; + + printk(KERN_INFO "%s: Link speed = ", dev->name); + + /* Determine actual speed of operation. */ + switch (phyctrl & IPG_PC_LINK_SPEED) { + case IPG_PC_LINK_SPEED_10MBPS: + printk("10Mbps.\n"); + printk(KERN_INFO "%s: 10Mbps operational mode enabled.\n", + dev->name); + sp->tenmbpsmode = 1; + break; + case IPG_PC_LINK_SPEED_100MBPS: + printk("100Mbps.\n"); + break; + case IPG_PC_LINK_SPEED_1000MBPS: + printk("1000Mbps.\n"); + gig = 1; + break; + default: + printk("undefined!\n"); + return 0; + } + + if (phyctrl & IPG_PC_DUPLEX_STATUS) { + fullduplex = 1; + txflowcontrol = 1; + rxflowcontrol = 1; + } + + /* Configure full duplex, and flow control. */ + if (fullduplex == 1) { + /* Configure IPG for full duplex operation. */ + printk(KERN_INFO "%s: setting full duplex, ", dev->name); + + mac_ctrl_val |= IPG_MC_DUPLEX_SELECT_FD; + + if (txflowcontrol == 1) { + printk("TX flow control"); + mac_ctrl_val |= IPG_MC_TX_FLOW_CONTROL_ENABLE; + } else { + printk("no TX flow control"); + mac_ctrl_val &= ~IPG_MC_TX_FLOW_CONTROL_ENABLE; + } + + if (rxflowcontrol == 1) { + printk(", RX flow control."); + mac_ctrl_val |= IPG_MC_RX_FLOW_CONTROL_ENABLE; + } else { + printk(", no RX flow control."); + mac_ctrl_val &= ~IPG_MC_RX_FLOW_CONTROL_ENABLE; + } + + printk("\n"); + } else { + /* Configure IPG for half duplex operation. */ + printk(KERN_INFO "%s: setting half duplex, " + "no TX flow control, no RX flow control.\n", dev->name); + + mac_ctrl_val &= ~IPG_MC_DUPLEX_SELECT_FD & + ~IPG_MC_TX_FLOW_CONTROL_ENABLE & + ~IPG_MC_RX_FLOW_CONTROL_ENABLE; + } + ipg_w32(mac_ctrl_val, MAC_CTRL); + return 0; +} + +/* Determine and configure multicast operation and set + * receive mode for IPG. + */ +static void ipg_nic_set_multicast_list(struct net_device *dev) +{ + void __iomem *ioaddr = ipg_ioaddr(dev); + struct dev_mc_list *mc_list_ptr; + unsigned int hashindex; + u32 hashtable[2]; + u8 receivemode; + + IPG_DEBUG_MSG("_nic_set_multicast_list\n"); + + receivemode = IPG_RM_RECEIVEUNICAST | IPG_RM_RECEIVEBROADCAST; + + if (dev->flags & IFF_PROMISC) { + /* NIC to be configured in promiscuous mode. */ + receivemode = IPG_RM_RECEIVEALLFRAMES; + } else if ((dev->flags & IFF_ALLMULTI) || + (dev->flags & IFF_MULTICAST & + (dev->mc_count > IPG_MULTICAST_HASHTABLE_SIZE))) { + /* NIC to be configured to receive all multicast + * frames. */ + receivemode |= IPG_RM_RECEIVEMULTICAST; + } else if (dev->flags & IFF_MULTICAST & (dev->mc_count > 0)) { + /* NIC to be configured to receive selected + * multicast addresses. */ + receivemode |= IPG_RM_RECEIVEMULTICASTHASH; + } + + /* Calculate the bits to set for the 64 bit, IPG HASHTABLE. + * The IPG applies a cyclic-redundancy-check (the same CRC + * used to calculate the frame data FCS) to the destination + * address all incoming multicast frames whose destination + * address has the multicast bit set. The least significant + * 6 bits of the CRC result are used as an addressing index + * into the hash table. If the value of the bit addressed by + * this index is a 1, the frame is passed to the host system. + */ + + /* Clear hashtable. */ + hashtable[0] = 0x00000000; + hashtable[1] = 0x00000000; + + /* Cycle through all multicast addresses to filter. */ + for (mc_list_ptr = dev->mc_list; + mc_list_ptr != NULL; mc_list_ptr = mc_list_ptr->next) { + /* Calculate CRC result for each multicast address. */ + hashindex = crc32_le(0xffffffff, mc_list_ptr->dmi_addr, + ETH_ALEN); + + /* Use only the least significant 6 bits. */ + hashindex = hashindex & 0x3F; + + /* Within "hashtable", set bit number "hashindex" + * to a logic 1. + */ + set_bit(hashindex, (void *)hashtable); + } + + /* Write the value of the hashtable, to the 4, 16 bit + * HASHTABLE IPG registers. + */ + ipg_w32(hashtable[0], HASHTABLE_0); + ipg_w32(hashtable[1], HASHTABLE_1); + + ipg_w8(IPG_RM_RSVD_MASK & receivemode, RECEIVE_MODE); + + IPG_DEBUG_MSG("ReceiveMode = %x\n", ipg_r8(RECEIVE_MODE)); +} + +static int ipg_io_config(struct net_device *dev) +{ + void __iomem *ioaddr = ipg_ioaddr(dev); + u32 origmacctrl; + u32 restoremacctrl; + + IPG_DEBUG_MSG("_io_config\n"); + + origmacctrl = ipg_r32(MAC_CTRL); + + restoremacctrl = origmacctrl | IPG_MC_STATISTICS_ENABLE; + + /* Based on compilation option, determine if FCS is to be + * stripped on receive frames by IPG. + */ + if (!IPG_STRIP_FCS_ON_RX) + restoremacctrl |= IPG_MC_RCV_FCS; + + /* Determine if transmitter and/or receiver are + * enabled so we may restore MACCTRL correctly. + */ + if (origmacctrl & IPG_MC_TX_ENABLED) + restoremacctrl |= IPG_MC_TX_ENABLE; + + if (origmacctrl & IPG_MC_RX_ENABLED) + restoremacctrl |= IPG_MC_RX_ENABLE; + + /* Transmitter and receiver must be disabled before setting + * IFSSelect. + */ + ipg_w32((origmacctrl & (IPG_MC_RX_DISABLE | IPG_MC_TX_DISABLE)) & + IPG_MC_RSVD_MASK, MAC_CTRL); + + /* Now that transmitter and receiver are disabled, write + * to IFSSelect. + */ + ipg_w32((origmacctrl & IPG_MC_IFS_96BIT) & IPG_MC_RSVD_MASK, MAC_CTRL); + + /* Set RECEIVEMODE register. */ + ipg_nic_set_multicast_list(dev); + + ipg_w16(IPG_MAX_RXFRAME_SIZE, MAX_FRAME_SIZE); + + ipg_w8(IPG_RXDMAPOLLPERIOD_VALUE, RX_DMA_POLL_PERIOD); + ipg_w8(IPG_RXDMAURGENTTHRESH_VALUE, RX_DMA_URGENT_THRESH); + ipg_w8(IPG_RXDMABURSTTHRESH_VALUE, RX_DMA_BURST_THRESH); + ipg_w8(IPG_TXDMAPOLLPERIOD_VALUE, TX_DMA_POLL_PERIOD); + ipg_w8(IPG_TXDMAURGENTTHRESH_VALUE, TX_DMA_URGENT_THRESH); + ipg_w8(IPG_TXDMABURSTTHRESH_VALUE, TX_DMA_BURST_THRESH); + ipg_w16((IPG_IE_HOST_ERROR | IPG_IE_TX_DMA_COMPLETE | + IPG_IE_TX_COMPLETE | IPG_IE_INT_REQUESTED | + IPG_IE_UPDATE_STATS | IPG_IE_LINK_EVENT | + IPG_IE_RX_DMA_COMPLETE | IPG_IE_RX_DMA_PRIORITY), INT_ENABLE); + ipg_w16(IPG_FLOWONTHRESH_VALUE, FLOW_ON_THRESH); + ipg_w16(IPG_FLOWOFFTHRESH_VALUE, FLOW_OFF_THRESH); + + /* IPG multi-frag frame bug workaround. + * Per silicon revision B3 eratta. + */ + ipg_w16(ipg_r16(DEBUG_CTRL) | 0x0200, DEBUG_CTRL); + + /* IPG TX poll now bug workaround. + * Per silicon revision B3 eratta. + */ + ipg_w16(ipg_r16(DEBUG_CTRL) | 0x0010, DEBUG_CTRL); + + /* IPG RX poll now bug workaround. + * Per silicon revision B3 eratta. + */ + ipg_w16(ipg_r16(DEBUG_CTRL) | 0x0020, DEBUG_CTRL); + + /* Now restore MACCTRL to original setting. */ + ipg_w32(IPG_MC_RSVD_MASK & restoremacctrl, MAC_CTRL); + + /* Disable unused RMON statistics. */ + ipg_w32(IPG_RZ_ALL, RMON_STATISTICS_MASK); + + /* Disable unused MIB statistics. */ + ipg_w32(IPG_SM_MACCONTROLFRAMESXMTD | IPG_SM_MACCONTROLFRAMESRCVD | + IPG_SM_BCSTOCTETXMTOK_BCSTFRAMESXMTDOK | IPG_SM_TXJUMBOFRAMES | + IPG_SM_MCSTOCTETXMTOK_MCSTFRAMESXMTDOK | IPG_SM_RXJUMBOFRAMES | + IPG_SM_BCSTOCTETRCVDOK_BCSTFRAMESRCVDOK | + IPG_SM_UDPCHECKSUMERRORS | IPG_SM_TCPCHECKSUMERRORS | + IPG_SM_IPCHECKSUMERRORS, STATISTICS_MASK); + + return 0; +} + +/* + * Create a receive buffer within system memory and update + * NIC private structure appropriately. + */ +static int ipg_get_rxbuff(struct net_device *dev, int entry) +{ + struct ipg_nic_private *sp = netdev_priv(dev); + struct ipg_rx *rxfd = sp->rxd + entry; + struct sk_buff *skb; + u64 rxfragsize; + + IPG_DEBUG_MSG("_get_rxbuff\n"); + + skb = netdev_alloc_skb(dev, IPG_RXSUPPORT_SIZE + NET_IP_ALIGN); + if (!skb) { + sp->RxBuff[entry] = NULL; + return -ENOMEM; + } + + /* Adjust the data start location within the buffer to + * align IP address field to a 16 byte boundary. + */ + skb_reserve(skb, NET_IP_ALIGN); + + /* Associate the receive buffer with the IPG NIC. */ + skb->dev = dev; + + /* Save the address of the sk_buff structure. */ + sp->RxBuff[entry] = skb; + + rxfd->frag_info = cpu_to_le64(pci_map_single(sp->pdev, skb->data, + sp->rx_buf_sz, PCI_DMA_FROMDEVICE)); + + /* Set the RFD fragment length. */ + rxfragsize = IPG_RXFRAG_SIZE; + rxfd->frag_info |= cpu_to_le64((rxfragsize << 48) & IPG_RFI_FRAGLEN); + + return 0; +} + +static int init_rfdlist(struct net_device *dev) +{ + struct ipg_nic_private *sp = netdev_priv(dev); + void __iomem *ioaddr = sp->ioaddr; + unsigned int i; + + IPG_DEBUG_MSG("_init_rfdlist\n"); + + for (i = 0; i < IPG_RFDLIST_LENGTH; i++) { + struct ipg_rx *rxfd = sp->rxd + i; + + if (sp->RxBuff[i]) { + pci_unmap_single(sp->pdev, + le64_to_cpu(rxfd->frag_info & ~IPG_RFI_FRAGLEN), + sp->rx_buf_sz, PCI_DMA_FROMDEVICE); + IPG_DEV_KFREE_SKB(sp->RxBuff[i]); + sp->RxBuff[i] = NULL; + } + + /* Clear out the RFS field. */ + rxfd->rfs = 0x0000000000000000; + + if (ipg_get_rxbuff(dev, i) < 0) { + /* + * A receive buffer was not ready, break the + * RFD list here. + */ + IPG_DEBUG_MSG("Cannot allocate Rx buffer.\n"); + + /* Just in case we cannot allocate a single RFD. + * Should not occur. + */ + if (i == 0) { + printk(KERN_ERR "%s: No memory available" + " for RFD list.\n", dev->name); + return -ENOMEM; + } + } + + rxfd->next_desc = cpu_to_le64(sp->rxd_map + + sizeof(struct ipg_rx)*(i + 1)); + } + sp->rxd[i - 1].next_desc = cpu_to_le64(sp->rxd_map); + + sp->rx_current = 0; + sp->rx_dirty = 0; + + /* Write the location of the RFDList to the IPG. */ + ipg_w32((u32) sp->rxd_map, RFD_LIST_PTR_0); + ipg_w32(0x00000000, RFD_LIST_PTR_1); + + return 0; +} + +static void init_tfdlist(struct net_device *dev) +{ + struct ipg_nic_private *sp = netdev_priv(dev); + void __iomem *ioaddr = sp->ioaddr; + unsigned int i; + + IPG_DEBUG_MSG("_init_tfdlist\n"); + + for (i = 0; i < IPG_TFDLIST_LENGTH; i++) { + struct ipg_tx *txfd = sp->txd + i; + + txfd->tfc = cpu_to_le64(IPG_TFC_TFDDONE); + + if (sp->TxBuff[i]) { + IPG_DEV_KFREE_SKB(sp->TxBuff[i]); + sp->TxBuff[i] = NULL; + } + + txfd->next_desc = cpu_to_le64(sp->txd_map + + sizeof(struct ipg_tx)*(i + 1)); + } + sp->txd[i - 1].next_desc = cpu_to_le64(sp->txd_map); + + sp->tx_current = 0; + sp->tx_dirty = 0; + + /* Write the location of the TFDList to the IPG. */ + IPG_DDEBUG_MSG("Starting TFDListPtr = %8.8x\n", + (u32) sp->txd_map); + ipg_w32((u32) sp->txd_map, TFD_LIST_PTR_0); + ipg_w32(0x00000000, TFD_LIST_PTR_1); + + sp->ResetCurrentTFD = 1; +} + +/* + * Free all transmit buffers which have already been transfered + * via DMA to the IPG. + */ +static void ipg_nic_txfree(struct net_device *dev) +{ + struct ipg_nic_private *sp = netdev_priv(dev); + void __iomem *ioaddr = sp->ioaddr; + const unsigned int curr = ipg_r32(TFD_LIST_PTR_0) - + (sp->txd_map / sizeof(struct ipg_tx)) - 1; + unsigned int released, pending; + + IPG_DEBUG_MSG("_nic_txfree\n"); + + pending = sp->tx_current - sp->tx_dirty; + + for (released = 0; released < pending; released++) { + unsigned int dirty = sp->tx_dirty % IPG_TFDLIST_LENGTH; + struct sk_buff *skb = sp->TxBuff[dirty]; + struct ipg_tx *txfd = sp->txd + dirty; + + IPG_DEBUG_MSG("TFC = %16.16lx\n", (unsigned long) txfd->tfc); + + /* Look at each TFD's TFC field beginning + * at the last freed TFD up to the current TFD. + * If the TFDDone bit is set, free the associated + * buffer. + */ + if (dirty == curr) + break; + + /* Setup TFDDONE for compatible issue. */ + txfd->tfc |= cpu_to_le64(IPG_TFC_TFDDONE); + + /* Free the transmit buffer. */ + if (skb) { + pci_unmap_single(sp->pdev, + le64_to_cpu(txfd->frag_info & ~IPG_TFI_FRAGLEN), + skb->len, PCI_DMA_TODEVICE); + + IPG_DEV_KFREE_SKB(skb); + + sp->TxBuff[dirty] = NULL; + } + } + + sp->tx_dirty += released; + + if (netif_queue_stopped(dev) && + (sp->tx_current != (sp->tx_dirty + IPG_TFDLIST_LENGTH))) { + netif_wake_queue(dev); + } +} + +static void ipg_tx_timeout(struct net_device *dev) +{ + struct ipg_nic_private *sp = netdev_priv(dev); + void __iomem *ioaddr = sp->ioaddr; + + ipg_reset(dev, IPG_AC_TX_RESET | IPG_AC_DMA | IPG_AC_NETWORK | + IPG_AC_FIFO); + + spin_lock_irq(&sp->lock); + + /* Re-configure after DMA reset. */ + if (ipg_io_config(dev) < 0) { + printk(KERN_INFO "%s: Error during re-configuration.\n", + dev->name); + } + + init_tfdlist(dev); + + spin_unlock_irq(&sp->lock); + + ipg_w32((ipg_r32(MAC_CTRL) | IPG_MC_TX_ENABLE) & IPG_MC_RSVD_MASK, + MAC_CTRL); +} + +/* + * For TxComplete interrupts, free all transmit + * buffers which have already been transfered via DMA + * to the IPG. + */ +static void ipg_nic_txcleanup(struct net_device *dev) +{ + struct ipg_nic_private *sp = netdev_priv(dev); + void __iomem *ioaddr = sp->ioaddr; + unsigned int i; + + IPG_DEBUG_MSG("_nic_txcleanup\n"); + + for (i = 0; i < IPG_TFDLIST_LENGTH; i++) { + /* Reading the TXSTATUS register clears the + * TX_COMPLETE interrupt. + */ + u32 txstatusdword = ipg_r32(TX_STATUS); + + IPG_DEBUG_MSG("TxStatus = %8.8x\n", txstatusdword); + + /* Check for Transmit errors. Error bits only valid if + * TX_COMPLETE bit in the TXSTATUS register is a 1. + */ + if (!(txstatusdword & IPG_TS_TX_COMPLETE)) + break; + + /* If in 10Mbps mode, indicate transmit is ready. */ + if (sp->tenmbpsmode) { + netif_wake_queue(dev); + } + + /* Transmit error, increment stat counters. */ + if (txstatusdword & IPG_TS_TX_ERROR) { + IPG_DEBUG_MSG("Transmit error.\n"); + sp->stats.tx_errors++; + } + + /* Late collision, re-enable transmitter. */ + if (txstatusdword & IPG_TS_LATE_COLLISION) { + IPG_DEBUG_MSG("Late collision on transmit.\n"); + ipg_w32((ipg_r32(MAC_CTRL) | IPG_MC_TX_ENABLE) & + IPG_MC_RSVD_MASK, MAC_CTRL); + } + + /* Maximum collisions, re-enable transmitter. */ + if (txstatusdword & IPG_TS_TX_MAX_COLL) { + IPG_DEBUG_MSG("Maximum collisions on transmit.\n"); + ipg_w32((ipg_r32(MAC_CTRL) | IPG_MC_TX_ENABLE) & + IPG_MC_RSVD_MASK, MAC_CTRL); + } + + /* Transmit underrun, reset and re-enable + * transmitter. + */ + if (txstatusdword & IPG_TS_TX_UNDERRUN) { + IPG_DEBUG_MSG("Transmitter underrun.\n"); + sp->stats.tx_fifo_errors++; + ipg_reset(dev, IPG_AC_TX_RESET | IPG_AC_DMA | + IPG_AC_NETWORK | IPG_AC_FIFO); + + /* Re-configure after DMA reset. */ + if (ipg_io_config(dev) < 0) { + printk(KERN_INFO + "%s: Error during re-configuration.\n", + dev->name); + } + init_tfdlist(dev); + + ipg_w32((ipg_r32(MAC_CTRL) | IPG_MC_TX_ENABLE) & + IPG_MC_RSVD_MASK, MAC_CTRL); + } + } + + ipg_nic_txfree(dev); +} + +/* Provides statistical information about the IPG NIC. */ +struct net_device_stats *ipg_nic_get_stats(struct net_device *dev) +{ + struct ipg_nic_private *sp = netdev_priv(dev); + void __iomem *ioaddr = sp->ioaddr; + u16 temp1; + u16 temp2; + + IPG_DEBUG_MSG("_nic_get_stats\n"); + + /* Check to see if the NIC has been initialized via nic_open, + * before trying to read statistic registers. + */ + if (!test_bit(__LINK_STATE_START, &dev->state)) + return &sp->stats; + + sp->stats.rx_packets += ipg_r32(IPG_FRAMESRCVDOK); + sp->stats.tx_packets += ipg_r32(IPG_FRAMESXMTDOK); + sp->stats.rx_bytes += ipg_r32(IPG_OCTETRCVOK); + sp->stats.tx_bytes += ipg_r32(IPG_OCTETXMTOK); + temp1 = ipg_r16(IPG_FRAMESLOSTRXERRORS); + sp->stats.rx_errors += temp1; + sp->stats.rx_missed_errors += temp1; + temp1 = ipg_r32(IPG_SINGLECOLFRAMES) + ipg_r32(IPG_MULTICOLFRAMES) + + ipg_r32(IPG_LATECOLLISIONS); + temp2 = ipg_r16(IPG_CARRIERSENSEERRORS); + sp->stats.collisions += temp1; + sp->stats.tx_dropped += ipg_r16(IPG_FRAMESABORTXSCOLLS); + sp->stats.tx_errors += ipg_r16(IPG_FRAMESWEXDEFERRAL) + + ipg_r32(IPG_FRAMESWDEFERREDXMT) + temp1 + temp2; + sp->stats.multicast += ipg_r32(IPG_MCSTOCTETRCVDOK); + + /* detailed tx_errors */ + sp->stats.tx_carrier_errors += temp2; + + /* detailed rx_errors */ + sp->stats.rx_length_errors += ipg_r16(IPG_INRANGELENGTHERRORS) + + ipg_r16(IPG_FRAMETOOLONGERRRORS); + sp->stats.rx_crc_errors += ipg_r16(IPG_FRAMECHECKSEQERRORS); + + /* Unutilized IPG statistic registers. */ + ipg_r32(IPG_MCSTFRAMESRCVDOK); + + return &sp->stats; +} + +/* Restore used receive buffers. */ +static int ipg_nic_rxrestore(struct net_device *dev) +{ + struct ipg_nic_private *sp = netdev_priv(dev); + const unsigned int curr = sp->rx_current; + unsigned int dirty = sp->rx_dirty; + + IPG_DEBUG_MSG("_nic_rxrestore\n"); + + for (dirty = sp->rx_dirty; curr - dirty > 0; dirty++) { + unsigned int entry = dirty % IPG_RFDLIST_LENGTH; + + /* rx_copybreak may poke hole here and there. */ + if (sp->RxBuff[entry]) + continue; + + /* Generate a new receive buffer to replace the + * current buffer (which will be released by the + * Linux system). + */ + if (ipg_get_rxbuff(dev, entry) < 0) { + IPG_DEBUG_MSG("Cannot allocate new Rx buffer.\n"); + + break; + } + + /* Reset the RFS field. */ + sp->rxd[entry].rfs = 0x0000000000000000; + } + sp->rx_dirty = dirty; + + return 0; +} + +#ifdef JUMBO_FRAME + +/* use jumboindex and jumbosize to control jumbo frame status + initial status is jumboindex=-1 and jumbosize=0 + 1. jumboindex = -1 and jumbosize=0 : previous jumbo frame has been done. + 2. jumboindex != -1 and jumbosize != 0 : jumbo frame is not over size and receiving + 3. jumboindex = -1 and jumbosize != 0 : jumbo frame is over size, already dump + previous receiving and need to continue dumping the current one +*/ +enum { + NormalPacket, + ErrorPacket +}; + +enum { + Frame_NoStart_NoEnd = 0, + Frame_WithStart = 1, + Frame_WithEnd = 10, + Frame_WithStart_WithEnd = 11 +}; + +inline void ipg_nic_rx_free_skb(struct net_device *dev) +{ + struct ipg_nic_private *sp = netdev_priv(dev); + unsigned int entry = sp->rx_current % IPG_RFDLIST_LENGTH; + + if (sp->RxBuff[entry]) { + struct ipg_rx *rxfd = sp->rxd + entry; + + pci_unmap_single(sp->pdev, + le64_to_cpu(rxfd->frag_info & ~IPG_RFI_FRAGLEN), + sp->rx_buf_sz, PCI_DMA_FROMDEVICE); + IPG_DEV_KFREE_SKB(sp->RxBuff[entry]); + sp->RxBuff[entry] = NULL; + } +} + +inline int ipg_nic_rx_check_frame_type(struct net_device *dev) +{ + struct ipg_nic_private *sp = netdev_priv(dev); + struct ipg_rx *rxfd = sp->rxd + (sp->rx_current % IPG_RFDLIST_LENGTH); + int type = Frame_NoStart_NoEnd; + + if (le64_to_cpu(rxfd->rfs) & IPG_RFS_FRAMESTART) + type += Frame_WithStart; + if (le64_to_cpu(rxfd->rfs) & IPG_RFS_FRAMEEND) + type += Frame_WithEnd; + return type; +} + +inline int ipg_nic_rx_check_error(struct net_device *dev) +{ + struct ipg_nic_private *sp = netdev_priv(dev); + unsigned int entry = sp->rx_current % IPG_RFDLIST_LENGTH; + struct ipg_rx *rxfd = sp->rxd + entry; + + if (IPG_DROP_ON_RX_ETH_ERRORS && (le64_to_cpu(rxfd->rfs) & + (IPG_RFS_RXFIFOOVERRUN | IPG_RFS_RXRUNTFRAME | + IPG_RFS_RXALIGNMENTERROR | IPG_RFS_RXFCSERROR | + IPG_RFS_RXOVERSIZEDFRAME | IPG_RFS_RXLENGTHERROR))) { + IPG_DEBUG_MSG("Rx error, RFS = %16.16lx\n", + (unsigned long) rxfd->rfs); + + /* Increment general receive error statistic. */ + sp->stats.rx_errors++; + + /* Increment detailed receive error statistics. */ + if (le64_to_cpu(rxfd->rfs) & IPG_RFS_RXFIFOOVERRUN) { + IPG_DEBUG_MSG("RX FIFO overrun occured.\n"); + + sp->stats.rx_fifo_errors++; + } + + if (le64_to_cpu(rxfd->rfs) & IPG_RFS_RXRUNTFRAME) { + IPG_DEBUG_MSG("RX runt occured.\n"); + sp->stats.rx_length_errors++; + } + + /* Do nothing for IPG_RFS_RXOVERSIZEDFRAME, + * error count handled by a IPG statistic register. + */ + + if (le64_to_cpu(rxfd->rfs) & IPG_RFS_RXALIGNMENTERROR) { + IPG_DEBUG_MSG("RX alignment error occured.\n"); + sp->stats.rx_frame_errors++; + } + + /* Do nothing for IPG_RFS_RXFCSERROR, error count + * handled by a IPG statistic register. + */ + + /* Free the memory associated with the RX + * buffer since it is erroneous and we will + * not pass it to higher layer processes. + */ + if (sp->RxBuff[entry]) { + pci_unmap_single(sp->pdev, + le64_to_cpu(rxfd->frag_info & ~IPG_RFI_FRAGLEN), + sp->rx_buf_sz, PCI_DMA_FROMDEVICE); + + IPG_DEV_KFREE_SKB(sp->RxBuff[entry]); + sp->RxBuff[entry] = NULL; + } + return ErrorPacket; + } + return NormalPacket; +} + +static void ipg_nic_rx_with_start_and_end(struct net_device *dev, + struct ipg_nic_private *sp, + struct ipg_rx *rxfd, unsigned entry) +{ + struct SJumbo *jumbo = &sp->Jumbo; + struct sk_buff *skb; + int framelen; + + if (jumbo->FoundStart) { + IPG_DEV_KFREE_SKB(jumbo->skb); + jumbo->FoundStart = 0; + jumbo->CurrentSize = 0; + jumbo->skb = NULL; + } + + // 1: found error, 0 no error + if (ipg_nic_rx_check_error(dev) != NormalPacket) + return; + + skb = sp->RxBuff[entry]; + if (!skb) + return; + + // accept this frame and send to upper layer + framelen = le64_to_cpu(rxfd->rfs) & IPG_RFS_RXFRAMELEN; + if (framelen > IPG_RXFRAG_SIZE) + framelen = IPG_RXFRAG_SIZE; + + skb_put(skb, framelen); + skb->protocol = eth_type_trans(skb, dev); + skb->ip_summed = CHECKSUM_NONE; + netif_rx(skb); + dev->last_rx = jiffies; + sp->RxBuff[entry] = NULL; +} + +static void ipg_nic_rx_with_start(struct net_device *dev, + struct ipg_nic_private *sp, + struct ipg_rx *rxfd, unsigned entry) +{ + struct SJumbo *jumbo = &sp->Jumbo; + struct pci_dev *pdev = sp->pdev; + struct sk_buff *skb; + + // 1: found error, 0 no error + if (ipg_nic_rx_check_error(dev) != NormalPacket) + return; + + // accept this frame and send to upper layer + skb = sp->RxBuff[entry]; + if (!skb) + return; + + if (jumbo->FoundStart) + IPG_DEV_KFREE_SKB(jumbo->skb); + + pci_unmap_single(pdev, le64_to_cpu(rxfd->frag_info & ~IPG_RFI_FRAGLEN), + sp->rx_buf_sz, PCI_DMA_FROMDEVICE); + + skb_put(skb, IPG_RXFRAG_SIZE); + + jumbo->FoundStart = 1; + jumbo->CurrentSize = IPG_RXFRAG_SIZE; + jumbo->skb = skb; + + sp->RxBuff[entry] = NULL; + dev->last_rx = jiffies; +} + +static void ipg_nic_rx_with_end(struct net_device *dev, + struct ipg_nic_private *sp, + struct ipg_rx *rxfd, unsigned entry) +{ + struct SJumbo *jumbo = &sp->Jumbo; + + //1: found error, 0 no error + if (ipg_nic_rx_check_error(dev) == NormalPacket) { + struct sk_buff *skb = sp->RxBuff[entry]; + + if (!skb) + return; + + if (jumbo->FoundStart) { + int framelen, endframelen; + + framelen = le64_to_cpu(rxfd->rfs) & IPG_RFS_RXFRAMELEN; + + endframeLen = framelen - jumbo->CurrentSize; + /* + if (framelen > IPG_RXFRAG_SIZE) + framelen=IPG_RXFRAG_SIZE; + */ + if (framelen > IPG_RXSUPPORT_SIZE) + IPG_DEV_KFREE_SKB(jumbo->skb); + else { + memcpy(skb_put(jumbo->skb, endframeLen), + skb->data, endframeLen); + + jumbo->skb->protocol = + eth_type_trans(jumbo->skb, dev); + + jumbo->skb->ip_summed = CHECKSUM_NONE; + netif_rx(jumbo->skb); + } + } + + dev->last_rx = jiffies; + jumbo->FoundStart = 0; + jumbo->CurrentSize = 0; + jumbo->skb = NULL; + + ipg_nic_rx_free_skb(dev); + } else { + IPG_DEV_KFREE_SKB(jumbo->skb); + jumbo->FoundStart = 0; + jumbo->CurrentSize = 0; + jumbo->skb = NULL; + } +} + +static void ipg_nic_rx_no_start_no_end(struct net_device *dev, + struct ipg_nic_private *sp, + struct ipg_rx *rxfd, unsigned entry) +{ + struct SJumbo *jumbo = &sp->Jumbo; + + //1: found error, 0 no error + if (ipg_nic_rx_check_error(dev) == NormalPacket) { + struct sk_buff *skb = sp->RxBuff[entry]; + + if (skb) { + if (jumbo->FoundStart) { + jumbo->CurrentSize += IPG_RXFRAG_SIZE; + if (jumbo->CurrentSize <= IPG_RXSUPPORT_SIZE) { + memcpy(skb_put(jumbo->skb, + IPG_RXFRAG_SIZE), + skb->data, IPG_RXFRAG_SIZE); + } + } + dev->last_rx = jiffies; + ipg_nic_rx_free_skb(dev); + } + } else { + IPG_DEV_KFREE_SKB(jumbo->skb); + jumbo->FoundStart = 0; + jumbo->CurrentSize = 0; + jumbo->skb = NULL; + } +} + +static int ipg_nic_rx(struct net_device *dev) +{ + struct ipg_nic_private *sp = netdev_priv(dev); + unsigned int curr = sp->rx_current; + void __iomem *ioaddr = sp->ioaddr; + unsigned int i; + + IPG_DEBUG_MSG("_nic_rx\n"); + + for (i = 0; i < IPG_MAXRFDPROCESS_COUNT; i++, curr++) { + unsigned int entry = curr % IPG_RFDLIST_LENGTH; + struct ipg_rx *rxfd = sp->rxd + entry; + + if (!(rxfd->rfs & le64_to_cpu(IPG_RFS_RFDDONE))) + break; + + switch (ipg_nic_rx_check_frame_type(dev)) { + case Frame_WithStart_WithEnd: + ipg_nic_rx_with_start_and_end(dev, tp, rxfd, entry); + break; + case Frame_WithStart: + ipg_nic_rx_with_start(dev, tp, rxfd, entry); + break; + case Frame_WithEnd: + ipg_nic_rx_with_end(dev, tp, rxfd, entry); + break; + case Frame_NoStart_NoEnd: + ipg_nic_rx_no_start_no_end(dev, tp, rxfd, entry); + break; + } + } + + sp->rx_current = curr; + + if (i == IPG_MAXRFDPROCESS_COUNT) { + /* There are more RFDs to process, however the + * allocated amount of RFD processing time has + * expired. Assert Interrupt Requested to make + * sure we come back to process the remaining RFDs. + */ + ipg_w32(ipg_r32(ASIC_CTRL) | IPG_AC_INT_REQUEST, ASIC_CTRL); + } + + ipg_nic_rxrestore(dev); + + return 0; +} + +#else +static int ipg_nic_rx(struct net_device *dev) +{ + /* Transfer received Ethernet frames to higher network layers. */ + struct ipg_nic_private *sp = netdev_priv(dev); + unsigned int curr = sp->rx_current; + void __iomem *ioaddr = sp->ioaddr; + struct ipg_rx *rxfd; + unsigned int i; + + IPG_DEBUG_MSG("_nic_rx\n"); + +#define __RFS_MASK \ + cpu_to_le64(IPG_RFS_RFDDONE | IPG_RFS_FRAMESTART | IPG_RFS_FRAMEEND) + + for (i = 0; i < IPG_MAXRFDPROCESS_COUNT; i++, curr++) { + unsigned int entry = curr % IPG_RFDLIST_LENGTH; + struct sk_buff *skb = sp->RxBuff[entry]; + unsigned int framelen; + + rxfd = sp->rxd + entry; + + if (((rxfd->rfs & __RFS_MASK) != __RFS_MASK) || !skb) + break; + + /* Get received frame length. */ + framelen = le64_to_cpu(rxfd->rfs) & IPG_RFS_RXFRAMELEN; + + /* Check for jumbo frame arrival with too small + * RXFRAG_SIZE. + */ + if (framelen > IPG_RXFRAG_SIZE) { + IPG_DEBUG_MSG + ("RFS FrameLen > allocated fragment size.\n"); + + framelen = IPG_RXFRAG_SIZE; + } + + if ((IPG_DROP_ON_RX_ETH_ERRORS && (le64_to_cpu(rxfd->rfs & + (IPG_RFS_RXFIFOOVERRUN | IPG_RFS_RXRUNTFRAME | + IPG_RFS_RXALIGNMENTERROR | IPG_RFS_RXFCSERROR | + IPG_RFS_RXOVERSIZEDFRAME | IPG_RFS_RXLENGTHERROR))))) { + + IPG_DEBUG_MSG("Rx error, RFS = %16.16lx\n", + (unsigned long int) rxfd->rfs); + + /* Increment general receive error statistic. */ + sp->stats.rx_errors++; + + /* Increment detailed receive error statistics. */ + if (le64_to_cpu(rxfd->rfs & IPG_RFS_RXFIFOOVERRUN)) { + IPG_DEBUG_MSG("RX FIFO overrun occured.\n"); + sp->stats.rx_fifo_errors++; + } + + if (le64_to_cpu(rxfd->rfs & IPG_RFS_RXRUNTFRAME)) { + IPG_DEBUG_MSG("RX runt occured.\n"); + sp->stats.rx_length_errors++; + } + + if (le64_to_cpu(rxfd->rfs & IPG_RFS_RXOVERSIZEDFRAME)) ; + /* Do nothing, error count handled by a IPG + * statistic register. + */ + + if (le64_to_cpu(rxfd->rfs & IPG_RFS_RXALIGNMENTERROR)) { + IPG_DEBUG_MSG("RX alignment error occured.\n"); + sp->stats.rx_frame_errors++; + } + + if (le64_to_cpu(rxfd->rfs & IPG_RFS_RXFCSERROR)) ; + /* Do nothing, error count handled by a IPG + * statistic register. + */ + + /* Free the memory associated with the RX + * buffer since it is erroneous and we will + * not pass it to higher layer processes. + */ + if (skb) { + u64 info = rxfd->frag_info; + + pci_unmap_single(sp->pdev, + le64_to_cpu(info & ~IPG_RFI_FRAGLEN), + sp->rx_buf_sz, PCI_DMA_FROMDEVICE); + + IPG_DEV_KFREE_SKB(skb); + } + } else { + + /* Adjust the new buffer length to accomodate the size + * of the received frame. + */ + skb_put(skb, framelen); + + /* Set the buffer's protocol field to Ethernet. */ + skb->protocol = eth_type_trans(skb, dev); + + /* If the frame contains an IP/TCP/UDP frame, + * determine if upper layer must check IP/TCP/UDP + * checksums. + * + * NOTE: DO NOT RELY ON THE TCP/UDP CHECKSUM + * VERIFICATION FOR SILICON REVISIONS B3 + * AND EARLIER! + * + if ((le64_to_cpu(rxfd->rfs & + (IPG_RFS_TCPDETECTED | IPG_RFS_UDPDETECTED | + IPG_RFS_IPDETECTED))) && + !(le64_to_cpu(rxfd->rfs & + (IPG_RFS_TCPERROR | IPG_RFS_UDPERROR | + IPG_RFS_IPERROR)))) { + * Indicate IP checksums were performed + * by the IPG. + * + skb->ip_summed = CHECKSUM_UNNECESSARY; + } else + */ + { + /* The IPG encountered an error with (or + * there were no) IP/TCP/UDP checksums. + * This may or may not indicate an invalid + * IP/TCP/UDP frame was received. Let the + * upper layer decide. + */ + skb->ip_summed = CHECKSUM_NONE; + } + + /* Hand off frame for higher layer processing. + * The function netif_rx() releases the sk_buff + * when processing completes. + */ + netif_rx(skb); + + /* Record frame receive time (jiffies = Linux + * kernel current time stamp). + */ + dev->last_rx = jiffies; + } + + /* Assure RX buffer is not reused by IPG. */ + sp->RxBuff[entry] = NULL; + } + + /* + * If there are more RFDs to proces and the allocated amount of RFD + * processing time has expired, assert Interrupt Requested to make + * sure we come back to process the remaining RFDs. + */ + if (i == IPG_MAXRFDPROCESS_COUNT) + ipg_w32(ipg_r32(ASIC_CTRL) | IPG_AC_INT_REQUEST, ASIC_CTRL); + +#ifdef IPG_DEBUG + /* Check if the RFD list contained no receive frame data. */ + if (!i) + sp->EmptyRFDListCount++; +#endif + while ((le64_to_cpu(rxfd->rfs & IPG_RFS_RFDDONE)) && + !((le64_to_cpu(rxfd->rfs & IPG_RFS_FRAMESTART)) && + (le64_to_cpu(rxfd->rfs & IPG_RFS_FRAMEEND)))) { + unsigned int entry = curr++ % IPG_RFDLIST_LENGTH; + + rxfd = sp->rxd + entry; + + IPG_DEBUG_MSG("Frame requires multiple RFDs.\n"); + + /* An unexpected event, additional code needed to handle + * properly. So for the time being, just disregard the + * frame. + */ + + /* Free the memory associated with the RX + * buffer since it is erroneous and we will + * not pass it to higher layer processes. + */ + if (sp->RxBuff[entry]) { + pci_unmap_single(sp->pdev, + le64_to_cpu(rxfd->frag_info & ~IPG_RFI_FRAGLEN), + sp->rx_buf_sz, PCI_DMA_FROMDEVICE); + IPG_DEV_KFREE_SKB(sp->RxBuff[entry]); + } + + /* Assure RX buffer is not reused by IPG. */ + sp->RxBuff[entry] = NULL; + } + + sp->rx_current = curr; + + /* Check to see if there are a minimum number of used + * RFDs before restoring any (should improve performance.) + */ + if ((curr - sp->rx_dirty) >= IPG_MINUSEDRFDSTOFREE) + ipg_nic_rxrestore(dev); + + return 0; +} +#endif + +static void ipg_reset_after_host_error(struct work_struct *work) +{ + struct ipg_nic_private *sp = + container_of(work, struct ipg_nic_private, task.work); + struct net_device *dev = sp->dev; + + IPG_DDEBUG_MSG("DMACtrl = %8.8x\n", ioread32(sp->ioaddr + IPG_DMACTRL)); + + /* + * Acknowledge HostError interrupt by resetting + * IPG DMA and HOST. + */ + ipg_reset(dev, IPG_AC_GLOBAL_RESET | IPG_AC_HOST | IPG_AC_DMA); + + init_rfdlist(dev); + init_tfdlist(dev); + + if (ipg_io_config(dev) < 0) { + printk(KERN_INFO "%s: Cannot recover from PCI error.\n", + dev->name); + schedule_delayed_work(&sp->task, HZ); + } +} + +static irqreturn_t ipg_interrupt_handler(int irq, void *dev_inst) +{ + struct net_device *dev = dev_inst; + struct ipg_nic_private *sp = netdev_priv(dev); + void __iomem *ioaddr = sp->ioaddr; + unsigned int handled = 0; + u16 status; + + IPG_DEBUG_MSG("_interrupt_handler\n"); + +#ifdef JUMBO_FRAME + ipg_nic_rxrestore(dev); +#endif + /* Get interrupt source information, and acknowledge + * some (i.e. TxDMAComplete, RxDMAComplete, RxEarly, + * IntRequested, MacControlFrame, LinkEvent) interrupts + * if issued. Also, all IPG interrupts are disabled by + * reading IntStatusAck. + */ + status = ipg_r16(INT_STATUS_ACK); + + IPG_DEBUG_MSG("IntStatusAck = %4.4x\n", status); + + /* Shared IRQ of remove event. */ + if (!(status & IPG_IS_RSVD_MASK)) + goto out_enable; + + handled = 1; + + if (unlikely(!netif_running(dev))) + goto out; + + spin_lock(&sp->lock); + + /* If RFDListEnd interrupt, restore all used RFDs. */ + if (status & IPG_IS_RFD_LIST_END) { + IPG_DEBUG_MSG("RFDListEnd Interrupt.\n"); + + /* The RFD list end indicates an RFD was encountered + * with a 0 NextPtr, or with an RFDDone bit set to 1 + * (indicating the RFD is not read for use by the + * IPG.) Try to restore all RFDs. + */ + ipg_nic_rxrestore(dev); + +#ifdef IPG_DEBUG + /* Increment the RFDlistendCount counter. */ + sp->RFDlistendCount++; +#endif + } + + /* If RFDListEnd, RxDMAPriority, RxDMAComplete, or + * IntRequested interrupt, process received frames. */ + if ((status & IPG_IS_RX_DMA_PRIORITY) || + (status & IPG_IS_RFD_LIST_END) || + (status & IPG_IS_RX_DMA_COMPLETE) || + (status & IPG_IS_INT_REQUESTED)) { +#ifdef IPG_DEBUG + /* Increment the RFD list checked counter if interrupted + * only to check the RFD list. */ + if (status & (~(IPG_IS_RX_DMA_PRIORITY | IPG_IS_RFD_LIST_END | + IPG_IS_RX_DMA_COMPLETE | IPG_IS_INT_REQUESTED) & + (IPG_IS_HOST_ERROR | IPG_IS_TX_DMA_COMPLETE | + IPG_IS_LINK_EVENT | IPG_IS_TX_COMPLETE | + IPG_IS_UPDATE_STATS))) + sp->RFDListCheckedCount++; +#endif + + ipg_nic_rx(dev); + } + + /* If TxDMAComplete interrupt, free used TFDs. */ + if (status & IPG_IS_TX_DMA_COMPLETE) + ipg_nic_txfree(dev); + + /* TxComplete interrupts indicate one of numerous actions. + * Determine what action to take based on TXSTATUS register. + */ + if (status & IPG_IS_TX_COMPLETE) + ipg_nic_txcleanup(dev); + + /* If UpdateStats interrupt, update Linux Ethernet statistics */ + if (status & IPG_IS_UPDATE_STATS) + ipg_nic_get_stats(dev); + + /* If HostError interrupt, reset IPG. */ + if (status & IPG_IS_HOST_ERROR) { + IPG_DDEBUG_MSG("HostError Interrupt\n"); + + schedule_delayed_work(&sp->task, 0); + } + + /* If LinkEvent interrupt, resolve autonegotiation. */ + if (status & IPG_IS_LINK_EVENT) { + if (ipg_config_autoneg(dev) < 0) + printk(KERN_INFO "%s: Auto-negotiation error.\n", + dev->name); + } + + /* If MACCtrlFrame interrupt, do nothing. */ + if (status & IPG_IS_MAC_CTRL_FRAME) + IPG_DEBUG_MSG("MACCtrlFrame interrupt.\n"); + + /* If RxComplete interrupt, do nothing. */ + if (status & IPG_IS_RX_COMPLETE) + IPG_DEBUG_MSG("RxComplete interrupt.\n"); + + /* If RxEarly interrupt, do nothing. */ + if (status & IPG_IS_RX_EARLY) + IPG_DEBUG_MSG("RxEarly interrupt.\n"); + +out_enable: + /* Re-enable IPG interrupts. */ + ipg_w16(IPG_IE_TX_DMA_COMPLETE | IPG_IE_RX_DMA_COMPLETE | + IPG_IE_HOST_ERROR | IPG_IE_INT_REQUESTED | IPG_IE_TX_COMPLETE | + IPG_IE_LINK_EVENT | IPG_IE_UPDATE_STATS, INT_ENABLE); + + spin_unlock(&sp->lock); +out: + return IRQ_RETVAL(handled); +} + +static void ipg_rx_clear(struct ipg_nic_private *sp) +{ + unsigned int i; + + for (i = 0; i < IPG_RFDLIST_LENGTH; i++) { + if (sp->RxBuff[i]) { + struct ipg_rx *rxfd = sp->rxd + i; + + IPG_DEV_KFREE_SKB(sp->RxBuff[i]); + sp->RxBuff[i] = NULL; + pci_unmap_single(sp->pdev, + le64_to_cpu(rxfd->frag_info & ~IPG_RFI_FRAGLEN), + sp->rx_buf_sz, PCI_DMA_FROMDEVICE); + } + } +} + +static void ipg_tx_clear(struct ipg_nic_private *sp) +{ + unsigned int i; + + for (i = 0; i < IPG_TFDLIST_LENGTH; i++) { + if (sp->TxBuff[i]) { + struct ipg_tx *txfd = sp->txd + i; + + pci_unmap_single(sp->pdev, + le64_to_cpu(txfd->frag_info & ~IPG_TFI_FRAGLEN), + sp->TxBuff[i]->len, PCI_DMA_TODEVICE); + + IPG_DEV_KFREE_SKB(sp->TxBuff[i]); + + sp->TxBuff[i] = NULL; + } + } +} + +static int ipg_nic_open(struct net_device *dev) +{ + struct ipg_nic_private *sp = netdev_priv(dev); + void __iomem *ioaddr = sp->ioaddr; + struct pci_dev *pdev = sp->pdev; + int rc; + + IPG_DEBUG_MSG("_nic_open\n"); + + sp->rx_buf_sz = IPG_RXSUPPORT_SIZE; + + /* Check for interrupt line conflicts, and request interrupt + * line for IPG. + * + * IMPORTANT: Disable IPG interrupts prior to registering + * IRQ. + */ + ipg_w16(0x0000, INT_ENABLE); + + /* Register the interrupt line to be used by the IPG within + * the Linux system. + */ + rc = request_irq(pdev->irq, &ipg_interrupt_handler, IRQF_SHARED, + dev->name, dev); + if (rc < 0) { + printk(KERN_INFO "%s: Error when requesting interrupt.\n", + dev->name); + goto out; + } + + dev->irq = pdev->irq; + + rc = -ENOMEM; + + sp->rxd = dma_alloc_coherent(&pdev->dev, IPG_RX_RING_BYTES, + &sp->rxd_map, GFP_KERNEL); + if (!sp->rxd) + goto err_free_irq_0; + + sp->txd = dma_alloc_coherent(&pdev->dev, IPG_TX_RING_BYTES, + &sp->txd_map, GFP_KERNEL); + if (!sp->txd) + goto err_free_rx_1; + + rc = init_rfdlist(dev); + if (rc < 0) { + printk(KERN_INFO "%s: Error during configuration.\n", + dev->name); + goto err_free_tx_2; + } + + init_tfdlist(dev); + + rc = ipg_io_config(dev); + if (rc < 0) { + printk(KERN_INFO "%s: Error during configuration.\n", + dev->name); + goto err_release_tfdlist_3; + } + + /* Resolve autonegotiation. */ + if (ipg_config_autoneg(dev) < 0) + printk(KERN_INFO "%s: Auto-negotiation error.\n", dev->name); + +#ifdef JUMBO_FRAME + /* initialize JUMBO Frame control variable */ + sp->Jumbo.FoundStart = 0; + sp->Jumbo.CurrentSize = 0; + sp->Jumbo.skb = 0; + dev->mtu = IPG_TXFRAG_SIZE; +#endif + + /* Enable transmit and receive operation of the IPG. */ + ipg_w32((ipg_r32(MAC_CTRL) | IPG_MC_RX_ENABLE | IPG_MC_TX_ENABLE) & + IPG_MC_RSVD_MASK, MAC_CTRL); + + netif_start_queue(dev); +out: + return rc; + +err_release_tfdlist_3: + ipg_tx_clear(sp); + ipg_rx_clear(sp); +err_free_tx_2: + dma_free_coherent(&pdev->dev, IPG_TX_RING_BYTES, sp->txd, sp->txd_map); +err_free_rx_1: + dma_free_coherent(&pdev->dev, IPG_RX_RING_BYTES, sp->rxd, sp->rxd_map); +err_free_irq_0: + free_irq(pdev->irq, dev); + goto out; +} + +static int ipg_nic_stop(struct net_device *dev) +{ + struct ipg_nic_private *sp = netdev_priv(dev); + void __iomem *ioaddr = sp->ioaddr; + struct pci_dev *pdev = sp->pdev; + + IPG_DEBUG_MSG("_nic_stop\n"); + + netif_stop_queue(dev); + + IPG_DDEBUG_MSG("RFDlistendCount = %i\n", sp->RFDlistendCount); + IPG_DDEBUG_MSG("RFDListCheckedCount = %i\n", sp->rxdCheckedCount); + IPG_DDEBUG_MSG("EmptyRFDListCount = %i\n", sp->EmptyRFDListCount); + IPG_DUMPTFDLIST(dev); + + do { + (void) ipg_r16(INT_STATUS_ACK); + + ipg_reset(dev, IPG_AC_GLOBAL_RESET | IPG_AC_HOST | IPG_AC_DMA); + + synchronize_irq(pdev->irq); + } while (ipg_r16(INT_ENABLE) & IPG_IE_RSVD_MASK); + + ipg_rx_clear(sp); + + ipg_tx_clear(sp); + + pci_free_consistent(pdev, IPG_RX_RING_BYTES, sp->rxd, sp->rxd_map); + pci_free_consistent(pdev, IPG_TX_RING_BYTES, sp->txd, sp->txd_map); + + free_irq(pdev->irq, dev); + + return 0; +} + +static int ipg_nic_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) +{ + struct ipg_nic_private *sp = netdev_priv(dev); + void __iomem *ioaddr = sp->ioaddr; + unsigned int entry = sp->tx_current % IPG_TFDLIST_LENGTH; + unsigned long flags; + struct ipg_tx *txfd; + + IPG_DDEBUG_MSG("_nic_hard_start_xmit\n"); + + /* If in 10Mbps mode, stop the transmit queue so + * no more transmit frames are accepted. + */ + if (sp->tenmbpsmode) + netif_stop_queue(dev); + + if (sp->ResetCurrentTFD) { + sp->ResetCurrentTFD = 0; + entry = 0; + } + + txfd = sp->txd + entry; + + sp->TxBuff[entry] = skb; + + /* Clear all TFC fields, except TFDDONE. */ + txfd->tfc = cpu_to_le64(IPG_TFC_TFDDONE); + + /* Specify the TFC field within the TFD. */ + txfd->tfc |= cpu_to_le64(IPG_TFC_WORDALIGNDISABLED | + (IPG_TFC_FRAMEID & cpu_to_le64(sp->tx_current)) | + (IPG_TFC_FRAGCOUNT & (1 << 24))); + + /* Request TxComplete interrupts at an interval defined + * by the constant IPG_FRAMESBETWEENTXCOMPLETES. + * Request TxComplete interrupt for every frame + * if in 10Mbps mode to accomodate problem with 10Mbps + * processing. + */ + if (sp->tenmbpsmode) + txfd->tfc |= cpu_to_le64(IPG_TFC_TXINDICATE); + else if (!((sp->tx_current - sp->tx_dirty + 1) > + IPG_FRAMESBETWEENTXDMACOMPLETES)) { + txfd->tfc |= cpu_to_le64(IPG_TFC_TXDMAINDICATE); + } + /* Based on compilation option, determine if FCS is to be + * appended to transmit frame by IPG. + */ + if (!(IPG_APPEND_FCS_ON_TX)) + txfd->tfc |= cpu_to_le64(IPG_TFC_FCSAPPENDDISABLE); + + /* Based on compilation option, determine if IP, TCP and/or + * UDP checksums are to be added to transmit frame by IPG. + */ + if (IPG_ADD_IPCHECKSUM_ON_TX) + txfd->tfc |= cpu_to_le64(IPG_TFC_IPCHECKSUMENABLE); + + if (IPG_ADD_TCPCHECKSUM_ON_TX) + txfd->tfc |= cpu_to_le64(IPG_TFC_TCPCHECKSUMENABLE); + + if (IPG_ADD_UDPCHECKSUM_ON_TX) + txfd->tfc |= cpu_to_le64(IPG_TFC_UDPCHECKSUMENABLE); + + /* Based on compilation option, determine if VLAN tag info is to be + * inserted into transmit frame by IPG. + */ + if (IPG_INSERT_MANUAL_VLAN_TAG) { + txfd->tfc |= cpu_to_le64(IPG_TFC_VLANTAGINSERT | + ((u64) IPG_MANUAL_VLAN_VID << 32) | + ((u64) IPG_MANUAL_VLAN_CFI << 44) | + ((u64) IPG_MANUAL_VLAN_USERPRIORITY << 45)); + } + + /* The fragment start location within system memory is defined + * by the sk_buff structure's data field. The physical address + * of this location within the system's virtual memory space + * is determined using the IPG_HOST2BUS_MAP function. + */ + txfd->frag_info = cpu_to_le64(pci_map_single(sp->pdev, skb->data, + skb->len, PCI_DMA_TODEVICE)); + + /* The length of the fragment within system memory is defined by + * the sk_buff structure's len field. + */ + txfd->frag_info |= cpu_to_le64(IPG_TFI_FRAGLEN & + ((u64) (skb->len & 0xffff) << 48)); + + /* Clear the TFDDone bit last to indicate the TFD is ready + * for transfer to the IPG. + */ + txfd->tfc &= cpu_to_le64(~IPG_TFC_TFDDONE); + + spin_lock_irqsave(&sp->lock, flags); + + sp->tx_current++; + + mmiowb(); + + ipg_w32(IPG_DC_TX_DMA_POLL_NOW, DMA_CTRL); + + if (sp->tx_current == (sp->tx_dirty + IPG_TFDLIST_LENGTH)) + netif_wake_queue(dev); + + spin_unlock_irqrestore(&sp->lock, flags); + + return NETDEV_TX_OK; +} + +static void ipg_set_phy_default_param(unsigned char rev, + struct net_device *dev, int phy_address) +{ + unsigned short length; + unsigned char revision; + unsigned short *phy_param; + unsigned short address, value; + + phy_param = &DefaultPhyParam[0]; + length = *phy_param & 0x00FF; + revision = (unsigned char)((*phy_param) >> 8); + phy_param++; + while (length != 0) { + if (rev == revision) { + while (length > 1) { + address = *phy_param; + value = *(phy_param + 1); + phy_param += 2; + mdio_write(dev, phy_address, address, value); + length -= 4; + } + break; + } else { + phy_param += length / 2; + length = *phy_param & 0x00FF; + revision = (unsigned char)((*phy_param) >> 8); + phy_param++; + } + } +} + +/* JES20040127EEPROM */ +static int read_eeprom(struct net_device *dev, int eep_addr) +{ + void __iomem *ioaddr = ipg_ioaddr(dev); + unsigned int i; + int ret = 0; + u16 value; + + value = IPG_EC_EEPROM_READOPCODE | (eep_addr & 0xff); + ipg_w16(value, EEPROM_CTRL); + + for (i = 0; i < 1000; i++) { + u16 data; + + mdelay(10); + data = ipg_r16(EEPROM_CTRL); + if (!(data & IPG_EC_EEPROM_BUSY)) { + ret = ipg_r16(EEPROM_DATA); + break; + } + } + return ret; +} + +static void ipg_init_mii(struct net_device *dev) +{ + struct ipg_nic_private *sp = netdev_priv(dev); + struct mii_if_info *mii_if = &sp->mii_if; + int phyaddr; + + mii_if->dev = dev; + mii_if->mdio_read = mdio_read; + mii_if->mdio_write = mdio_write; + mii_if->phy_id_mask = 0x1f; + mii_if->reg_num_mask = 0x1f; + + mii_if->phy_id = phyaddr = ipg_find_phyaddr(dev); + + if (phyaddr != 0x1f) { + u16 mii_phyctrl, mii_1000cr; + u8 revisionid = 0; + + mii_1000cr = mdio_read(dev, phyaddr, MII_CTRL1000); + mii_1000cr |= ADVERTISE_1000FULL | ADVERTISE_1000HALF | + GMII_PHY_1000BASETCONTROL_PreferMaster; + mdio_write(dev, phyaddr, MII_CTRL1000, mii_1000cr); + + mii_phyctrl = mdio_read(dev, phyaddr, MII_BMCR); + + /* Set default phyparam */ + pci_read_config_byte(sp->pdev, PCI_REVISION_ID, &revisionid); + ipg_set_phy_default_param(revisionid, dev, phyaddr); + + /* Reset PHY */ + mii_phyctrl |= BMCR_RESET | BMCR_ANRESTART; + mdio_write(dev, phyaddr, MII_BMCR, mii_phyctrl); + + } +} + +static int ipg_hw_init(struct net_device *dev) +{ + struct ipg_nic_private *sp = netdev_priv(dev); + void __iomem *ioaddr = sp->ioaddr; + unsigned int i; + int rc; + + /* Read/Write and Reset EEPROM Value Jesse20040128EEPROM_VALUE */ + /* Read LED Mode Configuration from EEPROM */ + sp->LED_Mode = read_eeprom(dev, 6); + + /* Reset all functions within the IPG. Do not assert + * RST_OUT as not compatible with some PHYs. + */ + rc = ipg_reset(dev, IPG_RESET_MASK); + if (rc < 0) + goto out; + + ipg_init_mii(dev); + + /* Read MAC Address from EEPROM */ + for (i = 0; i < 3; i++) + sp->station_addr[i] = read_eeprom(dev, 16 + i); + + for (i = 0; i < 3; i++) + ipg_w16(sp->station_addr[i], STATION_ADDRESS_0 + 2*i); + + /* Set station address in ethernet_device structure. */ + dev->dev_addr[0] = ipg_r16(STATION_ADDRESS_0) & 0x00ff; + dev->dev_addr[1] = (ipg_r16(STATION_ADDRESS_0) & 0xff00) >> 8; + dev->dev_addr[2] = ipg_r16(STATION_ADDRESS_1) & 0x00ff; + dev->dev_addr[3] = (ipg_r16(STATION_ADDRESS_1) & 0xff00) >> 8; + dev->dev_addr[4] = ipg_r16(STATION_ADDRESS_2) & 0x00ff; + dev->dev_addr[5] = (ipg_r16(STATION_ADDRESS_2) & 0xff00) >> 8; +out: + return rc; +} + +static int ipg_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) +{ + struct ipg_nic_private *sp = netdev_priv(dev); + int rc; + + mutex_lock(&sp->mii_mutex); + rc = generic_mii_ioctl(&sp->mii_if, if_mii(ifr), cmd, NULL); + mutex_unlock(&sp->mii_mutex); + + return rc; +} + +static int ipg_nic_change_mtu(struct net_device *dev, int new_mtu) +{ + /* Function to accomodate changes to Maximum Transfer Unit + * (or MTU) of IPG NIC. Cannot use default function since + * the default will not allow for MTU > 1500 bytes. + */ + + IPG_DEBUG_MSG("_nic_change_mtu\n"); + + /* Check that the new MTU value is between 68 (14 byte header, 46 + * byte payload, 4 byte FCS) and IPG_MAX_RXFRAME_SIZE, which + * corresponds to the MAXFRAMESIZE register in the IPG. + */ + if ((new_mtu < 68) || (new_mtu > IPG_MAX_RXFRAME_SIZE)) + return -EINVAL; + + dev->mtu = new_mtu; + + return 0; +} + +static int ipg_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) +{ + struct ipg_nic_private *sp = netdev_priv(dev); + int rc; + + mutex_lock(&sp->mii_mutex); + rc = mii_ethtool_gset(&sp->mii_if, cmd); + mutex_unlock(&sp->mii_mutex); + + return rc; +} + +static int ipg_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) +{ + struct ipg_nic_private *sp = netdev_priv(dev); + int rc; + + mutex_lock(&sp->mii_mutex); + rc = mii_ethtool_sset(&sp->mii_if, cmd); + mutex_unlock(&sp->mii_mutex); + + return rc; +} + +static int ipg_nway_reset(struct net_device *dev) +{ + struct ipg_nic_private *sp = netdev_priv(dev); + int rc; + + mutex_lock(&sp->mii_mutex); + rc = mii_nway_restart(&sp->mii_if); + mutex_unlock(&sp->mii_mutex); + + return rc; +} + +static struct ethtool_ops ipg_ethtool_ops = { + .get_settings = ipg_get_settings, + .set_settings = ipg_set_settings, + .nway_reset = ipg_nway_reset, +}; + +static void ipg_remove(struct pci_dev *pdev) +{ + struct net_device *dev = pci_get_drvdata(pdev); + struct ipg_nic_private *sp = netdev_priv(dev); + + IPG_DEBUG_MSG("_remove\n"); + + /* Un-register Ethernet device. */ + unregister_netdev(dev); + + pci_iounmap(pdev, sp->ioaddr); + + pci_release_regions(pdev); + + free_netdev(dev); + pci_disable_device(pdev); + pci_set_drvdata(pdev, NULL); +} + +static int __devinit ipg_probe(struct pci_dev *pdev, + const struct pci_device_id *id) +{ + unsigned int i = id->driver_data; + struct ipg_nic_private *sp; + struct net_device *dev; + void __iomem *ioaddr; + int rc; + + rc = pci_enable_device(pdev); + if (rc < 0) + goto out; + + printk(KERN_INFO "%s: %s\n", pci_name(pdev), ipg_brand_name[i]); + + pci_set_master(pdev); + + rc = pci_set_dma_mask(pdev, DMA_40BIT_MASK); + if (rc < 0) { + rc = pci_set_dma_mask(pdev, DMA_32BIT_MASK); + if (rc < 0) { + printk(KERN_ERR "%s: DMA config failed.\n", + pci_name(pdev)); + goto err_disable_0; + } + } + + /* + * Initialize net device. + */ + dev = alloc_etherdev(sizeof(struct ipg_nic_private)); + if (!dev) { + printk(KERN_ERR "%s: alloc_etherdev failed\n", pci_name(pdev)); + rc = -ENOMEM; + goto err_disable_0; + } + + sp = netdev_priv(dev); + spin_lock_init(&sp->lock); + mutex_init(&sp->mii_mutex); + + /* Declare IPG NIC functions for Ethernet device methods. + */ + dev->open = &ipg_nic_open; + dev->stop = &ipg_nic_stop; + dev->hard_start_xmit = &ipg_nic_hard_start_xmit; + dev->get_stats = &ipg_nic_get_stats; + dev->set_multicast_list = &ipg_nic_set_multicast_list; + dev->do_ioctl = ipg_ioctl; + dev->tx_timeout = ipg_tx_timeout; + dev->change_mtu = &ipg_nic_change_mtu; + + SET_NETDEV_DEV(dev, &pdev->dev); + SET_ETHTOOL_OPS(dev, &ipg_ethtool_ops); + + rc = pci_request_regions(pdev, DRV_NAME); + if (rc) + goto err_free_dev_1; + + ioaddr = pci_iomap(pdev, 1, pci_resource_len(pdev, 1)); + if (!ioaddr) { + printk(KERN_ERR "%s cannot map MMIO\n", pci_name(pdev)); + rc = -EIO; + goto err_release_regions_2; + } + + /* Save the pointer to the PCI device information. */ + sp->ioaddr = ioaddr; + sp->pdev = pdev; + sp->dev = dev; + + INIT_DELAYED_WORK(&sp->task, ipg_reset_after_host_error); + + pci_set_drvdata(pdev, dev); + + rc = ipg_hw_init(dev); + if (rc < 0) + goto err_unmap_3; + + rc = register_netdev(dev); + if (rc < 0) + goto err_unmap_3; + + printk(KERN_INFO "Ethernet device registered as: %s\n", dev->name); +out: + return rc; + +err_unmap_3: + pci_iounmap(pdev, ioaddr); +err_release_regions_2: + pci_release_regions(pdev); +err_free_dev_1: + free_netdev(dev); +err_disable_0: + pci_disable_device(pdev); + goto out; +} + +static struct pci_driver ipg_pci_driver = { + .name = IPG_DRIVER_NAME, + .id_table = ipg_pci_tbl, + .probe = ipg_probe, + .remove = __devexit_p(ipg_remove), +}; + +static int __init ipg_init_module(void) +{ + return pci_register_driver(&ipg_pci_driver); +} + +static void __exit ipg_exit_module(void) +{ + pci_unregister_driver(&ipg_pci_driver); +} + +module_init(ipg_init_module); +module_exit(ipg_exit_module); diff --git a/drivers/net/ipg.h b/drivers/net/ipg.h new file mode 100644 index 000000000000..1952d0dfd314 --- /dev/null +++ b/drivers/net/ipg.h @@ -0,0 +1,856 @@ +/* + * + * ipg.h + * + * Include file for Gigabit Ethernet device driver for Network + * Interface Cards (NICs) utilizing the Tamarack Microelectronics + * Inc. IPG Gigabit or Triple Speed Ethernet Media Access + * Controller. + * + * Craig Rich + * Sundance Technology, Inc. + * 1485 Saratoga Avenue + * Suite 200 + * San Jose, CA 95129 + * 408 873 4117 + * www.sundanceti.com + * craig_rich@sundanceti.com + */ +#ifndef __LINUX_IPG_H +#define __LINUX_IPG_H + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +/*#include */ + +#define DrvVer "2.09d" + +#define IPG_DEV_KFREE_SKB(skb) dev_kfree_skb_irq(skb) + +/* + * Constants + */ + +/* GMII based PHY IDs */ +#define NS 0x2000 +#define MARVELL 0x0141 +#define ICPLUS_PHY 0x243 + +/* NIC Physical Layer Device MII register fields. */ +#define MII_PHY_SELECTOR_IEEE8023 0x0001 +#define MII_PHY_TECHABILITYFIELD 0x1FE0 + +/* GMII_PHY_1000 need to set to prefer master */ +#define GMII_PHY_1000BASETCONTROL_PreferMaster 0x0400 + +/* NIC Physical Layer Device GMII constants. */ +#define GMII_PREAMBLE 0xFFFFFFFF +#define GMII_ST 0x1 +#define GMII_READ 0x2 +#define GMII_WRITE 0x1 +#define GMII_TA_READ_MASK 0x1 +#define GMII_TA_WRITE 0x2 + +/* I/O register offsets. */ +enum ipg_regs { + DMA_CTRL = 0x00, + RX_DMA_STATUS = 0x08, // Unused + reserved + TFD_LIST_PTR_0 = 0x10, + TFD_LIST_PTR_1 = 0x14, + TX_DMA_BURST_THRESH = 0x18, + TX_DMA_URGENT_THRESH = 0x19, + TX_DMA_POLL_PERIOD = 0x1a, + RFD_LIST_PTR_0 = 0x1c, + RFD_LIST_PTR_1 = 0x20, + RX_DMA_BURST_THRESH = 0x24, + RX_DMA_URGENT_THRESH = 0x25, + RX_DMA_POLL_PERIOD = 0x26, + DEBUG_CTRL = 0x2c, + ASIC_CTRL = 0x30, + FIFO_CTRL = 0x38, // Unused + FLOW_OFF_THRESH = 0x3c, + FLOW_ON_THRESH = 0x3e, + EEPROM_DATA = 0x48, + EEPROM_CTRL = 0x4a, + EXPROM_ADDR = 0x4c, // Unused + EXPROM_DATA = 0x50, // Unused + WAKE_EVENT = 0x51, // Unused + COUNTDOWN = 0x54, // Unused + INT_STATUS_ACK = 0x5a, + INT_ENABLE = 0x5c, + INT_STATUS = 0x5e, // Unused + TX_STATUS = 0x60, + MAC_CTRL = 0x6c, + VLAN_TAG = 0x70, // Unused + PHY_SET = 0x75, // JES20040127EEPROM + PHY_CTRL = 0x76, + STATION_ADDRESS_0 = 0x78, + STATION_ADDRESS_1 = 0x7a, + STATION_ADDRESS_2 = 0x7c, + MAX_FRAME_SIZE = 0x86, + RECEIVE_MODE = 0x88, + HASHTABLE_0 = 0x8c, + HASHTABLE_1 = 0x90, + RMON_STATISTICS_MASK = 0x98, + STATISTICS_MASK = 0x9c, + RX_JUMBO_FRAMES = 0xbc, // Unused + TCP_CHECKSUM_ERRORS = 0xc0, // Unused + IP_CHECKSUM_ERRORS = 0xc2, // Unused + UDP_CHECKSUM_ERRORS = 0xc4, // Unused + TX_JUMBO_FRAMES = 0xf4 // Unused +}; + +/* Ethernet MIB statistic register offsets. */ +#define IPG_OCTETRCVOK 0xA8 +#define IPG_MCSTOCTETRCVDOK 0xAC +#define IPG_BCSTOCTETRCVOK 0xB0 +#define IPG_FRAMESRCVDOK 0xB4 +#define IPG_MCSTFRAMESRCVDOK 0xB8 +#define IPG_BCSTFRAMESRCVDOK 0xBE +#define IPG_MACCONTROLFRAMESRCVD 0xC6 +#define IPG_FRAMETOOLONGERRRORS 0xC8 +#define IPG_INRANGELENGTHERRORS 0xCA +#define IPG_FRAMECHECKSEQERRORS 0xCC +#define IPG_FRAMESLOSTRXERRORS 0xCE +#define IPG_OCTETXMTOK 0xD0 +#define IPG_MCSTOCTETXMTOK 0xD4 +#define IPG_BCSTOCTETXMTOK 0xD8 +#define IPG_FRAMESXMTDOK 0xDC +#define IPG_MCSTFRAMESXMTDOK 0xE0 +#define IPG_FRAMESWDEFERREDXMT 0xE4 +#define IPG_LATECOLLISIONS 0xE8 +#define IPG_MULTICOLFRAMES 0xEC +#define IPG_SINGLECOLFRAMES 0xF0 +#define IPG_BCSTFRAMESXMTDOK 0xF6 +#define IPG_CARRIERSENSEERRORS 0xF8 +#define IPG_MACCONTROLFRAMESXMTDOK 0xFA +#define IPG_FRAMESABORTXSCOLLS 0xFC +#define IPG_FRAMESWEXDEFERRAL 0xFE + +/* RMON statistic register offsets. */ +#define IPG_ETHERSTATSCOLLISIONS 0x100 +#define IPG_ETHERSTATSOCTETSTRANSMIT 0x104 +#define IPG_ETHERSTATSPKTSTRANSMIT 0x108 +#define IPG_ETHERSTATSPKTS64OCTESTSTRANSMIT 0x10C +#define IPG_ETHERSTATSPKTS65TO127OCTESTSTRANSMIT 0x110 +#define IPG_ETHERSTATSPKTS128TO255OCTESTSTRANSMIT 0x114 +#define IPG_ETHERSTATSPKTS256TO511OCTESTSTRANSMIT 0x118 +#define IPG_ETHERSTATSPKTS512TO1023OCTESTSTRANSMIT 0x11C +#define IPG_ETHERSTATSPKTS1024TO1518OCTESTSTRANSMIT 0x120 +#define IPG_ETHERSTATSCRCALIGNERRORS 0x124 +#define IPG_ETHERSTATSUNDERSIZEPKTS 0x128 +#define IPG_ETHERSTATSFRAGMENTS 0x12C +#define IPG_ETHERSTATSJABBERS 0x130 +#define IPG_ETHERSTATSOCTETS 0x134 +#define IPG_ETHERSTATSPKTS 0x138 +#define IPG_ETHERSTATSPKTS64OCTESTS 0x13C +#define IPG_ETHERSTATSPKTS65TO127OCTESTS 0x140 +#define IPG_ETHERSTATSPKTS128TO255OCTESTS 0x144 +#define IPG_ETHERSTATSPKTS256TO511OCTESTS 0x148 +#define IPG_ETHERSTATSPKTS512TO1023OCTESTS 0x14C +#define IPG_ETHERSTATSPKTS1024TO1518OCTESTS 0x150 + +/* RMON statistic register equivalents. */ +#define IPG_ETHERSTATSMULTICASTPKTSTRANSMIT 0xE0 +#define IPG_ETHERSTATSBROADCASTPKTSTRANSMIT 0xF6 +#define IPG_ETHERSTATSMULTICASTPKTS 0xB8 +#define IPG_ETHERSTATSBROADCASTPKTS 0xBE +#define IPG_ETHERSTATSOVERSIZEPKTS 0xC8 +#define IPG_ETHERSTATSDROPEVENTS 0xCE + +/* Serial EEPROM offsets */ +#define IPG_EEPROM_CONFIGPARAM 0x00 +#define IPG_EEPROM_ASICCTRL 0x01 +#define IPG_EEPROM_SUBSYSTEMVENDORID 0x02 +#define IPG_EEPROM_SUBSYSTEMID 0x03 +#define IPG_EEPROM_STATIONADDRESS0 0x10 +#define IPG_EEPROM_STATIONADDRESS1 0x11 +#define IPG_EEPROM_STATIONADDRESS2 0x12 + +/* Register & data structure bit masks */ + +/* PCI register masks. */ + +/* IOBaseAddress */ +#define IPG_PIB_RSVD_MASK 0xFFFFFE01 +#define IPG_PIB_IOBASEADDRESS 0xFFFFFF00 +#define IPG_PIB_IOBASEADDRIND 0x00000001 + +/* MemBaseAddress */ +#define IPG_PMB_RSVD_MASK 0xFFFFFE07 +#define IPG_PMB_MEMBASEADDRIND 0x00000001 +#define IPG_PMB_MEMMAPTYPE 0x00000006 +#define IPG_PMB_MEMMAPTYPE0 0x00000002 +#define IPG_PMB_MEMMAPTYPE1 0x00000004 +#define IPG_PMB_MEMBASEADDRESS 0xFFFFFE00 + +/* ConfigStatus */ +#define IPG_CS_RSVD_MASK 0xFFB0 +#define IPG_CS_CAPABILITIES 0x0010 +#define IPG_CS_66MHZCAPABLE 0x0020 +#define IPG_CS_FASTBACK2BACK 0x0080 +#define IPG_CS_DATAPARITYREPORTED 0x0100 +#define IPG_CS_DEVSELTIMING 0x0600 +#define IPG_CS_SIGNALEDTARGETABORT 0x0800 +#define IPG_CS_RECEIVEDTARGETABORT 0x1000 +#define IPG_CS_RECEIVEDMASTERABORT 0x2000 +#define IPG_CS_SIGNALEDSYSTEMERROR 0x4000 +#define IPG_CS_DETECTEDPARITYERROR 0x8000 + +/* TFD data structure masks. */ + +/* TFDList, TFC */ +#define IPG_TFC_RSVD_MASK 0x0000FFFF9FFFFFFF +#define IPG_TFC_FRAMEID 0x000000000000FFFF +#define IPG_TFC_WORDALIGN 0x0000000000030000 +#define IPG_TFC_WORDALIGNTODWORD 0x0000000000000000 +#define IPG_TFC_WORDALIGNTOWORD 0x0000000000020000 +#define IPG_TFC_WORDALIGNDISABLED 0x0000000000030000 +#define IPG_TFC_TCPCHECKSUMENABLE 0x0000000000040000 +#define IPG_TFC_UDPCHECKSUMENABLE 0x0000000000080000 +#define IPG_TFC_IPCHECKSUMENABLE 0x0000000000100000 +#define IPG_TFC_FCSAPPENDDISABLE 0x0000000000200000 +#define IPG_TFC_TXINDICATE 0x0000000000400000 +#define IPG_TFC_TXDMAINDICATE 0x0000000000800000 +#define IPG_TFC_FRAGCOUNT 0x000000000F000000 +#define IPG_TFC_VLANTAGINSERT 0x0000000010000000 +#define IPG_TFC_TFDDONE 0x0000000080000000 +#define IPG_TFC_VID 0x00000FFF00000000 +#define IPG_TFC_CFI 0x0000100000000000 +#define IPG_TFC_USERPRIORITY 0x0000E00000000000 + +/* TFDList, FragInfo */ +#define IPG_TFI_RSVD_MASK 0xFFFF00FFFFFFFFFF +#define IPG_TFI_FRAGADDR 0x000000FFFFFFFFFF +#define IPG_TFI_FRAGLEN 0xFFFF000000000000LL + +/* RFD data structure masks. */ + +/* RFDList, RFS */ +#define IPG_RFS_RSVD_MASK 0x0000FFFFFFFFFFFF +#define IPG_RFS_RXFRAMELEN 0x000000000000FFFF +#define IPG_RFS_RXFIFOOVERRUN 0x0000000000010000 +#define IPG_RFS_RXRUNTFRAME 0x0000000000020000 +#define IPG_RFS_RXALIGNMENTERROR 0x0000000000040000 +#define IPG_RFS_RXFCSERROR 0x0000000000080000 +#define IPG_RFS_RXOVERSIZEDFRAME 0x0000000000100000 +#define IPG_RFS_RXLENGTHERROR 0x0000000000200000 +#define IPG_RFS_VLANDETECTED 0x0000000000400000 +#define IPG_RFS_TCPDETECTED 0x0000000000800000 +#define IPG_RFS_TCPERROR 0x0000000001000000 +#define IPG_RFS_UDPDETECTED 0x0000000002000000 +#define IPG_RFS_UDPERROR 0x0000000004000000 +#define IPG_RFS_IPDETECTED 0x0000000008000000 +#define IPG_RFS_IPERROR 0x0000000010000000 +#define IPG_RFS_FRAMESTART 0x0000000020000000 +#define IPG_RFS_FRAMEEND 0x0000000040000000 +#define IPG_RFS_RFDDONE 0x0000000080000000 +#define IPG_RFS_TCI 0x0000FFFF00000000 + +/* RFDList, FragInfo */ +#define IPG_RFI_RSVD_MASK 0xFFFF00FFFFFFFFFF +#define IPG_RFI_FRAGADDR 0x000000FFFFFFFFFF +#define IPG_RFI_FRAGLEN 0xFFFF000000000000LL + +/* I/O Register masks. */ + +/* RMON Statistics Mask */ +#define IPG_RZ_ALL 0x0FFFFFFF + +/* Statistics Mask */ +#define IPG_SM_ALL 0x0FFFFFFF +#define IPG_SM_OCTETRCVOK_FRAMESRCVDOK 0x00000001 +#define IPG_SM_MCSTOCTETRCVDOK_MCSTFRAMESRCVDOK 0x00000002 +#define IPG_SM_BCSTOCTETRCVDOK_BCSTFRAMESRCVDOK 0x00000004 +#define IPG_SM_RXJUMBOFRAMES 0x00000008 +#define IPG_SM_TCPCHECKSUMERRORS 0x00000010 +#define IPG_SM_IPCHECKSUMERRORS 0x00000020 +#define IPG_SM_UDPCHECKSUMERRORS 0x00000040 +#define IPG_SM_MACCONTROLFRAMESRCVD 0x00000080 +#define IPG_SM_FRAMESTOOLONGERRORS 0x00000100 +#define IPG_SM_INRANGELENGTHERRORS 0x00000200 +#define IPG_SM_FRAMECHECKSEQERRORS 0x00000400 +#define IPG_SM_FRAMESLOSTRXERRORS 0x00000800 +#define IPG_SM_OCTETXMTOK_FRAMESXMTOK 0x00001000 +#define IPG_SM_MCSTOCTETXMTOK_MCSTFRAMESXMTDOK 0x00002000 +#define IPG_SM_BCSTOCTETXMTOK_BCSTFRAMESXMTDOK 0x00004000 +#define IPG_SM_FRAMESWDEFERREDXMT 0x00008000 +#define IPG_SM_LATECOLLISIONS 0x00010000 +#define IPG_SM_MULTICOLFRAMES 0x00020000 +#define IPG_SM_SINGLECOLFRAMES 0x00040000 +#define IPG_SM_TXJUMBOFRAMES 0x00080000 +#define IPG_SM_CARRIERSENSEERRORS 0x00100000 +#define IPG_SM_MACCONTROLFRAMESXMTD 0x00200000 +#define IPG_SM_FRAMESABORTXSCOLLS 0x00400000 +#define IPG_SM_FRAMESWEXDEFERAL 0x00800000 + +/* Countdown */ +#define IPG_CD_RSVD_MASK 0x0700FFFF +#define IPG_CD_COUNT 0x0000FFFF +#define IPG_CD_COUNTDOWNSPEED 0x01000000 +#define IPG_CD_COUNTDOWNMODE 0x02000000 +#define IPG_CD_COUNTINTENABLED 0x04000000 + +/* TxDMABurstThresh */ +#define IPG_TB_RSVD_MASK 0xFF + +/* TxDMAUrgentThresh */ +#define IPG_TU_RSVD_MASK 0xFF + +/* TxDMAPollPeriod */ +#define IPG_TP_RSVD_MASK 0xFF + +/* RxDMAUrgentThresh */ +#define IPG_RU_RSVD_MASK 0xFF + +/* RxDMAPollPeriod */ +#define IPG_RP_RSVD_MASK 0xFF + +/* ReceiveMode */ +#define IPG_RM_RSVD_MASK 0x3F +#define IPG_RM_RECEIVEUNICAST 0x01 +#define IPG_RM_RECEIVEMULTICAST 0x02 +#define IPG_RM_RECEIVEBROADCAST 0x04 +#define IPG_RM_RECEIVEALLFRAMES 0x08 +#define IPG_RM_RECEIVEMULTICASTHASH 0x10 +#define IPG_RM_RECEIVEIPMULTICAST 0x20 + +/* PhySet JES20040127EEPROM*/ +#define IPG_PS_MEM_LENB9B 0x01 +#define IPG_PS_MEM_LEN9 0x02 +#define IPG_PS_NON_COMPDET 0x04 + +/* PhyCtrl */ +#define IPG_PC_RSVD_MASK 0xFF +#define IPG_PC_MGMTCLK_LO 0x00 +#define IPG_PC_MGMTCLK_HI 0x01 +#define IPG_PC_MGMTCLK 0x01 +#define IPG_PC_MGMTDATA 0x02 +#define IPG_PC_MGMTDIR 0x04 +#define IPG_PC_DUPLEX_POLARITY 0x08 +#define IPG_PC_DUPLEX_STATUS 0x10 +#define IPG_PC_LINK_POLARITY 0x20 +#define IPG_PC_LINK_SPEED 0xC0 +#define IPG_PC_LINK_SPEED_10MBPS 0x40 +#define IPG_PC_LINK_SPEED_100MBPS 0x80 +#define IPG_PC_LINK_SPEED_1000MBPS 0xC0 + +/* DMACtrl */ +#define IPG_DC_RSVD_MASK 0xC07D9818 +#define IPG_DC_RX_DMA_COMPLETE 0x00000008 +#define IPG_DC_RX_DMA_POLL_NOW 0x00000010 +#define IPG_DC_TX_DMA_COMPLETE 0x00000800 +#define IPG_DC_TX_DMA_POLL_NOW 0x00001000 +#define IPG_DC_TX_DMA_IN_PROG 0x00008000 +#define IPG_DC_RX_EARLY_DISABLE 0x00010000 +#define IPG_DC_MWI_DISABLE 0x00040000 +#define IPG_DC_TX_WRITE_BACK_DISABLE 0x00080000 +#define IPG_DC_TX_BURST_LIMIT 0x00700000 +#define IPG_DC_TARGET_ABORT 0x40000000 +#define IPG_DC_MASTER_ABORT 0x80000000 + +/* ASICCtrl */ +#define IPG_AC_RSVD_MASK 0x07FFEFF2 +#define IPG_AC_EXP_ROM_SIZE 0x00000002 +#define IPG_AC_PHY_SPEED10 0x00000010 +#define IPG_AC_PHY_SPEED100 0x00000020 +#define IPG_AC_PHY_SPEED1000 0x00000040 +#define IPG_AC_PHY_MEDIA 0x00000080 +#define IPG_AC_FORCED_CFG 0x00000700 +#define IPG_AC_D3RESETDISABLE 0x00000800 +#define IPG_AC_SPEED_UP_MODE 0x00002000 +#define IPG_AC_LED_MODE 0x00004000 +#define IPG_AC_RST_OUT_POLARITY 0x00008000 +#define IPG_AC_GLOBAL_RESET 0x00010000 +#define IPG_AC_RX_RESET 0x00020000 +#define IPG_AC_TX_RESET 0x00040000 +#define IPG_AC_DMA 0x00080000 +#define IPG_AC_FIFO 0x00100000 +#define IPG_AC_NETWORK 0x00200000 +#define IPG_AC_HOST 0x00400000 +#define IPG_AC_AUTO_INIT 0x00800000 +#define IPG_AC_RST_OUT 0x01000000 +#define IPG_AC_INT_REQUEST 0x02000000 +#define IPG_AC_RESET_BUSY 0x04000000 +#define IPG_AC_LED_SPEED 0x08000000 //JES20040127EEPROM +#define IPG_AC_LED_MODE_BIT_1 0x20000000 //JES20040127EEPROM + +/* EepromCtrl */ +#define IPG_EC_RSVD_MASK 0x83FF +#define IPG_EC_EEPROM_ADDR 0x00FF +#define IPG_EC_EEPROM_OPCODE 0x0300 +#define IPG_EC_EEPROM_SUBCOMMAD 0x0000 +#define IPG_EC_EEPROM_WRITEOPCODE 0x0100 +#define IPG_EC_EEPROM_READOPCODE 0x0200 +#define IPG_EC_EEPROM_ERASEOPCODE 0x0300 +#define IPG_EC_EEPROM_BUSY 0x8000 + +/* FIFOCtrl */ +#define IPG_FC_RSVD_MASK 0xC001 +#define IPG_FC_RAM_TEST_MODE 0x0001 +#define IPG_FC_TRANSMITTING 0x4000 +#define IPG_FC_RECEIVING 0x8000 + +/* TxStatus */ +#define IPG_TS_RSVD_MASK 0xFFFF00DD +#define IPG_TS_TX_ERROR 0x00000001 +#define IPG_TS_LATE_COLLISION 0x00000004 +#define IPG_TS_TX_MAX_COLL 0x00000008 +#define IPG_TS_TX_UNDERRUN 0x00000010 +#define IPG_TS_TX_IND_REQD 0x00000040 +#define IPG_TS_TX_COMPLETE 0x00000080 +#define IPG_TS_TX_FRAMEID 0xFFFF0000 + +/* WakeEvent */ +#define IPG_WE_WAKE_PKT_ENABLE 0x01 +#define IPG_WE_MAGIC_PKT_ENABLE 0x02 +#define IPG_WE_LINK_EVT_ENABLE 0x04 +#define IPG_WE_WAKE_POLARITY 0x08 +#define IPG_WE_WAKE_PKT_EVT 0x10 +#define IPG_WE_MAGIC_PKT_EVT 0x20 +#define IPG_WE_LINK_EVT 0x40 +#define IPG_WE_WOL_ENABLE 0x80 + +/* IntEnable */ +#define IPG_IE_RSVD_MASK 0x1FFE +#define IPG_IE_HOST_ERROR 0x0002 +#define IPG_IE_TX_COMPLETE 0x0004 +#define IPG_IE_MAC_CTRL_FRAME 0x0008 +#define IPG_IE_RX_COMPLETE 0x0010 +#define IPG_IE_RX_EARLY 0x0020 +#define IPG_IE_INT_REQUESTED 0x0040 +#define IPG_IE_UPDATE_STATS 0x0080 +#define IPG_IE_LINK_EVENT 0x0100 +#define IPG_IE_TX_DMA_COMPLETE 0x0200 +#define IPG_IE_RX_DMA_COMPLETE 0x0400 +#define IPG_IE_RFD_LIST_END 0x0800 +#define IPG_IE_RX_DMA_PRIORITY 0x1000 + +/* IntStatus */ +#define IPG_IS_RSVD_MASK 0x1FFF +#define IPG_IS_INTERRUPT_STATUS 0x0001 +#define IPG_IS_HOST_ERROR 0x0002 +#define IPG_IS_TX_COMPLETE 0x0004 +#define IPG_IS_MAC_CTRL_FRAME 0x0008 +#define IPG_IS_RX_COMPLETE 0x0010 +#define IPG_IS_RX_EARLY 0x0020 +#define IPG_IS_INT_REQUESTED 0x0040 +#define IPG_IS_UPDATE_STATS 0x0080 +#define IPG_IS_LINK_EVENT 0x0100 +#define IPG_IS_TX_DMA_COMPLETE 0x0200 +#define IPG_IS_RX_DMA_COMPLETE 0x0400 +#define IPG_IS_RFD_LIST_END 0x0800 +#define IPG_IS_RX_DMA_PRIORITY 0x1000 + +/* MACCtrl */ +#define IPG_MC_RSVD_MASK 0x7FE33FA3 +#define IPG_MC_IFS_SELECT 0x00000003 +#define IPG_MC_IFS_4352BIT 0x00000003 +#define IPG_MC_IFS_1792BIT 0x00000002 +#define IPG_MC_IFS_1024BIT 0x00000001 +#define IPG_MC_IFS_96BIT 0x00000000 +#define IPG_MC_DUPLEX_SELECT 0x00000020 +#define IPG_MC_DUPLEX_SELECT_FD 0x00000020 +#define IPG_MC_DUPLEX_SELECT_HD 0x00000000 +#define IPG_MC_TX_FLOW_CONTROL_ENABLE 0x00000080 +#define IPG_MC_RX_FLOW_CONTROL_ENABLE 0x00000100 +#define IPG_MC_RCV_FCS 0x00000200 +#define IPG_MC_FIFO_LOOPBACK 0x00000400 +#define IPG_MC_MAC_LOOPBACK 0x00000800 +#define IPG_MC_AUTO_VLAN_TAGGING 0x00001000 +#define IPG_MC_AUTO_VLAN_UNTAGGING 0x00002000 +#define IPG_MC_COLLISION_DETECT 0x00010000 +#define IPG_MC_CARRIER_SENSE 0x00020000 +#define IPG_MC_STATISTICS_ENABLE 0x00200000 +#define IPG_MC_STATISTICS_DISABLE 0x00400000 +#define IPG_MC_STATISTICS_ENABLED 0x00800000 +#define IPG_MC_TX_ENABLE 0x01000000 +#define IPG_MC_TX_DISABLE 0x02000000 +#define IPG_MC_TX_ENABLED 0x04000000 +#define IPG_MC_RX_ENABLE 0x08000000 +#define IPG_MC_RX_DISABLE 0x10000000 +#define IPG_MC_RX_ENABLED 0x20000000 +#define IPG_MC_PAUSED 0x40000000 + +/* + * Tune + */ + +/* Miscellaneous Constants. */ +#define TRUE 1 +#define FALSE 0 + +/* Assign IPG_APPEND_FCS_ON_TX > 0 for auto FCS append on TX. */ +#define IPG_APPEND_FCS_ON_TX TRUE + +/* Assign IPG_APPEND_FCS_ON_TX > 0 for auto FCS strip on RX. */ +#define IPG_STRIP_FCS_ON_RX TRUE + +/* Assign IPG_DROP_ON_RX_ETH_ERRORS > 0 to drop RX frames with + * Ethernet errors. + */ +#define IPG_DROP_ON_RX_ETH_ERRORS TRUE + +/* Assign IPG_INSERT_MANUAL_VLAN_TAG > 0 to insert VLAN tags manually + * (via TFC). + */ +#define IPG_INSERT_MANUAL_VLAN_TAG FALSE + +/* Assign IPG_ADD_IPCHECKSUM_ON_TX > 0 for auto IP checksum on TX. */ +#define IPG_ADD_IPCHECKSUM_ON_TX FALSE + +/* Assign IPG_ADD_TCPCHECKSUM_ON_TX > 0 for auto TCP checksum on TX. + * DO NOT USE FOR SILICON REVISIONS B3 AND EARLIER. + */ +#define IPG_ADD_TCPCHECKSUM_ON_TX FALSE + +/* Assign IPG_ADD_UDPCHECKSUM_ON_TX > 0 for auto UDP checksum on TX. + * DO NOT USE FOR SILICON REVISIONS B3 AND EARLIER. + */ +#define IPG_ADD_UDPCHECKSUM_ON_TX FALSE + +/* If inserting VLAN tags manually, assign the IPG_MANUAL_VLAN_xx + * constants as desired. + */ +#define IPG_MANUAL_VLAN_VID 0xABC +#define IPG_MANUAL_VLAN_CFI 0x1 +#define IPG_MANUAL_VLAN_USERPRIORITY 0x5 + +#define IPG_IO_REG_RANGE 0xFF +#define IPG_MEM_REG_RANGE 0x154 +#define IPG_DRIVER_NAME "Sundance Technology IPG Triple-Speed Ethernet" +#define IPG_NIC_PHY_ADDRESS 0x01 +#define IPG_DMALIST_ALIGN_PAD 0x07 +#define IPG_MULTICAST_HASHTABLE_SIZE 0x40 + +/* Number of miliseconds to wait after issuing a software reset. + * 0x05 <= IPG_AC_RESETWAIT to account for proper 10Mbps operation. + */ +#define IPG_AC_RESETWAIT 0x05 + +/* Number of IPG_AC_RESETWAIT timeperiods before declaring timeout. */ +#define IPG_AC_RESET_TIMEOUT 0x0A + +/* Minimum number of nanoseconds used to toggle MDC clock during + * MII/GMII register access. + */ +#define IPG_PC_PHYCTRLWAIT_NS 200 + +#define IPG_TFDLIST_LENGTH 0x100 + +/* Number of frames between TxDMAComplete interrupt. + * 0 < IPG_FRAMESBETWEENTXDMACOMPLETES <= IPG_TFDLIST_LENGTH + */ +#define IPG_FRAMESBETWEENTXDMACOMPLETES 0x1 + +#ifdef JUMBO_FRAME + +# ifdef JUMBO_FRAME_SIZE_2K +# define JUMBO_FRAME_SIZE 2048 +# define __IPG_RXFRAG_SIZE 2048 +# else +# ifdef JUMBO_FRAME_SIZE_3K +# define JUMBO_FRAME_SIZE 3072 +# define __IPG_RXFRAG_SIZE 3072 +# else +# ifdef JUMBO_FRAME_SIZE_4K +# define JUMBO_FRAME_SIZE 4096 +# define __IPG_RXFRAG_SIZE 4088 +# else +# ifdef JUMBO_FRAME_SIZE_5K +# define JUMBO_FRAME_SIZE 5120 +# define __IPG_RXFRAG_SIZE 4088 +# else +# ifdef JUMBO_FRAME_SIZE_6K +# define JUMBO_FRAME_SIZE 6144 +# define __IPG_RXFRAG_SIZE 4088 +# else +# ifdef JUMBO_FRAME_SIZE_7K +# define JUMBO_FRAME_SIZE 7168 +# define __IPG_RXFRAG_SIZE 4088 +# else +# ifdef JUMBO_FRAME_SIZE_8K +# define JUMBO_FRAME_SIZE 8192 +# define __IPG_RXFRAG_SIZE 4088 +# else +# ifdef JUMBO_FRAME_SIZE_9K +# define JUMBO_FRAME_SIZE 9216 +# define __IPG_RXFRAG_SIZE 4088 +# else +# ifdef JUMBO_FRAME_SIZE_10K +# define JUMBO_FRAME_SIZE 10240 +# define __IPG_RXFRAG_SIZE 4088 +# else +# define JUMBO_FRAME_SIZE 4096 +# endif +# endif +# endif +# endif +# endif +# endif +# endif +# endif +# endif +#endif + +/* Size of allocated received buffers. Nominally 0x0600. + * Define larger if expecting jumbo frames. + */ +#ifdef JUMBO_FRAME +//IPG_TXFRAG_SIZE must <= 0x2b00, or TX will crash +#define IPG_TXFRAG_SIZE JUMBO_FRAME_SIZE +#endif + +/* Size of allocated received buffers. Nominally 0x0600. + * Define larger if expecting jumbo frames. + */ +#ifdef JUMBO_FRAME +//4088=4096-8 +#define IPG_RXFRAG_SIZE __IPG_RXFRAG_SIZE +#define IPG_RXSUPPORT_SIZE IPG_MAX_RXFRAME_SIZE +#else +#define IPG_RXFRAG_SIZE 0x0600 +#define IPG_RXSUPPORT_SIZE IPG_RXFRAG_SIZE +#endif + +/* IPG_MAX_RXFRAME_SIZE <= IPG_RXFRAG_SIZE */ +#ifdef JUMBO_FRAME +#define IPG_MAX_RXFRAME_SIZE JUMBO_FRAME_SIZE +#else +#define IPG_MAX_RXFRAME_SIZE 0x0600 +#endif + +#define IPG_RFDLIST_LENGTH 0x100 + +/* Maximum number of RFDs to process per interrupt. + * 1 < IPG_MAXRFDPROCESS_COUNT < IPG_RFDLIST_LENGTH + */ +#define IPG_MAXRFDPROCESS_COUNT 0x80 + +/* Minimum margin between last freed RFD, and current RFD. + * 1 < IPG_MINUSEDRFDSTOFREE < IPG_RFDLIST_LENGTH + */ +#define IPG_MINUSEDRFDSTOFREE 0x80 + +/* specify the jumbo frame maximum size + * per unit is 0x600 (the RxBuffer size that one RFD can carry) + */ +#define MAX_JUMBOSIZE 0x8 // max is 12K + +/* Key register values loaded at driver start up. */ + +/* TXDMAPollPeriod is specified in 320ns increments. + * + * Value Time + * --------------------- + * 0x00-0x01 320ns + * 0x03 ~1us + * 0x1F ~10us + * 0xFF ~82us + */ +#define IPG_TXDMAPOLLPERIOD_VALUE 0x26 + +/* TxDMAUrgentThresh specifies the minimum amount of + * data in the transmit FIFO before asserting an + * urgent transmit DMA request. + * + * Value Min TxFIFO occupied space before urgent TX request + * --------------------------------------------------------------- + * 0x00-0x04 128 bytes (1024 bits) + * 0x27 1248 bytes (~10000 bits) + * 0x30 1536 bytes (12288 bits) + * 0xFF 8192 bytes (65535 bits) + */ +#define IPG_TXDMAURGENTTHRESH_VALUE 0x04 + +/* TxDMABurstThresh specifies the minimum amount of + * free space in the transmit FIFO before asserting an + * transmit DMA request. + * + * Value Min TxFIFO free space before TX request + * ---------------------------------------------------- + * 0x00-0x08 256 bytes + * 0x30 1536 bytes + * 0xFF 8192 bytes + */ +#define IPG_TXDMABURSTTHRESH_VALUE 0x30 + +/* RXDMAPollPeriod is specified in 320ns increments. + * + * Value Time + * --------------------- + * 0x00-0x01 320ns + * 0x03 ~1us + * 0x1F ~10us + * 0xFF ~82us + */ +#define IPG_RXDMAPOLLPERIOD_VALUE 0x01 + +/* RxDMAUrgentThresh specifies the minimum amount of + * free space within the receive FIFO before asserting + * a urgent receive DMA request. + * + * Value Min RxFIFO free space before urgent RX request + * --------------------------------------------------------------- + * 0x00-0x04 128 bytes (1024 bits) + * 0x27 1248 bytes (~10000 bits) + * 0x30 1536 bytes (12288 bits) + * 0xFF 8192 bytes (65535 bits) + */ +#define IPG_RXDMAURGENTTHRESH_VALUE 0x30 + +/* RxDMABurstThresh specifies the minimum amount of + * occupied space within the receive FIFO before asserting + * a receive DMA request. + * + * Value Min TxFIFO free space before TX request + * ---------------------------------------------------- + * 0x00-0x08 256 bytes + * 0x30 1536 bytes + * 0xFF 8192 bytes + */ +#define IPG_RXDMABURSTTHRESH_VALUE 0x30 + +/* FlowOnThresh specifies the maximum amount of occupied + * space in the receive FIFO before a PAUSE frame with + * maximum pause time transmitted. + * + * Value Max RxFIFO occupied space before PAUSE + * --------------------------------------------------- + * 0x0000 0 bytes + * 0x0740 29,696 bytes + * 0x07FF 32,752 bytes + */ +#define IPG_FLOWONTHRESH_VALUE 0x0740 + +/* FlowOffThresh specifies the minimum amount of occupied + * space in the receive FIFO before a PAUSE frame with + * zero pause time is transmitted. + * + * Value Max RxFIFO occupied space before PAUSE + * --------------------------------------------------- + * 0x0000 0 bytes + * 0x00BF 3056 bytes + * 0x07FF 32,752 bytes + */ +#define IPG_FLOWOFFTHRESH_VALUE 0x00BF + +/* + * Miscellaneous macros. + */ + +/* Marco for printing debug statements. +# define IPG_DDEBUG_MSG(args...) printk(KERN_DEBUG "IPG: " ## args) */ +#ifdef IPG_DEBUG +# define IPG_DEBUG_MSG(args...) +# define IPG_DDEBUG_MSG(args...) printk(KERN_DEBUG "IPG: " args) +# define IPG_DUMPRFDLIST(args) ipg_dump_rfdlist(args) +# define IPG_DUMPTFDLIST(args) ipg_dump_tfdlist(args) +#else +# define IPG_DEBUG_MSG(args...) +# define IPG_DDEBUG_MSG(args...) +# define IPG_DUMPRFDLIST(args) +# define IPG_DUMPTFDLIST(args) +#endif + +/* + * End miscellaneous macros. + */ + +/* Transmit Frame Descriptor. The IPG supports 15 fragments, + * however Linux requires only a single fragment. Note, each + * TFD field is 64 bits wide. + */ +struct ipg_tx { + u64 next_desc; + u64 tfc; + u64 frag_info; +}; + +/* Receive Frame Descriptor. Note, each RFD field is 64 bits wide. + */ +struct ipg_rx { + u64 next_desc; + u64 rfs; + u64 frag_info; +}; + +struct SJumbo { + int FoundStart; + int CurrentSize; + struct sk_buff *skb; +}; +/* Structure of IPG NIC specific data. */ +struct ipg_nic_private { + void __iomem *ioaddr; + struct ipg_tx *txd; + struct ipg_rx *rxd; + dma_addr_t txd_map; + dma_addr_t rxd_map; + struct sk_buff *TxBuff[IPG_TFDLIST_LENGTH]; + struct sk_buff *RxBuff[IPG_RFDLIST_LENGTH]; + unsigned int tx_current; + unsigned int tx_dirty; + unsigned int rx_current; + unsigned int rx_dirty; +// Add by Grace 2005/05/19 +#ifdef JUMBO_FRAME + struct SJumbo Jumbo; +#endif + unsigned int rx_buf_sz; + struct pci_dev *pdev; + struct net_device *dev; + struct net_device_stats stats; + spinlock_t lock; + int tenmbpsmode; + + /*Jesse20040128EEPROM_VALUE */ + u16 LED_Mode; + u16 station_addr[3]; /* Station Address in EEPROM Reg 0x10..0x12 */ + + struct mutex mii_mutex; + struct mii_if_info mii_if; + int ResetCurrentTFD; +#ifdef IPG_DEBUG + int RFDlistendCount; + int RFDListCheckedCount; + int EmptyRFDListCount; +#endif + struct delayed_work task; +}; + +//variable record -- index by leading revision/length +//Revision/Length(=N*4), Address1, Data1, Address2, Data2,...,AddressN,DataN +unsigned short DefaultPhyParam[] = { + // 11/12/03 IP1000A v1-3 rev=0x40 + /*-------------------------------------------------------------------------- + (0x4000|(15*4)), 31, 0x0001, 27, 0x01e0, 31, 0x0002, 22, 0x85bd, 24, 0xfff2, + 27, 0x0c10, 28, 0x0c10, 29, 0x2c10, 31, 0x0003, 23, 0x92f6, + 31, 0x0000, 23, 0x003d, 30, 0x00de, 20, 0x20e7, 9, 0x0700, + --------------------------------------------------------------------------*/ + // 12/17/03 IP1000A v1-4 rev=0x40 + (0x4000 | (07 * 4)), 31, 0x0001, 27, 0x01e0, 31, 0x0002, 27, 0xeb8e, 31, + 0x0000, + 30, 0x005e, 9, 0x0700, + // 01/09/04 IP1000A v1-5 rev=0x41 + (0x4100 | (07 * 4)), 31, 0x0001, 27, 0x01e0, 31, 0x0002, 27, 0xeb8e, 31, + 0x0000, + 30, 0x005e, 9, 0x0700, + 0x0000 +}; + +#endif /* __LINUX_IPG_H */ diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index 55f307ffbf96..c9c24ddf9c7b 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -1841,6 +1841,8 @@ #define PCI_VENDOR_ID_ABOCOM 0x13D1 #define PCI_DEVICE_ID_ABOCOM_2BD1 0x2BD1 +#define PCI_VENDOR_ID_SUNDANCE 0x13f0 + #define PCI_VENDOR_ID_CMEDIA 0x13f6 #define PCI_DEVICE_ID_CMEDIA_CM8338A 0x0100 #define PCI_DEVICE_ID_CMEDIA_CM8338B 0x0101 -- cgit v1.2.3 From 1a348ccc1047a00507e554826775a3d81f7f3437 Mon Sep 17 00:00:00 2001 From: Andy Gospodarek Date: Mon, 17 Sep 2007 18:50:36 -0700 Subject: [NET]: Add Tehuti network driver. [ Ported to napi_struct changes... -DaveM ] Signed-off-by: David S. Miller --- MAINTAINERS | 8 + drivers/net/Kconfig | 6 + drivers/net/Makefile | 1 + drivers/net/tehuti.c | 2508 +++++++++++ drivers/net/tehuti.h | 564 +++ drivers/net/tehuti_fw.h | 10712 ++++++++++++++++++++++++++++++++++++++++++++++ include/linux/pci_ids.h | 5 + 7 files changed, 13804 insertions(+) create mode 100644 drivers/net/tehuti.c create mode 100644 drivers/net/tehuti.h create mode 100644 drivers/net/tehuti_fw.h (limited to 'include/linux') diff --git a/MAINTAINERS b/MAINTAINERS index 27cd503cf0e4..3f07d5ff85f1 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -3630,6 +3630,14 @@ M: hlhung3i@gmail.com W: http://tcp-lp-mod.sourceforge.net/ S: Maintained +TEHUTI ETHERNET DRIVER +P: Alexander Indenbaum +M: baum@tehutinetworks.net +P: Andy Gospodarek +M: andy@greyhouse.net +L: netdev@vger.kernel.org +S: Supported + TI FLASH MEDIA INTERFACE DRIVER P: Alex Dubov M: oakad@yahoo.com diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 63ab05b5a87a..fd284a93c9dd 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -2661,6 +2661,12 @@ config MLX4_DEBUG debug_level module parameter (which can also be set after the driver is loaded through sysfs). +config TEHUTI + tristate "Tehuti Networks 10G Ethernet" + depends on PCI + help + Tehuti Networks 10G Ethernet NIC + endif # NETDEV_10000 source "drivers/net/tokenring/Kconfig" diff --git a/drivers/net/Makefile b/drivers/net/Makefile index 2098647080a0..2ab33e8b9159 100644 --- a/drivers/net/Makefile +++ b/drivers/net/Makefile @@ -14,6 +14,7 @@ obj-$(CONFIG_EHEA) += ehea/ obj-$(CONFIG_BONDING) += bonding/ obj-$(CONFIG_ATL1) += atl1/ obj-$(CONFIG_GIANFAR) += gianfar_driver.o +obj-$(CONFIG_TEHUTI) += tehuti.o gianfar_driver-objs := gianfar.o \ gianfar_ethtool.o \ diff --git a/drivers/net/tehuti.c b/drivers/net/tehuti.c new file mode 100644 index 000000000000..248343177356 --- /dev/null +++ b/drivers/net/tehuti.c @@ -0,0 +1,2508 @@ +/* + * Tehuti Networks(R) Network Driver + * ethtool interface implementation + * Copyright (C) 2007 Tehuti Networks Ltd. All rights reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +/* + * RX HW/SW interaction overview + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * There are 2 types of RX communication channels betwean driver and NIC. + * 1) RX Free Fifo - RXF - holds descriptors of empty buffers to accept incoming + * traffic. This Fifo is filled by SW and is readen by HW. Each descriptor holds + * info about buffer's location, size and ID. An ID field is used to identify a + * buffer when it's returned with data via RXD Fifo (see below) + * 2) RX Data Fifo - RXD - holds descriptors of full buffers. This Fifo is + * filled by HW and is readen by SW. Each descriptor holds status and ID. + * HW pops descriptor from RXF Fifo, stores ID, fills buffer with incoming data, + * via dma moves it into host memory, builds new RXD descriptor with same ID, + * pushes it into RXD Fifo and raises interrupt to indicate new RX data. + * + * Current NIC configuration (registers + firmware) makes NIC use 2 RXF Fifos. + * One holds 1.5K packets and another - 26K packets. Depending on incoming + * packet size, HW desides on a RXF Fifo to pop buffer from. When packet is + * filled with data, HW builds new RXD descriptor for it and push it into single + * RXD Fifo. + * + * RX SW Data Structures + * ~~~~~~~~~~~~~~~~~~~~~ + * skb db - used to keep track of all skbs owned by SW and their dma addresses. + * For RX case, ownership lasts from allocating new empty skb for RXF until + * accepting full skb from RXD and passing it to OS. Each RXF Fifo has its own + * skb db. Implemented as array with bitmask. + * fifo - keeps info about fifo's size and location, relevant HW registers, + * usage and skb db. Each RXD and RXF Fifo has its own fifo structure. + * Implemented as simple struct. + * + * RX SW Execution Flow + * ~~~~~~~~~~~~~~~~~~~~ + * Upon initialization (ifconfig up) driver creates RX fifos and initializes + * relevant registers. At the end of init phase, driver enables interrupts. + * NIC sees that there is no RXF buffers and raises + * RD_INTR interrupt, isr fills skbs and Rx begins. + * Driver has two receive operation modes: + * NAPI - interrupt-driven mixed with polling + * interrupt-driven only + * + * Interrupt-driven only flow is following. When buffer is ready, HW raises + * interrupt and isr is called. isr collects all available packets + * (bdx_rx_receive), refills skbs (bdx_rx_alloc_skbs) and exit. + + * Rx buffer allocation note + * ~~~~~~~~~~~~~~~~~~~~~~~~~ + * Driver cares to feed such amount of RxF descriptors that respective amount of + * RxD descriptors can not fill entire RxD fifo. The main reason is lack of + * overflow check in Bordeaux for RxD fifo free/used size. + * FIXME: this is NOT fully implemented, more work should be done + * + */ + +#include "tehuti.h" +#include "tehuti_fw.h" + +static struct pci_device_id __devinitdata bdx_pci_tbl[] = { + {0x1FC9, 0x3009, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, + {0x1FC9, 0x3010, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, + {0x1FC9, 0x3014, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, + {0} +}; + +MODULE_DEVICE_TABLE(pci, bdx_pci_tbl); + +/* Definitions needed by ISR or NAPI functions */ +static void bdx_rx_alloc_skbs(struct bdx_priv *priv, struct rxf_fifo *f); +static void bdx_tx_cleanup(struct bdx_priv *priv); +static int bdx_rx_receive(struct bdx_priv *priv, struct rxd_fifo *f, int budget); + +/* Definitions needed by FW loading */ +static void bdx_tx_push_desc_safe(struct bdx_priv *priv, void *data, int size); + +/* Definitions needed by hw_start */ +static int bdx_tx_init(struct bdx_priv *priv); +static int bdx_rx_init(struct bdx_priv *priv); + +/* Definitions needed by bdx_close */ +static void bdx_rx_free(struct bdx_priv *priv); +static void bdx_tx_free(struct bdx_priv *priv); + +/* Definitions needed by bdx_probe */ +static void bdx_ethtool_ops(struct net_device *netdev); + +/************************************************************************* + * Print Info * + *************************************************************************/ + +static void print_hw_id(struct pci_dev *pdev) +{ + struct pci_nic *nic = pci_get_drvdata(pdev); + u16 pci_link_status = 0; + u16 pci_ctrl = 0; + + pci_read_config_word(pdev, PCI_LINK_STATUS_REG, &pci_link_status); + pci_read_config_word(pdev, PCI_DEV_CTRL_REG, &pci_ctrl); + + printk(KERN_INFO "tehuti: %s%s\n", BDX_NIC_NAME, + nic->port_num == 1 ? "" : ", 2-Port"); + printk(KERN_INFO + "tehuti: srom 0x%x fpga %d build %u lane# %d" + " max_pl 0x%x mrrs 0x%x\n", + readl(nic->regs + SROM_VER), readl(nic->regs + FPGA_VER) & 0xFFF, + readl(nic->regs + FPGA_SEED), + GET_LINK_STATUS_LANES(pci_link_status), + GET_DEV_CTRL_MAXPL(pci_ctrl), GET_DEV_CTRL_MRRS(pci_ctrl)); +} + +static void print_fw_id(struct pci_nic *nic) +{ + printk(KERN_INFO "tehuti: fw 0x%x\n", readl(nic->regs + FW_VER)); +} + +static void print_eth_id(struct net_device *ndev) +{ + printk(KERN_INFO "%s: %s, Port %c\n", ndev->name, BDX_NIC_NAME, + (ndev->if_port == 0) ? 'A' : 'B'); + +} + +/************************************************************************* + * Code * + *************************************************************************/ + +#define bdx_enable_interrupts(priv) \ + do { WRITE_REG(priv, regIMR, IR_RUN); } while (0) +#define bdx_disable_interrupts(priv) \ + do { WRITE_REG(priv, regIMR, 0); } while (0) + +/* bdx_fifo_init + * create TX/RX descriptor fifo for host-NIC communication. + * 1K extra space is allocated at the end of the fifo to simplify + * processing of descriptors that wraps around fifo's end + * @priv - NIC private structure + * @f - fifo to initialize + * @fsz_type - fifo size type: 0-4KB, 1-8KB, 2-16KB, 3-32KB + * @reg_XXX - offsets of registers relative to base address + * + * Returns 0 on success, negative value on failure + * + */ +static int +bdx_fifo_init(struct bdx_priv *priv, struct fifo *f, int fsz_type, + u16 reg_CFG0, u16 reg_CFG1, u16 reg_RPTR, u16 reg_WPTR) +{ + u16 memsz = FIFO_SIZE * (1 << fsz_type); + + memset(f, 0, sizeof(struct fifo)); + /* pci_alloc_consistent gives us 4k-aligned memory */ + f->va = pci_alloc_consistent(priv->pdev, + memsz + FIFO_EXTRA_SPACE, &f->da); + if (!f->va) { + ERR("pci_alloc_consistent failed\n"); + RET(-ENOMEM); + } + f->reg_CFG0 = reg_CFG0; + f->reg_CFG1 = reg_CFG1; + f->reg_RPTR = reg_RPTR; + f->reg_WPTR = reg_WPTR; + f->rptr = 0; + f->wptr = 0; + f->memsz = memsz; + f->size_mask = memsz - 1; + WRITE_REG(priv, reg_CFG0, (u32) ((f->da & TX_RX_CFG0_BASE) | fsz_type)); + WRITE_REG(priv, reg_CFG1, H32_64(f->da)); + + RET(0); +} + +/* bdx_fifo_free - free all resources used by fifo + * @priv - NIC private structure + * @f - fifo to release + */ +static void bdx_fifo_free(struct bdx_priv *priv, struct fifo *f) +{ + ENTER; + if (f->va) { + pci_free_consistent(priv->pdev, + f->memsz + FIFO_EXTRA_SPACE, f->va, f->da); + f->va = NULL; + } + RET(); +} + +/* + * bdx_link_changed - notifies OS about hw link state. + * @bdx_priv - hw adapter structure + */ +static void bdx_link_changed(struct bdx_priv *priv) +{ + u32 link = READ_REG(priv, regMAC_LNK_STAT) & MAC_LINK_STAT; + + if (!link) { + if (netif_carrier_ok(priv->ndev)) { + netif_stop_queue(priv->ndev); + netif_carrier_off(priv->ndev); + ERR("%s: Link Down\n", priv->ndev->name); + } + } else { + if (!netif_carrier_ok(priv->ndev)) { + netif_wake_queue(priv->ndev); + netif_carrier_on(priv->ndev); + ERR("%s: Link Up\n", priv->ndev->name); + } + } +} + +static void bdx_isr_extra(struct bdx_priv *priv, u32 isr) +{ + if (isr & IR_RX_FREE_0) { + bdx_rx_alloc_skbs(priv, &priv->rxf_fifo0); + DBG("RX_FREE_0\n"); + } + + if (isr & IR_LNKCHG0) + bdx_link_changed(priv); + + if (isr & IR_PCIE_LINK) + ERR("%s: PCI-E Link Fault\n", priv->ndev->name); + + if (isr & IR_PCIE_TOUT) + ERR("%s: PCI-E Time Out\n", priv->ndev->name); + +} + +/* bdx_isr - Interrupt Service Routine for Bordeaux NIC + * @irq - interrupt number + * @ndev - network device + * @regs - CPU registers + * + * Return IRQ_NONE if it was not our interrupt, IRQ_HANDLED - otherwise + * + * It reads ISR register to know interrupt reasons, and proceed them one by one. + * Reasons of interest are: + * RX_DESC - new packet has arrived and RXD fifo holds its descriptor + * RX_FREE - number of free Rx buffers in RXF fifo gets low + * TX_FREE - packet was transmited and RXF fifo holds its descriptor + */ + +static irqreturn_t bdx_isr_napi(int irq, void *dev) +{ + struct net_device *ndev = dev; + struct bdx_priv *priv = ndev->priv; + u32 isr; + + ENTER; + isr = (READ_REG(priv, regISR) & IR_RUN); + if (unlikely(!isr)) { + bdx_enable_interrupts(priv); + return IRQ_NONE; /* Not our interrupt */ + } + + if (isr & IR_EXTRA) + bdx_isr_extra(priv, isr); + + if (isr & (IR_RX_DESC_0 | IR_TX_FREE_0)) { + if (likely(netif_rx_schedule_prep(ndev, &priv->napi))) { + __netif_rx_schedule(ndev, &priv->napi); + RET(IRQ_HANDLED); + } else { + /* NOTE: we get here if intr has slipped into window + * between these lines in bdx_poll: + * bdx_enable_interrupts(priv); + * return 0; + * currently intrs are disabled (since we read ISR), + * and we have failed to register next poll. + * so we read the regs to trigger chip + * and allow further interupts. */ + READ_REG(priv, regTXF_WPTR_0); + READ_REG(priv, regRXD_WPTR_0); + } + } + + bdx_enable_interrupts(priv); + RET(IRQ_HANDLED); +} + +static int bdx_poll(struct napi_struct *napi, int budget) +{ + struct bdx_priv *priv = container_of(napi, struct bdx_priv, napi); + struct net_device *dev = priv->ndev; + int work_done; + + ENTER; + bdx_tx_cleanup(priv); + work_done = bdx_rx_receive(priv, &priv->rxd_fifo0, budget); + if ((work_done < budget) || + (priv->napi_stop++ >= 30)) { + DBG("rx poll is done. backing to isr-driven\n"); + + /* from time to time we exit to let NAPI layer release + * device lock and allow waiting tasks (eg rmmod) to advance) */ + priv->napi_stop = 0; + + netif_rx_complete(dev, napi); + bdx_enable_interrupts(priv); + } + return work_done; +} + +/* bdx_fw_load - loads firmware to NIC + * @priv - NIC private structure + * Firmware is loaded via TXD fifo, so it must be initialized first. + * Firware must be loaded once per NIC not per PCI device provided by NIC (NIC + * can have few of them). So all drivers use semaphore register to choose one + * that will actually load FW to NIC. + */ + +static int bdx_fw_load(struct bdx_priv *priv) +{ + int master, i; + + ENTER; + master = READ_REG(priv, regINIT_SEMAPHORE); + if (!READ_REG(priv, regINIT_STATUS) && master) { + bdx_tx_push_desc_safe(priv, s_firmLoad, sizeof(s_firmLoad)); + mdelay(100); + } + for (i = 0; i < 200; i++) { + if (READ_REG(priv, regINIT_STATUS)) + break; + mdelay(2); + } + if (master) + WRITE_REG(priv, regINIT_SEMAPHORE, 1); + + if (i == 200) { + ERR("%s: firmware loading failed\n", priv->ndev->name); + DBG("VPC = 0x%x VIC = 0x%x INIT_STATUS = 0x%x i=%d\n", + READ_REG(priv, regVPC), + READ_REG(priv, regVIC), READ_REG(priv, regINIT_STATUS), i); + RET(-EIO); + } else { + DBG("%s: firmware loading success\n", priv->ndev->name); + RET(0); + } +} + +static void bdx_restore_mac(struct net_device *ndev, struct bdx_priv *priv) +{ + u32 val; + + ENTER; + DBG("mac0=%x mac1=%x mac2=%x\n", + READ_REG(priv, regUNC_MAC0_A), + READ_REG(priv, regUNC_MAC1_A), READ_REG(priv, regUNC_MAC2_A)); + + val = (ndev->dev_addr[0] << 8) | (ndev->dev_addr[1]); + WRITE_REG(priv, regUNC_MAC2_A, val); + val = (ndev->dev_addr[2] << 8) | (ndev->dev_addr[3]); + WRITE_REG(priv, regUNC_MAC1_A, val); + val = (ndev->dev_addr[4] << 8) | (ndev->dev_addr[5]); + WRITE_REG(priv, regUNC_MAC0_A, val); + + DBG("mac0=%x mac1=%x mac2=%x\n", + READ_REG(priv, regUNC_MAC0_A), + READ_REG(priv, regUNC_MAC1_A), READ_REG(priv, regUNC_MAC2_A)); + RET(); +} + +/* bdx_hw_start - inits registers and starts HW's Rx and Tx engines + * @priv - NIC private structure + */ +static int bdx_hw_start(struct bdx_priv *priv) +{ + int rc = -EIO; + struct net_device *ndev = priv->ndev; + + ENTER; + bdx_link_changed(priv); + + /* 10G overall max length (vlan, eth&ip header, ip payload, crc) */ + WRITE_REG(priv, regFRM_LENGTH, 0X3FE0); + WRITE_REG(priv, regPAUSE_QUANT, 0x96); + WRITE_REG(priv, regRX_FIFO_SECTION, 0x800010); + WRITE_REG(priv, regTX_FIFO_SECTION, 0xE00010); + WRITE_REG(priv, regRX_FULLNESS, 0); + WRITE_REG(priv, regTX_FULLNESS, 0); + WRITE_REG(priv, regCTRLST, + regCTRLST_BASE | regCTRLST_RX_ENA | regCTRLST_TX_ENA); + + WRITE_REG(priv, regVGLB, 0); + WRITE_REG(priv, regMAX_FRAME_A, + priv->rxf_fifo0.m.pktsz & MAX_FRAME_AB_VAL); + + DBG("RDINTCM=%08x\n", priv->rdintcm); /*NOTE: test script uses this */ + WRITE_REG(priv, regRDINTCM0, priv->rdintcm); + WRITE_REG(priv, regRDINTCM2, 0); /*cpu_to_le32(rcm.val)); */ + + DBG("TDINTCM=%08x\n", priv->tdintcm); /*NOTE: test script uses this */ + WRITE_REG(priv, regTDINTCM0, priv->tdintcm); /* old val = 0x300064 */ + + /* Enable timer interrupt once in 2 secs. */ + /*WRITE_REG(priv, regGTMR0, ((GTMR_SEC * 2) & GTMR_DATA)); */ + bdx_restore_mac(priv->ndev, priv); + + WRITE_REG(priv, regGMAC_RXF_A, GMAC_RX_FILTER_OSEN | + GMAC_RX_FILTER_AM | GMAC_RX_FILTER_AB); + +#define BDX_IRQ_TYPE ((priv->nic->irq_type == IRQ_MSI)?0:IRQF_SHARED) + if ((rc = request_irq(priv->pdev->irq, &bdx_isr_napi, BDX_IRQ_TYPE, + ndev->name, ndev))) + goto err_irq; + bdx_enable_interrupts(priv); + + RET(0); + +err_irq: + RET(rc); +} + +static void bdx_hw_stop(struct bdx_priv *priv) +{ + ENTER; + bdx_disable_interrupts(priv); + free_irq(priv->pdev->irq, priv->ndev); + + netif_carrier_off(priv->ndev); + netif_stop_queue(priv->ndev); + + RET(); +} + +static int bdx_hw_reset_direct(void __iomem *regs) +{ + u32 val, i; + ENTER; + + /* reset sequences: read, write 1, read, write 0 */ + val = readl(regs + regCLKPLL); + writel((val | CLKPLL_SFTRST) + 0x8, regs + regCLKPLL); + udelay(50); + val = readl(regs + regCLKPLL); + writel(val & ~CLKPLL_SFTRST, regs + regCLKPLL); + + /* check that the PLLs are locked and reset ended */ + for (i = 0; i < 70; i++, mdelay(10)) + if ((readl(regs + regCLKPLL) & CLKPLL_LKD) == CLKPLL_LKD) { + /* do any PCI-E read transaction */ + readl(regs + regRXD_CFG0_0); + return 0; + } + ERR("tehuti: HW reset failed\n"); + return 1; /* failure */ +} + +static int bdx_hw_reset(struct bdx_priv *priv) +{ + u32 val, i; + ENTER; + + if (priv->port == 0) { + /* reset sequences: read, write 1, read, write 0 */ + val = READ_REG(priv, regCLKPLL); + WRITE_REG(priv, regCLKPLL, (val | CLKPLL_SFTRST) + 0x8); + udelay(50); + val = READ_REG(priv, regCLKPLL); + WRITE_REG(priv, regCLKPLL, val & ~CLKPLL_SFTRST); + } + /* check that the PLLs are locked and reset ended */ + for (i = 0; i < 70; i++, mdelay(10)) + if ((READ_REG(priv, regCLKPLL) & CLKPLL_LKD) == CLKPLL_LKD) { + /* do any PCI-E read transaction */ + READ_REG(priv, regRXD_CFG0_0); + return 0; + } + ERR("tehuti: HW reset failed\n"); + return 1; /* failure */ +} + +static int bdx_sw_reset(struct bdx_priv *priv) +{ + int i; + + ENTER; + /* 1. load MAC (obsolete) */ + /* 2. disable Rx (and Tx) */ + WRITE_REG(priv, regGMAC_RXF_A, 0); + mdelay(100); + /* 3. disable port */ + WRITE_REG(priv, regDIS_PORT, 1); + /* 4. disable queue */ + WRITE_REG(priv, regDIS_QU, 1); + /* 5. wait until hw is disabled */ + for (i = 0; i < 50; i++) { + if (READ_REG(priv, regRST_PORT) & 1) + break; + mdelay(10); + } + if (i == 50) + ERR("%s: SW reset timeout. continuing anyway\n", + priv->ndev->name); + + /* 6. disable intrs */ + WRITE_REG(priv, regRDINTCM0, 0); + WRITE_REG(priv, regTDINTCM0, 0); + WRITE_REG(priv, regIMR, 0); + READ_REG(priv, regISR); + + /* 7. reset queue */ + WRITE_REG(priv, regRST_QU, 1); + /* 8. reset port */ + WRITE_REG(priv, regRST_PORT, 1); + /* 9. zero all read and write pointers */ + for (i = regTXD_WPTR_0; i <= regTXF_RPTR_3; i += 0x10) + DBG("%x = %x\n", i, READ_REG(priv, i) & TXF_WPTR_WR_PTR); + for (i = regTXD_WPTR_0; i <= regTXF_RPTR_3; i += 0x10) + WRITE_REG(priv, i, 0); + /* 10. unseet port disable */ + WRITE_REG(priv, regDIS_PORT, 0); + /* 11. unset queue disable */ + WRITE_REG(priv, regDIS_QU, 0); + /* 12. unset queue reset */ + WRITE_REG(priv, regRST_QU, 0); + /* 13. unset port reset */ + WRITE_REG(priv, regRST_PORT, 0); + /* 14. enable Rx */ + /* skiped. will be done later */ + /* 15. save MAC (obsolete) */ + for (i = regTXD_WPTR_0; i <= regTXF_RPTR_3; i += 0x10) + DBG("%x = %x\n", i, READ_REG(priv, i) & TXF_WPTR_WR_PTR); + + RET(0); +} + +/* bdx_reset - performs right type of reset depending on hw type */ +static int bdx_reset(struct bdx_priv *priv) +{ + ENTER; + RET((priv->pdev->device == 0x3009) + ? bdx_hw_reset(priv) + : bdx_sw_reset(priv)); +} + +/** + * bdx_close - Disables a network interface + * @netdev: network interface device structure + * + * Returns 0, this is not allowed to fail + * + * The close entry point is called when an interface is de-activated + * by the OS. The hardware is still under the drivers control, but + * needs to be disabled. A global MAC reset is issued to stop the + * hardware, and all transmit and receive resources are freed. + **/ +static int bdx_close(struct net_device *ndev) +{ + struct bdx_priv *priv = NULL; + + ENTER; + priv = ndev->priv; + + napi_disable(&priv->napi); + + bdx_reset(priv); + bdx_hw_stop(priv); + bdx_rx_free(priv); + bdx_tx_free(priv); + RET(0); +} + +/** + * bdx_open - Called when a network interface is made active + * @netdev: network interface device structure + * + * Returns 0 on success, negative value on failure + * + * The open entry point is called when a network interface is made + * active by the system (IFF_UP). At this point all resources needed + * for transmit and receive operations are allocated, the interrupt + * handler is registered with the OS, the watchdog timer is started, + * and the stack is notified that the interface is ready. + **/ +static int bdx_open(struct net_device *ndev) +{ + struct bdx_priv *priv; + int rc; + + ENTER; + priv = ndev->priv; + bdx_reset(priv); + if (netif_running(ndev)) + netif_stop_queue(priv->ndev); + + if ((rc = bdx_tx_init(priv))) + goto err; + + if ((rc = bdx_rx_init(priv))) + goto err; + + if ((rc = bdx_fw_load(priv))) + goto err; + + bdx_rx_alloc_skbs(priv, &priv->rxf_fifo0); + + if ((rc = bdx_hw_start(priv))) + goto err; + + napi_enable(&priv->napi); + + print_fw_id(priv->nic); + + RET(0); + +err: + bdx_close(ndev); + RET(rc); +} + +static void __init bdx_firmware_endianess(void) +{ + int i; + for (i = 0; i < sizeof(s_firmLoad) / sizeof(u32); i++) + s_firmLoad[i] = CPU_CHIP_SWAP32(s_firmLoad[i]); +} + +static int bdx_ioctl_priv(struct net_device *ndev, struct ifreq *ifr, int cmd) +{ + struct bdx_priv *priv = ndev->priv; + u32 data[3]; + int error; + + ENTER; + + DBG("jiffies=%ld cmd=%d\n", jiffies, cmd); + if (cmd != SIOCDEVPRIVATE) { + error = copy_from_user(data, ifr->ifr_data, sizeof(data)); + if (error) { + ERR("cant copy from user\n"); + RET(error); + } + DBG("%d 0x%x 0x%x\n", data[0], data[1], data[2]); + } + + switch (data[0]) { + + case BDX_OP_READ: + data[2] = READ_REG(priv, data[1]); + DBG("read_reg(0x%x)=0x%x (dec %d)\n", data[1], data[2], + data[2]); + error = copy_to_user(ifr->ifr_data, data, sizeof(data)); + if (error) + RET(error); + break; + + case BDX_OP_WRITE: + WRITE_REG(priv, data[1], data[2]); + DBG("write_reg(0x%x, 0x%x)\n", data[1], data[2]); + break; + + default: + RET(-EOPNOTSUPP); + } + return 0; +} + +static int bdx_ioctl(struct net_device *ndev, struct ifreq *ifr, int cmd) +{ + ENTER; + if (cmd >= SIOCDEVPRIVATE && cmd <= (SIOCDEVPRIVATE + 15)) + RET(bdx_ioctl_priv(ndev, ifr, cmd)); + else + RET(-EOPNOTSUPP); +} + +/* + * __bdx_vlan_rx_vid - private helper for adding/killing VLAN vid + * by passing VLAN filter table to hardware + * @ndev network device + * @vid VLAN vid + * @op add or kill operation + */ +static void __bdx_vlan_rx_vid(struct net_device *ndev, uint16_t vid, int enable) +{ + struct bdx_priv *priv = ndev->priv; + u32 reg, bit, val; + + ENTER; + DBG2("vid=%d value=%d\n", (int)vid, enable); + if (unlikely(vid >= 4096)) { + ERR("tehuti: invalid VID: %u (> 4096)\n", vid); + RET(); + } + reg = regVLAN_0 + (vid / 32) * 4; + bit = 1 << vid % 32; + val = READ_REG(priv, reg); + DBG2("reg=%x, val=%x, bit=%d\n", reg, val, bit); + if (enable) + val |= bit; + else + val &= ~bit; + DBG2("new val %x\n", val); + WRITE_REG(priv, reg, val); + RET(); +} + +/* + * bdx_vlan_rx_add_vid - kernel hook for adding VLAN vid to hw filtering table + * @ndev network device + * @vid VLAN vid to add + */ +static void bdx_vlan_rx_add_vid(struct net_device *ndev, uint16_t vid) +{ + __bdx_vlan_rx_vid(ndev, vid, 1); +} + +/* + * bdx_vlan_rx_kill_vid - kernel hook for killing VLAN vid in hw filtering table + * @ndev network device + * @vid VLAN vid to kill + */ +static void bdx_vlan_rx_kill_vid(struct net_device *ndev, unsigned short vid) +{ + __bdx_vlan_rx_vid(ndev, vid, 0); +} + +/* + * bdx_vlan_rx_register - kernel hook for adding VLAN group + * @ndev network device + * @grp VLAN group + */ +static void +bdx_vlan_rx_register(struct net_device *ndev, struct vlan_group *grp) +{ + struct bdx_priv *priv = ndev->priv; + + ENTER; + DBG("device='%s', group='%p'\n", ndev->name, grp); + priv->vlgrp = grp; + RET(); +} + +/** + * bdx_change_mtu - Change the Maximum Transfer Unit + * @netdev: network interface device structure + * @new_mtu: new value for maximum frame size + * + * Returns 0 on success, negative on failure + */ +static int bdx_change_mtu(struct net_device *ndev, int new_mtu) +{ + BDX_ASSERT(ndev == 0); + ENTER; + + if (new_mtu == ndev->mtu) + RET(0); + + /* enforce minimum frame size */ + if (new_mtu < ETH_ZLEN) { + ERR("%s: %s mtu %d is less then minimal %d\n", + BDX_DRV_NAME, ndev->name, new_mtu, ETH_ZLEN); + RET(-EINVAL); + } + + ndev->mtu = new_mtu; + if (netif_running(ndev)) { + bdx_close(ndev); + bdx_open(ndev); + } + RET(0); +} + +static void bdx_setmulti(struct net_device *ndev) +{ + struct bdx_priv *priv = ndev->priv; + + u32 rxf_val = + GMAC_RX_FILTER_AM | GMAC_RX_FILTER_AB | GMAC_RX_FILTER_OSEN; + int i; + + ENTER; + /* IMF - imperfect (hash) rx multicat filter */ + /* PMF - perfect rx multicat filter */ + + /* FIXME: RXE(OFF) */ + if (ndev->flags & IFF_PROMISC) { + rxf_val |= GMAC_RX_FILTER_PRM; + } else if (ndev->flags & IFF_ALLMULTI) { + /* set IMF to accept all multicast frmaes */ + for (i = 0; i < MAC_MCST_HASH_NUM; i++) + WRITE_REG(priv, regRX_MCST_HASH0 + i * 4, ~0); + } else if (ndev->mc_count) { + u8 hash; + struct dev_mc_list *mclist; + u32 reg, val; + + /* set IMF to deny all multicast frames */ + for (i = 0; i < MAC_MCST_HASH_NUM; i++) + WRITE_REG(priv, regRX_MCST_HASH0 + i * 4, 0); + /* set PMF to deny all multicast frames */ + for (i = 0; i < MAC_MCST_NUM; i++) { + WRITE_REG(priv, regRX_MAC_MCST0 + i * 8, 0); + WRITE_REG(priv, regRX_MAC_MCST1 + i * 8, 0); + } + + /* use PMF to accept first MAC_MCST_NUM (15) addresses */ + /* TBD: sort addreses and write them in ascending order + * into RX_MAC_MCST regs. we skip this phase now and accept ALL + * multicast frames throu IMF */ + mclist = ndev->mc_list; + + /* accept the rest of addresses throu IMF */ + for (; mclist; mclist = mclist->next) { + hash = 0; + for (i = 0; i < ETH_ALEN; i++) + hash ^= mclist->dmi_addr[i]; + reg = regRX_MCST_HASH0 + ((hash >> 5) << 2); + val = READ_REG(priv, reg); + val |= (1 << (hash % 32)); + WRITE_REG(priv, reg, val); + } + + } else { + DBG("only own mac %d\n", ndev->mc_count); + rxf_val |= GMAC_RX_FILTER_AB; + } + WRITE_REG(priv, regGMAC_RXF_A, rxf_val); + /* enable RX */ + /* FIXME: RXE(ON) */ + RET(); +} + +static int bdx_set_mac(struct net_device *ndev, void *p) +{ + struct bdx_priv *priv = ndev->priv; + struct sockaddr *addr = p; + + ENTER; + /* + if (netif_running(dev)) + return -EBUSY + */ + memcpy(ndev->dev_addr, addr->sa_data, ndev->addr_len); + bdx_restore_mac(ndev, priv); + RET(0); +} + +static int bdx_read_mac(struct bdx_priv *priv) +{ + u16 macAddress[3], i; + ENTER; + + macAddress[2] = READ_REG(priv, regUNC_MAC0_A); + macAddress[2] = READ_REG(priv, regUNC_MAC0_A); + macAddress[1] = READ_REG(priv, regUNC_MAC1_A); + macAddress[1] = READ_REG(priv, regUNC_MAC1_A); + macAddress[0] = READ_REG(priv, regUNC_MAC2_A); + macAddress[0] = READ_REG(priv, regUNC_MAC2_A); + for (i = 0; i < 3; i++) { + priv->ndev->dev_addr[i * 2 + 1] = macAddress[i]; + priv->ndev->dev_addr[i * 2] = macAddress[i] >> 8; + } + RET(0); +} + +static u64 bdx_read_l2stat(struct bdx_priv *priv, int reg) +{ + u64 val; + + val = READ_REG(priv, reg); + val |= ((u64) READ_REG(priv, reg + 8)) << 32; + return val; +} + +/*Do the statistics-update work*/ +static void bdx_update_stats(struct bdx_priv *priv) +{ + struct bdx_stats *stats = &priv->hw_stats; + u64 *stats_vector = (u64 *) stats; + int i; + int addr; + + /*Fill HW structure */ + addr = 0x7200; + /*First 12 statistics - 0x7200 - 0x72B0 */ + for (i = 0; i < 12; i++) { + stats_vector[i] = bdx_read_l2stat(priv, addr); + addr += 0x10; + } + BDX_ASSERT(addr != 0x72C0); + /* 0x72C0-0x72E0 RSRV */ + addr = 0x72F0; + for (; i < 16; i++) { + stats_vector[i] = bdx_read_l2stat(priv, addr); + addr += 0x10; + } + BDX_ASSERT(addr != 0x7330); + /* 0x7330-0x7360 RSRV */ + addr = 0x7370; + for (; i < 19; i++) { + stats_vector[i] = bdx_read_l2stat(priv, addr); + addr += 0x10; + } + BDX_ASSERT(addr != 0x73A0); + /* 0x73A0-0x73B0 RSRV */ + addr = 0x73C0; + for (; i < 23; i++) { + stats_vector[i] = bdx_read_l2stat(priv, addr); + addr += 0x10; + } + BDX_ASSERT(addr != 0x7400); + BDX_ASSERT((sizeof(struct bdx_stats) / sizeof(u64)) != i); +} + +static struct net_device_stats *bdx_get_stats(struct net_device *ndev) +{ + struct bdx_priv *priv = ndev->priv; + struct net_device_stats *net_stat = &priv->net_stats; + return net_stat; +} + +static void print_rxdd(struct rxd_desc *rxdd, u32 rxd_val1, u16 len, + u16 rxd_vlan); +static void print_rxfd(struct rxf_desc *rxfd); + +/************************************************************************* + * Rx DB * + *************************************************************************/ + +static void bdx_rxdb_destroy(struct rxdb *db) +{ + if (db) + vfree(db); +} + +static struct rxdb *bdx_rxdb_create(int nelem) +{ + struct rxdb *db; + int i; + + db = vmalloc(sizeof(struct rxdb) + + (nelem * sizeof(int)) + + (nelem * sizeof(struct rx_map))); + if (likely(db != NULL)) { + db->stack = (int *)(db + 1); + db->elems = (void *)(db->stack + nelem); + db->nelem = nelem; + db->top = nelem; + for (i = 0; i < nelem; i++) + db->stack[i] = nelem - i - 1; /* to make first allocs + close to db struct*/ + } + + return db; +} + +static inline int bdx_rxdb_alloc_elem(struct rxdb *db) +{ + BDX_ASSERT(db->top <= 0); + return db->stack[--(db->top)]; +} + +static inline void *bdx_rxdb_addr_elem(struct rxdb *db, int n) +{ + BDX_ASSERT((n < 0) || (n >= db->nelem)); + return db->elems + n; +} + +static inline int bdx_rxdb_available(struct rxdb *db) +{ + return db->top; +} + +static inline void bdx_rxdb_free_elem(struct rxdb *db, int n) +{ + BDX_ASSERT((n >= db->nelem) || (n < 0)); + db->stack[(db->top)++] = n; +} + +/************************************************************************* + * Rx Init * + *************************************************************************/ + +/* bdx_rx_init - initialize RX all related HW and SW resources + * @priv - NIC private structure + * + * Returns 0 on success, negative value on failure + * + * It creates rxf and rxd fifos, update relevant HW registers, preallocate + * skb for rx. It assumes that Rx is desabled in HW + * funcs are grouped for better cache usage + * + * RxD fifo is smaller then RxF fifo by design. Upon high load, RxD will be + * filled and packets will be dropped by nic without getting into host or + * cousing interrupt. Anyway, in that condition, host has no chance to proccess + * all packets, but dropping in nic is cheaper, since it takes 0 cpu cycles + */ + +/* TBD: ensure proper packet size */ + +static int bdx_rx_init(struct bdx_priv *priv) +{ + ENTER; + BDX_ASSERT(priv == 0); + if (bdx_fifo_init(priv, &priv->rxd_fifo0.m, priv->rxd_size, + regRXD_CFG0_0, regRXD_CFG1_0, + regRXD_RPTR_0, regRXD_WPTR_0)) + goto err_mem; + if (bdx_fifo_init(priv, &priv->rxf_fifo0.m, priv->rxf_size, + regRXF_CFG0_0, regRXF_CFG1_0, + regRXF_RPTR_0, regRXF_WPTR_0)) + goto err_mem; + if (! + (priv->rxdb = + bdx_rxdb_create(priv->rxf_fifo0.m.memsz / + sizeof(struct rxf_desc)))) + goto err_mem; + + priv->rxf_fifo0.m.pktsz = priv->ndev->mtu + VLAN_ETH_HLEN; + return 0; + +err_mem: + ERR("%s: %s: Rx init failed\n", BDX_DRV_NAME, priv->ndev->name); + return -ENOMEM; +} + +/* bdx_rx_free_skbs - frees and unmaps all skbs allocated for the fifo + * @priv - NIC private structure + * @f - RXF fifo + */ +static void bdx_rx_free_skbs(struct bdx_priv *priv, struct rxf_fifo *f) +{ + struct rx_map *dm; + struct rxdb *db = priv->rxdb; + u16 i; + + ENTER; + DBG("total=%d free=%d busy=%d\n", db->nelem, bdx_rxdb_available(db), + db->nelem - bdx_rxdb_available(db)); + while (bdx_rxdb_available(db) > 0) { + i = bdx_rxdb_alloc_elem(db); + dm = bdx_rxdb_addr_elem(db, i); + dm->dma = 0; + } + for (i = 0; i < db->nelem; i++) { + dm = bdx_rxdb_addr_elem(db, i); + if (dm->dma) { + pci_unmap_single(priv->pdev, + dm->dma, f->m.pktsz, + PCI_DMA_FROMDEVICE); + dev_kfree_skb(dm->skb); + } + } +} + +/* bdx_rx_free - release all Rx resources + * @priv - NIC private structure + * It assumes that Rx is desabled in HW + */ +static void bdx_rx_free(struct bdx_priv *priv) +{ + ENTER; + if (priv->rxdb) { + bdx_rx_free_skbs(priv, &priv->rxf_fifo0); + bdx_rxdb_destroy(priv->rxdb); + priv->rxdb = NULL; + } + bdx_fifo_free(priv, &priv->rxf_fifo0.m); + bdx_fifo_free(priv, &priv->rxd_fifo0.m); + + RET(); +} + +/************************************************************************* + * Rx Engine * + *************************************************************************/ + +/* bdx_rx_alloc_skbs - fill rxf fifo with new skbs + * @priv - nic's private structure + * @f - RXF fifo that needs skbs + * It allocates skbs, build rxf descs and push it (rxf descr) into rxf fifo. + * skb's virtual and physical addresses are stored in skb db. + * To calculate free space, func uses cached values of RPTR and WPTR + * When needed, it also updates RPTR and WPTR. + */ + +/* TBD: do not update WPTR if no desc were written */ + +static void bdx_rx_alloc_skbs(struct bdx_priv *priv, struct rxf_fifo *f) +{ + struct sk_buff *skb; + struct rxf_desc *rxfd; + struct rx_map *dm; + int dno, delta, idx; + struct rxdb *db = priv->rxdb; + + ENTER; + dno = bdx_rxdb_available(db) - 1; + while (dno > 0) { + if (!(skb = dev_alloc_skb(f->m.pktsz + NET_IP_ALIGN))) { + ERR("NO MEM: dev_alloc_skb failed\n"); + break; + } + skb->dev = priv->ndev; + skb_reserve(skb, NET_IP_ALIGN); + + idx = bdx_rxdb_alloc_elem(db); + dm = bdx_rxdb_addr_elem(db, idx); + dm->dma = pci_map_single(priv->pdev, + skb->data, f->m.pktsz, + PCI_DMA_FROMDEVICE); + dm->skb = skb; + rxfd = (struct rxf_desc *)(f->m.va + f->m.wptr); + rxfd->info = CPU_CHIP_SWAP32(0x10003); /* INFO=1 BC=3 */ + rxfd->va_lo = idx; + rxfd->pa_lo = CPU_CHIP_SWAP32(L32_64(dm->dma)); + rxfd->pa_hi = CPU_CHIP_SWAP32(H32_64(dm->dma)); + rxfd->len = CPU_CHIP_SWAP32(f->m.pktsz); + print_rxfd(rxfd); + + f->m.wptr += sizeof(struct rxf_desc); + delta = f->m.wptr - f->m.memsz; + if (unlikely(delta >= 0)) { + f->m.wptr = delta; + if (delta > 0) { + memcpy(f->m.va, f->m.va + f->m.memsz, delta); + DBG("wrapped descriptor\n"); + } + } + dno--; + } + /*TBD: to do - delayed rxf wptr like in txd */ + WRITE_REG(priv, f->m.reg_WPTR, f->m.wptr & TXF_WPTR_WR_PTR); + RET(); +} + +static inline void +NETIF_RX_MUX(struct bdx_priv *priv, u32 rxd_val1, u16 rxd_vlan, + struct sk_buff *skb) +{ + ENTER; + DBG("rxdd->flags.bits.vtag=%d vlgrp=%p\n", GET_RXD_VTAG(rxd_val1), + priv->vlgrp); + if (priv->vlgrp && GET_RXD_VTAG(rxd_val1)) { + DBG("%s: vlan rcv vlan '%x' vtag '%x', device name '%s'\n", + priv->ndev->name, + GET_RXD_VLAN_ID(rxd_vlan), + GET_RXD_VTAG(rxd_val1), + vlan_group_get_device(priv->vlgrp, + GET_RXD_VLAN_ID(rxd_vlan))->name); + /* NAPI variant of receive functions */ + vlan_hwaccel_receive_skb(skb, priv->vlgrp, + GET_RXD_VLAN_ID(rxd_vlan)); + } else { + netif_receive_skb(skb); + } +} + +static void bdx_recycle_skb(struct bdx_priv *priv, struct rxd_desc *rxdd) +{ + struct rxf_desc *rxfd; + struct rx_map *dm; + struct rxf_fifo *f; + struct rxdb *db; + struct sk_buff *skb; + int delta; + + ENTER; + DBG("priv=%p rxdd=%p\n", priv, rxdd); + f = &priv->rxf_fifo0; + db = priv->rxdb; + DBG("db=%p f=%p\n", db, f); + dm = bdx_rxdb_addr_elem(db, rxdd->va_lo); + DBG("dm=%p\n", dm); + skb = dm->skb; + rxfd = (struct rxf_desc *)(f->m.va + f->m.wptr); + rxfd->info = CPU_CHIP_SWAP32(0x10003); /* INFO=1 BC=3 */ + rxfd->va_lo = rxdd->va_lo; + rxfd->pa_lo = CPU_CHIP_SWAP32(L32_64(dm->dma)); + rxfd->pa_hi = CPU_CHIP_SWAP32(H32_64(dm->dma)); + rxfd->len = CPU_CHIP_SWAP32(f->m.pktsz); + print_rxfd(rxfd); + + f->m.wptr += sizeof(struct rxf_desc); + delta = f->m.wptr - f->m.memsz; + if (unlikely(delta >= 0)) { + f->m.wptr = delta; + if (delta > 0) { + memcpy(f->m.va, f->m.va + f->m.memsz, delta); + DBG("wrapped descriptor\n"); + } + } + RET(); +} + +/* bdx_rx_receive - recieves full packets from RXD fifo and pass them to OS + * NOTE: a special treatment is given to non-continous descriptors + * that start near the end, wraps around and continue at the beginning. a second + * part is copied right after the first, and then descriptor is interpreted as + * normal. fifo has an extra space to allow such operations + * @priv - nic's private structure + * @f - RXF fifo that needs skbs + */ + +/* TBD: replace memcpy func call by explicite inline asm */ + +static int bdx_rx_receive(struct bdx_priv *priv, struct rxd_fifo *f, int budget) +{ + struct sk_buff *skb, *skb2; + struct rxd_desc *rxdd; + struct rx_map *dm; + struct rxf_fifo *rxf_fifo; + int tmp_len, size; + int done = 0; + int max_done = BDX_MAX_RX_DONE; + struct rxdb *db = NULL; + /* Unmarshalled descriptor - copy of descriptor in host order */ + u32 rxd_val1; + u16 len; + u16 rxd_vlan; + + ENTER; + max_done = budget; + + priv->ndev->last_rx = jiffies; + f->m.wptr = READ_REG(priv, f->m.reg_WPTR) & TXF_WPTR_WR_PTR; + + size = f->m.wptr - f->m.rptr; + if (size < 0) + size = f->m.memsz + size; /* size is negative :-) */ + + while (size > 0) { + + rxdd = (struct rxd_desc *)(f->m.va + f->m.rptr); + rxd_val1 = CPU_CHIP_SWAP32(rxdd->rxd_val1); + + len = CPU_CHIP_SWAP16(rxdd->len); + + rxd_vlan = CPU_CHIP_SWAP16(rxdd->rxd_vlan); + + print_rxdd(rxdd, rxd_val1, len, rxd_vlan); + + tmp_len = GET_RXD_BC(rxd_val1) << 3; + BDX_ASSERT(tmp_len <= 0); + size -= tmp_len; + if (size < 0) /* test for partially arrived descriptor */ + break; + + f->m.rptr += tmp_len; + + tmp_len = f->m.rptr - f->m.memsz; + if (unlikely(tmp_len >= 0)) { + f->m.rptr = tmp_len; + if (tmp_len > 0) { + DBG("wrapped desc rptr=%d tmp_len=%d\n", + f->m.rptr, tmp_len); + memcpy(f->m.va + f->m.memsz, f->m.va, tmp_len); + } + } + + if (unlikely(GET_RXD_ERR(rxd_val1))) { + DBG("rxd_err = 0x%x\n", GET_RXD_ERR(rxd_val1)); + priv->net_stats.rx_errors++; + bdx_recycle_skb(priv, rxdd); + continue; + } + + rxf_fifo = &priv->rxf_fifo0; + db = priv->rxdb; + dm = bdx_rxdb_addr_elem(db, rxdd->va_lo); + skb = dm->skb; + + if (len < BDX_COPYBREAK && + (skb2 = dev_alloc_skb(len + NET_IP_ALIGN))) { + skb_reserve(skb2, NET_IP_ALIGN); + /*skb_put(skb2, len); */ + pci_dma_sync_single_for_cpu(priv->pdev, + dm->dma, rxf_fifo->m.pktsz, + PCI_DMA_FROMDEVICE); + memcpy(skb2->data, skb->data, len); + bdx_recycle_skb(priv, rxdd); + skb = skb2; + } else { + pci_unmap_single(priv->pdev, + dm->dma, rxf_fifo->m.pktsz, + PCI_DMA_FROMDEVICE); + bdx_rxdb_free_elem(db, rxdd->va_lo); + } + + priv->net_stats.rx_bytes += len; + + skb_put(skb, len); + skb->dev = priv->ndev; + skb->ip_summed = CHECKSUM_UNNECESSARY; + skb->protocol = eth_type_trans(skb, priv->ndev); + + /* Non-IP packets aren't checksum-offloaded */ + if (GET_RXD_PKT_ID(rxd_val1) == 0) + skb->ip_summed = CHECKSUM_NONE; + + NETIF_RX_MUX(priv, rxd_val1, rxd_vlan, skb); + + if (++done >= max_done) + break; + } + + priv->net_stats.rx_packets += done; + + /* FIXME: do smth to minimize pci accesses */ + WRITE_REG(priv, f->m.reg_RPTR, f->m.rptr & TXF_WPTR_WR_PTR); + + bdx_rx_alloc_skbs(priv, &priv->rxf_fifo0); + + RET(done); +} + +/************************************************************************* + * Debug / Temprorary Code * + *************************************************************************/ +static void print_rxdd(struct rxd_desc *rxdd, u32 rxd_val1, u16 len, + u16 rxd_vlan) +{ + DBG("ERROR: rxdd bc %d rxfq %d to %d type %d err %d rxp %d " + "pkt_id %d vtag %d len %d vlan_id %d cfi %d prio %d " + "va_lo %d va_hi %d\n", + GET_RXD_BC(rxd_val1), GET_RXD_RXFQ(rxd_val1), GET_RXD_TO(rxd_val1), + GET_RXD_TYPE(rxd_val1), GET_RXD_ERR(rxd_val1), + GET_RXD_RXP(rxd_val1), GET_RXD_PKT_ID(rxd_val1), + GET_RXD_VTAG(rxd_val1), len, GET_RXD_VLAN_ID(rxd_vlan), + GET_RXD_CFI(rxd_vlan), GET_RXD_PRIO(rxd_vlan), rxdd->va_lo, + rxdd->va_hi); +} + +static void print_rxfd(struct rxf_desc *rxfd) +{ + DBG("=== RxF desc CHIP ORDER/ENDIANESS =============\n" + "info 0x%x va_lo %u pa_lo 0x%x pa_hi 0x%x len 0x%x\n", + rxfd->info, rxfd->va_lo, rxfd->pa_lo, rxfd->pa_hi, rxfd->len); +} + +/* + * TX HW/SW interaction overview + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * There are 2 types of TX communication channels betwean driver and NIC. + * 1) TX Free Fifo - TXF - holds ack descriptors for sent packets + * 2) TX Data Fifo - TXD - holds descriptors of full buffers. + * + * Currently NIC supports TSO, checksuming and gather DMA + * UFO and IP fragmentation is on the way + * + * RX SW Data Structures + * ~~~~~~~~~~~~~~~~~~~~~ + * txdb - used to keep track of all skbs owned by SW and their dma addresses. + * For TX case, ownership lasts from geting packet via hard_xmit and until HW + * acknowledges sent by TXF descriptors. + * Implemented as cyclic buffer. + * fifo - keeps info about fifo's size and location, relevant HW registers, + * usage and skb db. Each RXD and RXF Fifo has its own fifo structure. + * Implemented as simple struct. + * + * TX SW Execution Flow + * ~~~~~~~~~~~~~~~~~~~~ + * OS calls driver's hard_xmit method with packet to sent. + * Driver creates DMA mappings, builds TXD descriptors and kicks HW + * by updating TXD WPTR. + * When packet is sent, HW write us TXF descriptor and SW frees original skb. + * To prevent TXD fifo overflow without reading HW registers every time, + * SW deploys "tx level" technique. + * Upon strart up, tx level is initialized to TXD fifo length. + * For every sent packet, SW gets its TXD descriptor sizei + * (from precalculated array) and substructs it from tx level. + * The size is also stored in txdb. When TXF ack arrives, SW fetch size of + * original TXD descriptor from txdb and adds it to tx level. + * When Tx level drops under some predefined treshhold, the driver + * stops the TX queue. When TX level rises above that level, + * the tx queue is enabled again. + * + * This technique avoids eccessive reading of RPTR and WPTR registers. + * As our benchmarks shows, it adds 1.5 Gbit/sec to NIS's throuput. + */ + +/************************************************************************* + * Tx DB * + *************************************************************************/ +static inline int bdx_tx_db_size(struct txdb *db) +{ + int taken = db->wptr - db->rptr; + if (taken < 0) + taken = db->size + 1 + taken; /* (size + 1) equals memsz */ + + return db->size - taken; +} + +/* __bdx_tx_ptr_next - helper function, increment read/write pointer + wrap + * @d - tx data base + * @ptr - read or write pointer + */ +static inline void __bdx_tx_db_ptr_next(struct txdb *db, struct tx_map **pptr) +{ + BDX_ASSERT(db == NULL || pptr == NULL); /* sanity */ + + BDX_ASSERT(*pptr != db->rptr && /* expect either read */ + *pptr != db->wptr); /* or write pointer */ + + BDX_ASSERT(*pptr < db->start || /* pointer has to be */ + *pptr >= db->end); /* in range */ + + ++*pptr; + if (unlikely(*pptr == db->end)) + *pptr = db->start; +} + +/* bdx_tx_db_inc_rptr - increment read pointer + * @d - tx data base + */ +static inline void bdx_tx_db_inc_rptr(struct txdb *db) +{ + BDX_ASSERT(db->rptr == db->wptr); /* can't read from empty db */ + __bdx_tx_db_ptr_next(db, &db->rptr); +} + +/* bdx_tx_db_inc_rptr - increment write pointer + * @d - tx data base + */ +static inline void bdx_tx_db_inc_wptr(struct txdb *db) +{ + __bdx_tx_db_ptr_next(db, &db->wptr); + BDX_ASSERT(db->rptr == db->wptr); /* we can not get empty db as + a result of write */ +} + +/* bdx_tx_db_init - creates and initializes tx db + * @d - tx data base + * @sz_type - size of tx fifo + * Returns 0 on success, error code otherwise + */ +static int bdx_tx_db_init(struct txdb *d, int sz_type) +{ + int memsz = FIFO_SIZE * (1 << (sz_type + 1)); + + d->start = vmalloc(memsz); + if (!d->start) + return -ENOMEM; + + /* + * In order to differentiate between db is empty and db is full + * states at least one element should always be empty in order to + * avoid rptr == wptr which means db is empty + */ + d->size = memsz / sizeof(struct tx_map) - 1; + d->end = d->start + d->size + 1; /* just after last element */ + + /* all dbs are created equally empty */ + d->rptr = d->start; + d->wptr = d->start; + + return 0; +} + +/* bdx_tx_db_close - closes tx db and frees all memory + * @d - tx data base + */ +static void bdx_tx_db_close(struct txdb *d) +{ + BDX_ASSERT(d == NULL); + + if (d->start) { + vfree(d->start); + d->start = NULL; + } +} + +/************************************************************************* + * Tx Engine * + *************************************************************************/ + +/* sizes of tx desc (including padding if needed) as function + * of skb's frag number */ +static struct { + u16 bytes; + u16 qwords; /* qword = 64 bit */ +} txd_sizes[MAX_SKB_FRAGS + 1]; + +/* txdb_map_skb - creates and stores dma mappings for skb's data blocks + * @priv - NIC private structure + * @skb - socket buffer to map + * + * It makes dma mappings for skb's data blocks and writes them to PBL of + * new tx descriptor. It also stores them in the tx db, so they could be + * unmaped after data was sent. It is reponsibility of a caller to make + * sure that there is enough space in the tx db. Last element holds pointer + * to skb itself and marked with zero length + */ +static inline void +bdx_tx_map_skb(struct bdx_priv *priv, struct sk_buff *skb, + struct txd_desc *txdd) +{ + struct txdb *db = &priv->txdb; + struct pbl *pbl = &txdd->pbl[0]; + int nr_frags = skb_shinfo(skb)->nr_frags; + int i; + + db->wptr->len = skb->len - skb->data_len; + db->wptr->addr.dma = pci_map_single(priv->pdev, skb->data, + db->wptr->len, PCI_DMA_TODEVICE); + pbl->len = CPU_CHIP_SWAP32(db->wptr->len); + pbl->pa_lo = CPU_CHIP_SWAP32(L32_64(db->wptr->addr.dma)); + pbl->pa_hi = CPU_CHIP_SWAP32(H32_64(db->wptr->addr.dma)); + DBG("=== pbl len: 0x%x ================\n", pbl->len); + DBG("=== pbl pa_lo: 0x%x ================\n", pbl->pa_lo); + DBG("=== pbl pa_hi: 0x%x ================\n", pbl->pa_hi); + bdx_tx_db_inc_wptr(db); + + for (i = 0; i < nr_frags; i++) { + struct skb_frag_struct *frag; + + frag = &skb_shinfo(skb)->frags[i]; + db->wptr->len = frag->size; + db->wptr->addr.dma = + pci_map_page(priv->pdev, frag->page, frag->page_offset, + frag->size, PCI_DMA_TODEVICE); + + pbl++; + pbl->len = CPU_CHIP_SWAP32(db->wptr->len); + pbl->pa_lo = CPU_CHIP_SWAP32(L32_64(db->wptr->addr.dma)); + pbl->pa_hi = CPU_CHIP_SWAP32(H32_64(db->wptr->addr.dma)); + bdx_tx_db_inc_wptr(db); + } + + /* add skb clean up info. */ + db->wptr->len = -txd_sizes[nr_frags].bytes; + db->wptr->addr.skb = skb; + bdx_tx_db_inc_wptr(db); +} + +/* init_txd_sizes - precalculate sizes of descriptors for skbs up to 16 frags + * number of frags is used as index to fetch correct descriptors size, + * instead of calculating it each time */ +static void __init init_txd_sizes(void) +{ + int i, lwords; + + /* 7 - is number of lwords in txd with one phys buffer + * 3 - is number of lwords used for every additional phys buffer */ + for (i = 0; i < MAX_SKB_FRAGS + 1; i++) { + lwords = 7 + (i * 3); + if (lwords & 1) + lwords++; /* pad it with 1 lword */ + txd_sizes[i].qwords = lwords >> 1; + txd_sizes[i].bytes = lwords << 2; + } +} + +/* bdx_tx_init - initialize all Tx related stuff. + * Namely, TXD and TXF fifos, database etc */ +static int bdx_tx_init(struct bdx_priv *priv) +{ + if (bdx_fifo_init(priv, &priv->txd_fifo0.m, priv->txd_size, + regTXD_CFG0_0, + regTXD_CFG1_0, regTXD_RPTR_0, regTXD_WPTR_0)) + goto err_mem; + if (bdx_fifo_init(priv, &priv->txf_fifo0.m, priv->txf_size, + regTXF_CFG0_0, + regTXF_CFG1_0, regTXF_RPTR_0, regTXF_WPTR_0)) + goto err_mem; + + /* The TX db has to keep mappings for all packets sent (on TxD) + * and not yet reclaimed (on TxF) */ + if (bdx_tx_db_init(&priv->txdb, max(priv->txd_size, priv->txf_size))) + goto err_mem; + + priv->tx_level = BDX_MAX_TX_LEVEL; +#ifdef BDX_DELAY_WPTR + priv->tx_update_mark = priv->tx_level - 1024; +#endif + return 0; + +err_mem: + ERR("tehuti: %s: Tx init failed\n", priv->ndev->name); + return -ENOMEM; +} + +/* + * bdx_tx_space - calculates avalable space in TX fifo + * @priv - NIC private structure + * Returns avaliable space in TX fifo in bytes + */ +static inline int bdx_tx_space(struct bdx_priv *priv) +{ + struct txd_fifo *f = &priv->txd_fifo0; + int fsize; + + f->m.rptr = READ_REG(priv, f->m.reg_RPTR) & TXF_WPTR_WR_PTR; + fsize = f->m.rptr - f->m.wptr; + if (fsize <= 0) + fsize = f->m.memsz + fsize; + return (fsize); +} + +/* bdx_tx_transmit - send packet to NIC + * @skb - packet to send + * ndev - network device assigned to NIC + * Return codes: + * o NETDEV_TX_OK everything ok. + * o NETDEV_TX_BUSY Cannot transmit packet, try later + * Usually a bug, means queue start/stop flow control is broken in + * the driver. Note: the driver must NOT put the skb in its DMA ring. + * o NETDEV_TX_LOCKED Locking failed, please retry quickly. + */ +static int bdx_tx_transmit(struct sk_buff *skb, struct net_device *ndev) +{ + struct bdx_priv *priv = ndev->priv; + struct txd_fifo *f = &priv->txd_fifo0; + int txd_checksum = 7; /* full checksum */ + int txd_lgsnd = 0; + int txd_vlan_id = 0; + int txd_vtag = 0; + int txd_mss = 0; + + int nr_frags = skb_shinfo(skb)->nr_frags; + struct txd_desc *txdd; + int len; + unsigned long flags; + + ENTER; + local_irq_save(flags); + if (!spin_trylock(&priv->tx_lock)) { + local_irq_restore(flags); + DBG("%s[%s]: TX locked, returning NETDEV_TX_LOCKED\n", + BDX_DRV_NAME, ndev->name); + return NETDEV_TX_LOCKED; + } + + /* build tx descriptor */ + BDX_ASSERT(f->m.wptr >= f->m.memsz); /* started with valid wptr */ + txdd = (struct txd_desc *)(f->m.va + f->m.wptr); + if (unlikely(skb->ip_summed != CHECKSUM_PARTIAL)) + txd_checksum = 0; + + if (skb_shinfo(skb)->gso_size) { + txd_mss = skb_shinfo(skb)->gso_size; + txd_lgsnd = 1; + DBG("skb %p skb len %d gso size = %d\n", skb, skb->len, + txd_mss); + } + + if (vlan_tx_tag_present(skb)) { + /*Cut VLAN ID to 12 bits */ + txd_vlan_id = vlan_tx_tag_get(skb) & BITS_MASK(12); + txd_vtag = 1; + } + + txdd->length = CPU_CHIP_SWAP16(skb->len); + txdd->mss = CPU_CHIP_SWAP16(txd_mss); + txdd->txd_val1 = + CPU_CHIP_SWAP32(TXD_W1_VAL + (txd_sizes[nr_frags].qwords, txd_checksum, txd_vtag, + txd_lgsnd, txd_vlan_id)); + DBG("=== TxD desc =====================\n"); + DBG("=== w1: 0x%x ================\n", txdd->txd_val1); + DBG("=== w2: mss 0x%x len 0x%x\n", txdd->mss, txdd->length); + + bdx_tx_map_skb(priv, skb, txdd); + + /* increment TXD write pointer. In case of + fifo wrapping copy reminder of the descriptor + to the beginning */ + f->m.wptr += txd_sizes[nr_frags].bytes; + len = f->m.wptr - f->m.memsz; + if (unlikely(len >= 0)) { + f->m.wptr = len; + if (len > 0) { + BDX_ASSERT(len > f->m.memsz); + memcpy(f->m.va, f->m.va + f->m.memsz, len); + } + } + BDX_ASSERT(f->m.wptr >= f->m.memsz); /* finished with valid wptr */ + + priv->tx_level -= txd_sizes[nr_frags].bytes; + BDX_ASSERT(priv->tx_level <= 0 || priv->tx_level > BDX_MAX_TX_LEVEL); +#ifdef BDX_DELAY_WPTR + if (priv->tx_level > priv->tx_update_mark) { + /* Force memory writes to complete before letting h/w + know there are new descriptors to fetch. + (might be needed on platforms like IA64) + wmb(); */ + WRITE_REG(priv, f->m.reg_WPTR, f->m.wptr & TXF_WPTR_WR_PTR); + } else { + if (priv->tx_noupd++ > BDX_NO_UPD_PACKETS) { + priv->tx_noupd = 0; + WRITE_REG(priv, f->m.reg_WPTR, + f->m.wptr & TXF_WPTR_WR_PTR); + } + } +#else + /* Force memory writes to complete before letting h/w + know there are new descriptors to fetch. + (might be needed on platforms like IA64) + wmb(); */ + WRITE_REG(priv, f->m.reg_WPTR, f->m.wptr & TXF_WPTR_WR_PTR); + +#endif + ndev->trans_start = jiffies; + + priv->net_stats.tx_packets++; + priv->net_stats.tx_bytes += skb->len; + + if (priv->tx_level < BDX_MIN_TX_LEVEL) { + DBG("%s: %s: TX Q STOP level %d\n", + BDX_DRV_NAME, ndev->name, priv->tx_level); + netif_stop_queue(ndev); + } + + spin_unlock_irqrestore(&priv->tx_lock, flags); + return NETDEV_TX_OK; +} + +/* bdx_tx_cleanup - clean TXF fifo, run in the context of IRQ. + * @priv - bdx adapter + * It scans TXF fifo for descriptors, frees DMA mappings and reports to OS + * that those packets were sent + */ +static void bdx_tx_cleanup(struct bdx_priv *priv) +{ + struct txf_fifo *f = &priv->txf_fifo0; + struct txdb *db = &priv->txdb; + int tx_level = 0; + + ENTER; + f->m.wptr = READ_REG(priv, f->m.reg_WPTR) & TXF_WPTR_MASK; + BDX_ASSERT(f->m.rptr >= f->m.memsz); /* started with valid rptr */ + + while (f->m.wptr != f->m.rptr) { + f->m.rptr += BDX_TXF_DESC_SZ; + f->m.rptr &= f->m.size_mask; + + /* unmap all the fragments */ + /* first has to come tx_maps containing dma */ + BDX_ASSERT(db->rptr->len == 0); + do { + BDX_ASSERT(db->rptr->addr.dma == 0); + pci_unmap_page(priv->pdev, db->rptr->addr.dma, + db->rptr->len, PCI_DMA_TODEVICE); + bdx_tx_db_inc_rptr(db); + } while (db->rptr->len > 0); + tx_level -= db->rptr->len; /* '-' koz len is negative */ + + /* now should come skb pointer - free it */ + BDX_ASSERT(db->rptr->addr.skb == 0); + dev_kfree_skb_irq(db->rptr->addr.skb); + bdx_tx_db_inc_rptr(db); + } + + /* let h/w know which TXF descriptors were cleaned */ + BDX_ASSERT((f->m.wptr & TXF_WPTR_WR_PTR) >= f->m.memsz); + WRITE_REG(priv, f->m.reg_RPTR, f->m.rptr & TXF_WPTR_WR_PTR); + + /* We reclaimed resources, so in case the Q is stopped by xmit callback, + * we resume the transmition and use tx_lock to synchronize with xmit.*/ + spin_lock(&priv->tx_lock); + priv->tx_level += tx_level; + BDX_ASSERT(priv->tx_level <= 0 || priv->tx_level > BDX_MAX_TX_LEVEL); +#ifdef BDX_DELAY_WPTR + if (priv->tx_noupd) { + priv->tx_noupd = 0; + WRITE_REG(priv, priv->txd_fifo0.m.reg_WPTR, + priv->txd_fifo0.m.wptr & TXF_WPTR_WR_PTR); + } +#endif + + if (unlikely(netif_queue_stopped(priv->ndev) + && netif_carrier_ok(priv->ndev) + && (priv->tx_level >= BDX_MIN_TX_LEVEL))) { + DBG("%s: %s: TX Q WAKE level %d\n", + BDX_DRV_NAME, priv->ndev->name, priv->tx_level); + netif_wake_queue(priv->ndev); + } + spin_unlock(&priv->tx_lock); +} + +/* bdx_tx_free_skbs - frees all skbs from TXD fifo. + * It gets called when OS stops this dev, eg upon "ifconfig down" or rmmod + */ +static void bdx_tx_free_skbs(struct bdx_priv *priv) +{ + struct txdb *db = &priv->txdb; + + ENTER; + while (db->rptr != db->wptr) { + if (likely(db->rptr->len)) + pci_unmap_page(priv->pdev, db->rptr->addr.dma, + db->rptr->len, PCI_DMA_TODEVICE); + else + dev_kfree_skb(db->rptr->addr.skb); + bdx_tx_db_inc_rptr(db); + } + RET(); +} + +/* bdx_tx_free - frees all Tx resources */ +static void bdx_tx_free(struct bdx_priv *priv) +{ + ENTER; + bdx_tx_free_skbs(priv); + bdx_fifo_free(priv, &priv->txd_fifo0.m); + bdx_fifo_free(priv, &priv->txf_fifo0.m); + bdx_tx_db_close(&priv->txdb); +} + +/* bdx_tx_push_desc - push descriptor to TxD fifo + * @priv - NIC private structure + * @data - desc's data + * @size - desc's size + * + * Pushes desc to TxD fifo and overlaps it if needed. + * NOTE: this func does not check for available space. this is responsibility + * of the caller. Neither does it check that data size is smaller then + * fifo size. + */ +static void bdx_tx_push_desc(struct bdx_priv *priv, void *data, int size) +{ + struct txd_fifo *f = &priv->txd_fifo0; + int i = f->m.memsz - f->m.wptr; + + if (size == 0) + return; + + if (i > size) { + memcpy(f->m.va + f->m.wptr, data, size); + f->m.wptr += size; + } else { + memcpy(f->m.va + f->m.wptr, data, i); + f->m.wptr = size - i; + memcpy(f->m.va, data + i, f->m.wptr); + } + WRITE_REG(priv, f->m.reg_WPTR, f->m.wptr & TXF_WPTR_WR_PTR); +} + +/* bdx_tx_push_desc_safe - push descriptor to TxD fifo in a safe way + * @priv - NIC private structure + * @data - desc's data + * @size - desc's size + * + * NOTE: this func does check for available space and, if neccessary, waits for + * NIC to read existing data before writing new one. + */ +static void bdx_tx_push_desc_safe(struct bdx_priv *priv, void *data, int size) +{ + int timer = 0; + ENTER; + + while (size > 0) { + /* we substruct 8 because when fifo is full rptr == wptr + which also means that fifo is empty, we can understand + the difference, but could hw do the same ??? :) */ + int avail = bdx_tx_space(priv) - 8; + if (avail <= 0) { + if (timer++ > 300) { /* prevent endless loop */ + DBG("timeout while writing desc to TxD fifo\n"); + break; + } + udelay(50); /* give hw a chance to clean fifo */ + continue; + } + avail = MIN(avail, size); + DBG("about to push %d bytes starting %p size %d\n", avail, + data, size); + bdx_tx_push_desc(priv, data, avail); + size -= avail; + data += avail; + } + RET(); +} + +/** + * bdx_probe - Device Initialization Routine + * @pdev: PCI device information struct + * @ent: entry in bdx_pci_tbl + * + * Returns 0 on success, negative on failure + * + * bdx_probe initializes an adapter identified by a pci_dev structure. + * The OS initialization, configuring of the adapter private structure, + * and a hardware reset occur. + * + * functions and their order used as explained in + * /usr/src/linux/Documentation/DMA-{API,mapping}.txt + * + */ + +/* TBD: netif_msg should be checked and implemented. I disable it for now */ +static int __devinit +bdx_probe(struct pci_dev *pdev, const struct pci_device_id *ent) +{ + struct net_device *ndev; + struct bdx_priv *priv; + int err, pci_using_dac, port; + unsigned long pciaddr; + u32 regionSize; + struct pci_nic *nic; + + ENTER; + + nic = vmalloc(sizeof(*nic)); + if (!nic) + RET(-ENOMEM); + + /************** pci *****************/ + if ((err = pci_enable_device(pdev))) /* it trigers interrupt, dunno why. */ + RET(err); /* it's not a problem though */ + + if (!(err = pci_set_dma_mask(pdev, DMA_64BIT_MASK)) && + !(err = pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK))) { + pci_using_dac = 1; + } else { + if ((err = pci_set_dma_mask(pdev, DMA_32BIT_MASK)) || + (err = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK))) { + printk(KERN_ERR "tehuti: No usable DMA configuration" + ", aborting\n"); + goto err_dma; + } + pci_using_dac = 0; + } + + if ((err = pci_request_regions(pdev, BDX_DRV_NAME))) + goto err_dma; + + pci_set_master(pdev); + + pciaddr = pci_resource_start(pdev, 0); + if (!pciaddr) { + err = -EIO; + ERR("tehuti: no MMIO resource\n"); + goto err_out_res; + } + if ((regionSize = pci_resource_len(pdev, 0)) < BDX_REGS_SIZE) { + err = -EIO; + ERR("tehuti: MMIO resource (%x) too small\n", regionSize); + goto err_out_res; + } + + nic->regs = ioremap(pciaddr, regionSize); + if (!nic->regs) { + err = -EIO; + ERR("tehuti: ioremap failed\n"); + goto err_out_res; + } + + if (pdev->irq < 2) { + err = -EIO; + ERR("tehuti: invalid irq (%d)\n", pdev->irq); + goto err_out_iomap; + } + pci_set_drvdata(pdev, nic); + + if (pdev->device == 0x3014) + nic->port_num = 2; + else + nic->port_num = 1; + + print_hw_id(pdev); + + bdx_hw_reset_direct(nic->regs); + + nic->irq_type = IRQ_INTX; +#ifdef BDX_MSI + if ((readl(nic->regs + FPGA_VER) & 0xFFF) >= 378) { + if ((err = pci_enable_msi(pdev))) + ERR("Tehuti: Can't eneble msi. error is %d\n", err); + else + nic->irq_type = IRQ_MSI; + } else + DBG("HW does not support MSI\n"); +#endif + + /************** netdev **************/ + for (port = 0; port < nic->port_num; port++) { + if (!(ndev = alloc_etherdev(sizeof(struct bdx_priv)))) { + err = -ENOMEM; + printk(KERN_ERR "tehuti: alloc_etherdev failed\n"); + goto err_out_iomap; + } + + ndev->open = bdx_open; + ndev->stop = bdx_close; + ndev->hard_start_xmit = bdx_tx_transmit; + ndev->do_ioctl = bdx_ioctl; + ndev->set_multicast_list = bdx_setmulti; + ndev->get_stats = bdx_get_stats; + ndev->change_mtu = bdx_change_mtu; + ndev->set_mac_address = bdx_set_mac; + ndev->tx_queue_len = BDX_NDEV_TXQ_LEN; + ndev->vlan_rx_register = bdx_vlan_rx_register; + ndev->vlan_rx_add_vid = bdx_vlan_rx_add_vid; + ndev->vlan_rx_kill_vid = bdx_vlan_rx_kill_vid; + + bdx_ethtool_ops(ndev); /* ethtool interface */ + + /* these fields are used for info purposes only + * so we can have them same for all ports of the board */ + ndev->if_port = port; + ndev->base_addr = pciaddr; + ndev->mem_start = pciaddr; + ndev->mem_end = pciaddr + regionSize; + ndev->irq = pdev->irq; + ndev->features = NETIF_F_IP_CSUM | NETIF_F_SG | NETIF_F_TSO + | NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX | + NETIF_F_HW_VLAN_FILTER + /*| NETIF_F_FRAGLIST */ + ; + + if (pci_using_dac) + ndev->features |= NETIF_F_HIGHDMA; + + /************** priv ****************/ + priv = nic->priv[port] = ndev->priv; + + memset(priv, 0, sizeof(struct bdx_priv)); + priv->pBdxRegs = nic->regs + port * 0x8000; + priv->port = port; + priv->pdev = pdev; + priv->ndev = ndev; + priv->nic = nic; + priv->msg_enable = BDX_DEF_MSG_ENABLE; + + netif_napi_add(ndev, &priv->napi, bdx_poll, 64); + + if ((readl(nic->regs + FPGA_VER) & 0xFFF) == 308) { + DBG("HW statistics not supported\n"); + priv->stats_flag = 0; + } else { + priv->stats_flag = 1; + } + + /* Initialize fifo sizes. */ + priv->txd_size = 2; + priv->txf_size = 2; + priv->rxd_size = 2; + priv->rxf_size = 3; + + /* Initialize the initial coalescing registers. */ + priv->rdintcm = INT_REG_VAL(0x20, 1, 4, 12); + priv->tdintcm = INT_REG_VAL(0x20, 1, 0, 12); + + /* ndev->xmit_lock spinlock is not used. + * Private priv->tx_lock is used for synchronization + * between transmit and TX irq cleanup. In addition + * set multicast list callback has to use priv->tx_lock. + */ +#ifdef BDX_LLTX + ndev->features |= NETIF_F_LLTX; +#endif + spin_lock_init(&priv->tx_lock); + + /*bdx_hw_reset(priv); */ + if (bdx_read_mac(priv)) { + printk(KERN_ERR "tehuti: load MAC address failed\n"); + goto err_out_iomap; + } + SET_NETDEV_DEV(ndev, &pdev->dev); + if ((err = register_netdev(ndev))) { + printk(KERN_ERR "tehuti: register_netdev failed\n"); + goto err_out_free; + } + netif_carrier_off(ndev); + netif_stop_queue(ndev); + + print_eth_id(ndev); + } + RET(0); + +err_out_free: + free_netdev(ndev); +err_out_iomap: + iounmap(nic->regs); +err_out_res: + pci_release_regions(pdev); +err_dma: + pci_disable_device(pdev); + vfree(nic); + + RET(err); +} + +/****************** Ethtool interface *********************/ +/* get strings for tests */ +static const char + bdx_test_names[][ETH_GSTRING_LEN] = { + "No tests defined" +}; + +/* get strings for statistics counters */ +static const char + bdx_stat_names[][ETH_GSTRING_LEN] = { + "InUCast", /* 0x7200 */ + "InMCast", /* 0x7210 */ + "InBCast", /* 0x7220 */ + "InPkts", /* 0x7230 */ + "InErrors", /* 0x7240 */ + "InDropped", /* 0x7250 */ + "FrameTooLong", /* 0x7260 */ + "FrameSequenceErrors", /* 0x7270 */ + "InVLAN", /* 0x7280 */ + "InDroppedDFE", /* 0x7290 */ + "InDroppedIntFull", /* 0x72A0 */ + "InFrameAlignErrors", /* 0x72B0 */ + + /* 0x72C0-0x72E0 RSRV */ + + "OutUCast", /* 0x72F0 */ + "OutMCast", /* 0x7300 */ + "OutBCast", /* 0x7310 */ + "OutPkts", /* 0x7320 */ + + /* 0x7330-0x7360 RSRV */ + + "OutVLAN", /* 0x7370 */ + "InUCastOctects", /* 0x7380 */ + "OutUCastOctects", /* 0x7390 */ + + /* 0x73A0-0x73B0 RSRV */ + + "InBCastOctects", /* 0x73C0 */ + "OutBCastOctects", /* 0x73D0 */ + "InOctects", /* 0x73E0 */ + "OutOctects", /* 0x73F0 */ +}; + +/* + * bdx_get_settings - get device-specific settings + * @netdev + * @ecmd + */ +static int bdx_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd) +{ + u32 rdintcm; + u32 tdintcm; + struct bdx_priv *priv = netdev->priv; + + rdintcm = priv->rdintcm; + tdintcm = priv->tdintcm; + + ecmd->supported = (SUPPORTED_10000baseT_Full | SUPPORTED_FIBRE); + ecmd->advertising = (ADVERTISED_10000baseT_Full | ADVERTISED_FIBRE); + ecmd->speed = SPEED_10000; + ecmd->duplex = DUPLEX_FULL; + ecmd->port = PORT_FIBRE; + ecmd->transceiver = XCVR_EXTERNAL; /* what does it mean? */ + ecmd->autoneg = AUTONEG_DISABLE; + + /* PCK_TH measures in multiples of FIFO bytes + We translate to packets */ + ecmd->maxtxpkt = + ((GET_PCK_TH(tdintcm) * PCK_TH_MULT) / BDX_TXF_DESC_SZ); + ecmd->maxrxpkt = + ((GET_PCK_TH(rdintcm) * PCK_TH_MULT) / sizeof(struct rxf_desc)); + + return 0; +} + +/* + * bdx_get_drvinfo - report driver information + * @netdev + * @drvinfo + */ +static void +bdx_get_drvinfo(struct net_device *netdev, struct ethtool_drvinfo *drvinfo) +{ + struct bdx_priv *priv = netdev->priv; + + strncat(drvinfo->driver, BDX_DRV_NAME, sizeof(drvinfo->driver)); + strncat(drvinfo->version, BDX_DRV_VERSION, sizeof(drvinfo->version)); + strncat(drvinfo->fw_version, "N/A", sizeof(drvinfo->fw_version)); + strncat(drvinfo->bus_info, pci_name(priv->pdev), + sizeof(drvinfo->bus_info)); + + drvinfo->n_stats = ((priv->stats_flag) ? + (sizeof(bdx_stat_names) / ETH_GSTRING_LEN) : 0); + drvinfo->testinfo_len = 0; + drvinfo->regdump_len = 0; + drvinfo->eedump_len = 0; +} + +/* + * bdx_get_rx_csum - report whether receive checksums are turned on or off + * @netdev + */ +static u32 bdx_get_rx_csum(struct net_device *netdev) +{ + return 1; /* always on */ +} + +/* + * bdx_get_tx_csum - report whether transmit checksums are turned on or off + * @netdev + */ +static u32 bdx_get_tx_csum(struct net_device *netdev) +{ + return (netdev->features & NETIF_F_IP_CSUM) != 0; +} + +/* + * bdx_get_coalesce - get interrupt coalescing parameters + * @netdev + * @ecoal + */ +static int +bdx_get_coalesce(struct net_device *netdev, struct ethtool_coalesce *ecoal) +{ + u32 rdintcm; + u32 tdintcm; + struct bdx_priv *priv = netdev->priv; + + rdintcm = priv->rdintcm; + tdintcm = priv->tdintcm; + + /* PCK_TH measures in multiples of FIFO bytes + We translate to packets */ + ecoal->rx_coalesce_usecs = GET_INT_COAL(rdintcm) * INT_COAL_MULT; + ecoal->rx_max_coalesced_frames = + ((GET_PCK_TH(rdintcm) * PCK_TH_MULT) / sizeof(struct rxf_desc)); + + ecoal->tx_coalesce_usecs = GET_INT_COAL(tdintcm) * INT_COAL_MULT; + ecoal->tx_max_coalesced_frames = + ((GET_PCK_TH(tdintcm) * PCK_TH_MULT) / BDX_TXF_DESC_SZ); + + /* adaptive parameters ignored */ + return 0; +} + +/* + * bdx_set_coalesce - set interrupt coalescing parameters + * @netdev + * @ecoal + */ +static int +bdx_set_coalesce(struct net_device *netdev, struct ethtool_coalesce *ecoal) +{ + u32 rdintcm; + u32 tdintcm; + struct bdx_priv *priv = netdev->priv; + int rx_coal; + int tx_coal; + int rx_max_coal; + int tx_max_coal; + + /* Check for valid input */ + rx_coal = ecoal->rx_coalesce_usecs / INT_COAL_MULT; + tx_coal = ecoal->tx_coalesce_usecs / INT_COAL_MULT; + rx_max_coal = ecoal->rx_max_coalesced_frames; + tx_max_coal = ecoal->tx_max_coalesced_frames; + + /* Translate from packets to multiples of FIFO bytes */ + rx_max_coal = + (((rx_max_coal * sizeof(struct rxf_desc)) + PCK_TH_MULT - 1) + / PCK_TH_MULT); + tx_max_coal = + (((tx_max_coal * BDX_TXF_DESC_SZ) + PCK_TH_MULT - 1) + / PCK_TH_MULT); + + if ((rx_coal > 0x7FFF) || (tx_coal > 0x7FFF) + || (rx_max_coal > 0xF) || (tx_max_coal > 0xF)) + return -EINVAL; + + rdintcm = INT_REG_VAL(rx_coal, GET_INT_COAL_RC(priv->rdintcm), + GET_RXF_TH(priv->rdintcm), rx_max_coal); + tdintcm = INT_REG_VAL(tx_coal, GET_INT_COAL_RC(priv->tdintcm), 0, + tx_max_coal); + + priv->rdintcm = rdintcm; + priv->tdintcm = tdintcm; + + WRITE_REG(priv, regRDINTCM0, rdintcm); + WRITE_REG(priv, regTDINTCM0, tdintcm); + + return 0; +} + +/* Convert RX fifo size to number of pending packets */ +static inline int bdx_rx_fifo_size_to_packets(int rx_size) +{ + return ((FIFO_SIZE * (1 << rx_size)) / sizeof(struct rxf_desc)); +} + +/* Convert TX fifo size to number of pending packets */ +static inline int bdx_tx_fifo_size_to_packets(int tx_size) +{ + return ((FIFO_SIZE * (1 << tx_size)) / BDX_TXF_DESC_SZ); +} + +/* + * bdx_get_ringparam - report ring sizes + * @netdev + * @ring + */ +static void +bdx_get_ringparam(struct net_device *netdev, struct ethtool_ringparam *ring) +{ + struct bdx_priv *priv = netdev->priv; + + /*max_pending - the maximum-sized FIFO we allow */ + ring->rx_max_pending = bdx_rx_fifo_size_to_packets(3); + ring->tx_max_pending = bdx_tx_fifo_size_to_packets(3); + ring->rx_pending = bdx_rx_fifo_size_to_packets(priv->rxf_size); + ring->tx_pending = bdx_tx_fifo_size_to_packets(priv->txd_size); +} + +/* + * bdx_set_ringparam - set ring sizes + * @netdev + * @ring + */ +static int +bdx_set_ringparam(struct net_device *netdev, struct ethtool_ringparam *ring) +{ + struct bdx_priv *priv = netdev->priv; + int rx_size = 0; + int tx_size = 0; + + for (; rx_size < 4; rx_size++) { + if (bdx_rx_fifo_size_to_packets(rx_size) >= ring->rx_pending) + break; + } + if (rx_size == 4) + rx_size = 3; + + for (; tx_size < 4; tx_size++) { + if (bdx_tx_fifo_size_to_packets(tx_size) >= ring->tx_pending) + break; + } + if (tx_size == 4) + tx_size = 3; + + /*Is there anything to do? */ + if ((rx_size == priv->rxf_size) + && (tx_size == priv->txd_size)) + return 0; + + priv->rxf_size = rx_size; + if (rx_size > 1) + priv->rxd_size = rx_size - 1; + else + priv->rxd_size = rx_size; + + priv->txf_size = priv->txd_size = tx_size; + + if (netif_running(netdev)) { + bdx_close(netdev); + bdx_open(netdev); + } + return 0; +} + +/* + * bdx_get_strings - return a set of strings that describe the requested objects + * @netdev + * @data + */ +static void bdx_get_strings(struct net_device *netdev, u32 stringset, u8 *data) +{ + switch (stringset) { + case ETH_SS_TEST: + memcpy(data, *bdx_test_names, sizeof(bdx_test_names)); + break; + case ETH_SS_STATS: + memcpy(data, *bdx_stat_names, sizeof(bdx_stat_names)); + break; + } +} + +/* + * bdx_get_stats_count - return number of 64bit statistics counters + * @netdev + */ +static int bdx_get_stats_count(struct net_device *netdev) +{ + struct bdx_priv *priv = netdev->priv; + BDX_ASSERT(sizeof(bdx_stat_names) / ETH_GSTRING_LEN + != sizeof(struct bdx_stats) / sizeof(u64)); + return ((priv->stats_flag) ? (sizeof(bdx_stat_names) / ETH_GSTRING_LEN) + : 0); +} + +/* + * bdx_get_ethtool_stats - return device's hardware L2 statistics + * @netdev + * @stats + * @data + */ +static void bdx_get_ethtool_stats(struct net_device *netdev, + struct ethtool_stats *stats, u64 *data) +{ + struct bdx_priv *priv = netdev->priv; + + if (priv->stats_flag) { + + /* Update stats from HW */ + bdx_update_stats(priv); + + /* Copy data to user buffer */ + memcpy(data, &priv->hw_stats, sizeof(priv->hw_stats)); + } +} + +/* + * bdx_ethtool_ops - ethtool interface implementation + * @netdev + */ +static void bdx_ethtool_ops(struct net_device *netdev) +{ + static struct ethtool_ops bdx_ethtool_ops = { + .get_settings = bdx_get_settings, + .get_drvinfo = bdx_get_drvinfo, + .get_link = ethtool_op_get_link, + .get_coalesce = bdx_get_coalesce, + .set_coalesce = bdx_set_coalesce, + .get_ringparam = bdx_get_ringparam, + .set_ringparam = bdx_set_ringparam, + .get_rx_csum = bdx_get_rx_csum, + .get_tx_csum = bdx_get_tx_csum, + .get_sg = ethtool_op_get_sg, + .get_tso = ethtool_op_get_tso, + .get_strings = bdx_get_strings, + .get_stats_count = bdx_get_stats_count, + .get_ethtool_stats = bdx_get_ethtool_stats, + }; + + SET_ETHTOOL_OPS(netdev, &bdx_ethtool_ops); +} + +/** + * bdx_remove - Device Removal Routine + * @pdev: PCI device information struct + * + * bdx_remove is called by the PCI subsystem to alert the driver + * that it should release a PCI device. The could be caused by a + * Hot-Plug event, or because the driver is going to be removed from + * memory. + **/ +static void __devexit bdx_remove(struct pci_dev *pdev) +{ + struct pci_nic *nic = pci_get_drvdata(pdev); + struct net_device *ndev; + int port; + + for (port = 0; port < nic->port_num; port++) { + ndev = nic->priv[port]->ndev; + unregister_netdev(ndev); + free_netdev(ndev); + } + + /*bdx_hw_reset_direct(nic->regs); */ +#ifdef BDX_MSI + if (nic->irq_type == IRQ_MSI) + pci_disable_msi(pdev); +#endif + + iounmap(nic->regs); + pci_release_regions(pdev); + pci_disable_device(pdev); + pci_set_drvdata(pdev, NULL); + vfree(nic); + + RET(); +} + +static struct pci_driver bdx_pci_driver = { + .name = BDX_DRV_NAME, + .id_table = bdx_pci_tbl, + .probe = bdx_probe, + .remove = __devexit_p(bdx_remove), +}; + +/* + * print_driver_id - print parameters of the driver build + */ +static void __init print_driver_id(void) +{ + printk(KERN_INFO "%s: %s, %s\n", BDX_DRV_NAME, BDX_DRV_DESC, + BDX_DRV_VERSION); + printk(KERN_INFO "%s: Options: hw_csum %s\n", BDX_DRV_NAME, + BDX_MSI_STRING); +} + +static int __init bdx_module_init(void) +{ + ENTER; + bdx_firmware_endianess(); + init_txd_sizes(); + print_driver_id(); + RET(pci_register_driver(&bdx_pci_driver)); +} + +module_init(bdx_module_init); + +static void __exit bdx_module_exit(void) +{ + ENTER; + pci_unregister_driver(&bdx_pci_driver); + RET(); +} + +module_exit(bdx_module_exit); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR(DRIVER_AUTHOR); +MODULE_DESCRIPTION(BDX_DRV_DESC); diff --git a/drivers/net/tehuti.h b/drivers/net/tehuti.h new file mode 100644 index 000000000000..efd170f451b4 --- /dev/null +++ b/drivers/net/tehuti.h @@ -0,0 +1,564 @@ +/* + * Tehuti Networks(R) Network Driver + * Copyright (C) 2007 Tehuti Networks Ltd. All rights reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#ifndef _TEHUTI_H +#define _TEHUTI_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Compile Time Switches */ +/* start */ +#define BDX_TSO +#define BDX_LLTX +#define BDX_DELAY_WPTR +/* #define BDX_MSI */ +/* end */ + +#if !defined CONFIG_PCI_MSI +# undef BDX_MSI +#endif + +#define BDX_DEF_MSG_ENABLE (NETIF_MSG_DRV | \ + NETIF_MSG_PROBE | \ + NETIF_MSG_LINK) + +/* ioctl ops */ +#define BDX_OP_READ 1 +#define BDX_OP_WRITE 2 + +/* RX copy break size */ +#define BDX_COPYBREAK 257 + +#define DRIVER_AUTHOR "Tehuti Networks(R)" +#define BDX_DRV_DESC "Tehuti Networks(R) Network Driver" +#define BDX_DRV_NAME "tehuti" +#define BDX_NIC_NAME "Tehuti 10 Giga TOE SmartNIC" +#define BDX_NIC2PORT_NAME "Tehuti 2-Port 10 Giga TOE SmartNIC" +#define BDX_DRV_VERSION "7.29.3" + +#ifdef BDX_MSI +# define BDX_MSI_STRING "msi " +#else +# define BDX_MSI_STRING "" +#endif + +/* netdev tx queue len for Luxor. default value is, btw, 1000 + * ifcontig eth1 txqueuelen 3000 - to change it at runtime */ +#define BDX_NDEV_TXQ_LEN 3000 + +#define FIFO_SIZE 4096 +#define FIFO_EXTRA_SPACE 1024 + +#define MIN(x, y) ((x) < (y) ? (x) : (y)) + +#if BITS_PER_LONG == 64 +# define H32_64(x) (u32) ((u64)(x) >> 32) +# define L32_64(x) (u32) ((u64)(x) & 0xffffffff) +#elif BITS_PER_LONG == 32 +# define H32_64(x) 0 +# define L32_64(x) ((u32) (x)) +#else /* BITS_PER_LONG == ?? */ +# error BITS_PER_LONG is undefined. Must be 64 or 32 +#endif /* BITS_PER_LONG */ + +#ifdef __BIG_ENDIAN +# define CPU_CHIP_SWAP32(x) swab32(x) +# define CPU_CHIP_SWAP16(x) swab16(x) +#else +# define CPU_CHIP_SWAP32(x) (x) +# define CPU_CHIP_SWAP16(x) (x) +#endif + +#define READ_REG(pp, reg) readl(pp->pBdxRegs + reg) +#define WRITE_REG(pp, reg, val) writel(val, pp->pBdxRegs + reg) + +#ifndef DMA_64BIT_MASK +# define DMA_64BIT_MASK 0xffffffffffffffffULL +#endif + +#ifndef DMA_32BIT_MASK +# define DMA_32BIT_MASK 0x00000000ffffffffULL +#endif + +#ifndef NET_IP_ALIGN +# define NET_IP_ALIGN 2 +#endif + +#ifndef NETDEV_TX_OK +# define NETDEV_TX_OK 0 +#endif + +#define LUXOR_MAX_PORT 2 +#define BDX_MAX_RX_DONE 150 +#define BDX_TXF_DESC_SZ 16 +#define BDX_MAX_TX_LEVEL (priv->txd_fifo0.m.memsz - 16) +#define BDX_MIN_TX_LEVEL 256 +#define BDX_NO_UPD_PACKETS 40 + +struct pci_nic { + int port_num; + void __iomem *regs; + int irq_type; + struct bdx_priv *priv[LUXOR_MAX_PORT]; +}; + +enum { IRQ_INTX, IRQ_MSI, IRQ_MSIX }; + +#define PCK_TH_MULT 128 +#define INT_COAL_MULT 2 + +#define BITS_MASK(nbits) ((1<>nshift)&BITS_MASK(nbits)) +#define BITS_SHIFT_MASK(nbits, nshift) (BITS_MASK(nbits)< Date: Tue, 18 Sep 2007 13:20:41 -0700 Subject: [NETNS]: Cleanup list walking in setup_net and cleanup_net I proposed introducing a list_for_each_entry_continue_reverse macro to be used in setup_net() when unrolling the failed ->init callback. Here is the macro and some more cleanup in the setup_net() itself to remove one variable from the stack :) The same thing is for the cleanup_net() - the existing list_for_each_entry_reverse() is used. Minor, but the code looks nicer. Signed-off-by: Pavel Emelyanov Acked-by: "Eric W. Biederman" Signed-off-by: David S. Miller --- include/linux/list.h | 14 ++++++++++++++ net/core/net_namespace.c | 12 ++++-------- 2 files changed, 18 insertions(+), 8 deletions(-) (limited to 'include/linux') diff --git a/include/linux/list.h b/include/linux/list.h index f29fc9c1a964..ad9dcb9e3375 100644 --- a/include/linux/list.h +++ b/include/linux/list.h @@ -524,6 +524,20 @@ static inline void list_splice_init_rcu(struct list_head *list, prefetch(pos->member.next), &pos->member != (head); \ pos = list_entry(pos->member.next, typeof(*pos), member)) +/** + * list_for_each_entry_continue_reverse - iterate backwards from the given point + * @pos: the type * to use as a loop cursor. + * @head: the head for your list. + * @member: the name of the list_struct within the struct. + * + * Start to iterate over list of given type backwards, continuing after + * the current position. + */ +#define list_for_each_entry_continue_reverse(pos, head, member) \ + for (pos = list_entry(pos->member.prev, typeof(*pos), member); \ + prefetch(pos->member.prev), &pos->member != (head); \ + pos = list_entry(pos->member.prev, typeof(*pos), member)) + /** * list_for_each_entry_from - iterate over list of given type from the current point * @pos: the type * to use as a loop cursor. diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c index 1fc513c4c79e..0e6cb02d7b77 100644 --- a/net/core/net_namespace.c +++ b/net/core/net_namespace.c @@ -56,7 +56,6 @@ static void net_free(struct net *net) static void cleanup_net(struct work_struct *work) { struct pernet_operations *ops; - struct list_head *ptr; struct net *net; net = container_of(work, struct net, work); @@ -69,8 +68,7 @@ static void cleanup_net(struct work_struct *work) net_unlock(); /* Run all of the network namespace exit methods */ - list_for_each_prev(ptr, &pernet_list) { - ops = list_entry(ptr, struct pernet_operations, list); + list_for_each_entry_reverse(ops, &pernet_list, list) { if (ops->exit) ops->exit(net); } @@ -102,7 +100,6 @@ static int setup_net(struct net *net) { /* Must be called with net_mutex held */ struct pernet_operations *ops; - struct list_head *ptr; int error; memset(net, 0, sizeof(struct net)); @@ -110,8 +107,7 @@ static int setup_net(struct net *net) atomic_set(&net->use_count, 0); error = 0; - list_for_each(ptr, &pernet_list) { - ops = list_entry(ptr, struct pernet_operations, list); + list_for_each_entry(ops, &pernet_list, list) { if (ops->init) { error = ops->init(net); if (error < 0) @@ -120,12 +116,12 @@ static int setup_net(struct net *net) } out: return error; + out_undo: /* Walk through the list backwards calling the exit functions * for the pernet modules whose init functions did not fail. */ - for (ptr = ptr->prev; ptr != &pernet_list; ptr = ptr->prev) { - ops = list_entry(ptr, struct pernet_operations, list); + list_for_each_entry_continue_reverse(ops, &pernet_list, list) { if (ops->exit) ops->exit(net); } -- cgit v1.2.3 From 61e115a56d1aafd6e6a8a9fee8ac099a6128ac7b Mon Sep 17 00:00:00 2001 From: Michael Buesch Date: Tue, 18 Sep 2007 15:12:50 -0400 Subject: [SSB]: add Sonics Silicon Backplane bus support SSB is an SoC bus used in a number of embedded devices. The most well-known of these devices is probably the Linksys WRT54G, but there are others as well. The bus is also used internally on the BCM43xx and BCM44xx devices from Broadcom. This patch also includes support for SSB ID tables in modules, so that SSB drivers can be loaded automatically. Signed-off-by: Michael Buesch Signed-off-by: John W. Linville Signed-off-by: David S. Miller --- MAINTAINERS | 6 + drivers/Kconfig | 2 + drivers/Makefile | 1 + drivers/ssb/Kconfig | 117 +++ drivers/ssb/Makefile | 18 + drivers/ssb/b43_pci_bridge.c | 46 ++ drivers/ssb/driver_chipcommon.c | 446 +++++++++++ drivers/ssb/driver_extif.c | 129 ++++ drivers/ssb/driver_mipscore.c | 223 ++++++ drivers/ssb/driver_pcicore.c | 576 ++++++++++++++ drivers/ssb/main.c | 1162 +++++++++++++++++++++++++++++ drivers/ssb/pci.c | 740 ++++++++++++++++++ drivers/ssb/pcihost_wrapper.c | 104 +++ drivers/ssb/pcmcia.c | 271 +++++++ drivers/ssb/scan.c | 413 ++++++++++ drivers/ssb/ssb_private.h | 136 ++++ include/linux/mod_devicetable.h | 15 + include/linux/ssb/ssb.h | 424 +++++++++++ include/linux/ssb/ssb_driver_chipcommon.h | 396 ++++++++++ include/linux/ssb/ssb_driver_extif.h | 204 +++++ include/linux/ssb/ssb_driver_mips.h | 46 ++ include/linux/ssb/ssb_driver_pci.h | 106 +++ include/linux/ssb/ssb_regs.h | 292 ++++++++ scripts/mod/file2alias.c | 19 + 24 files changed, 5892 insertions(+) create mode 100644 drivers/ssb/Kconfig create mode 100644 drivers/ssb/Makefile create mode 100644 drivers/ssb/b43_pci_bridge.c create mode 100644 drivers/ssb/driver_chipcommon.c create mode 100644 drivers/ssb/driver_extif.c create mode 100644 drivers/ssb/driver_mipscore.c create mode 100644 drivers/ssb/driver_pcicore.c create mode 100644 drivers/ssb/main.c create mode 100644 drivers/ssb/pci.c create mode 100644 drivers/ssb/pcihost_wrapper.c create mode 100644 drivers/ssb/pcmcia.c create mode 100644 drivers/ssb/scan.c create mode 100644 drivers/ssb/ssb_private.h create mode 100644 include/linux/ssb/ssb.h create mode 100644 include/linux/ssb/ssb_driver_chipcommon.h create mode 100644 include/linux/ssb/ssb_driver_extif.h create mode 100644 include/linux/ssb/ssb_driver_mips.h create mode 100644 include/linux/ssb/ssb_driver_pci.h create mode 100644 include/linux/ssb/ssb_regs.h (limited to 'include/linux') diff --git a/MAINTAINERS b/MAINTAINERS index 3f07d5ff85f1..7524cd802da3 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -3446,6 +3446,12 @@ M: tsbogend@alpha.franken.de L: netdev@vger.kernel.org S: Maintained +SONICS SILICON BACKPLANE DRIVER (SSB) +P: Michael Buesch +M: mb@bu3sch.de +L: netdev@vger.kernel.org +S: Maintained + SONY VAIO CONTROL DEVICE DRIVER P: Mattia Dongili M: malattia@linux.it diff --git a/drivers/Kconfig b/drivers/Kconfig index 3e1c442deff9..7bdae47d6b91 100644 --- a/drivers/Kconfig +++ b/drivers/Kconfig @@ -58,6 +58,8 @@ source "drivers/power/Kconfig" source "drivers/hwmon/Kconfig" +source "drivers/ssb/Kconfig" + source "drivers/mfd/Kconfig" source "drivers/media/Kconfig" diff --git a/drivers/Makefile b/drivers/Makefile index f0878b2ec55e..a168eacdcd9c 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -88,3 +88,4 @@ obj-$(CONFIG_DMA_ENGINE) += dma/ obj-$(CONFIG_HID) += hid/ obj-$(CONFIG_PPC_PS3) += ps3/ obj-$(CONFIG_OF) += of/ +obj-$(CONFIG_SSB) += ssb/ diff --git a/drivers/ssb/Kconfig b/drivers/ssb/Kconfig new file mode 100644 index 000000000000..b4a5e5e9d9fc --- /dev/null +++ b/drivers/ssb/Kconfig @@ -0,0 +1,117 @@ +menu "Sonics Silicon Backplane" + +config SSB_POSSIBLE + bool + depends on HAS_IOMEM + default y + +config SSB + tristate "Sonics Silicon Backplane support" + depends on SSB_POSSIBLE + help + Support for the Sonics Silicon Backplane bus. + You only need to enable this option, if you are + configuring a kernel for an embedded system with + this bus. + It will be auto-selected if needed in other + environments. + + The module will be called ssb. + + If unsure, say N. + +config SSB_PCIHOST_POSSIBLE + bool + depends on SSB && PCI + default y + +config SSB_PCIHOST + bool "Support for SSB on PCI-bus host" + depends on SSB_PCIHOST_POSSIBLE + default y + help + Support for a Sonics Silicon Backplane on top + of a PCI device. + + If unsure, say Y + +config SSB_PCMCIAHOST_POSSIBLE + bool + depends on SSB && PCMCIA && EXPERIMENTAL + default y + +config SSB_PCMCIAHOST + bool "Support for SSB on PCMCIA-bus host (EXPERIMENTAL)" + depends on SSB_PCMCIAHOST_POSSIBLE + help + Support for a Sonics Silicon Backplane on top + of a PCMCIA device. + + If unsure, say N + +config SSB_SILENT + bool "No SSB kernel messages" + depends on SSB && EMBEDDED + help + This option turns off all Sonics Silicon Backplane printks. + Note that you won't be able to identify problems, once + messages are turned off. + This might only be desired for production kernels on + embedded devices to reduce the kernel size. + + Say N + +config SSB_DEBUG + bool "SSB debugging" + depends on SSB && !SSB_SILENT + help + This turns on additional runtime checks and debugging + messages. Turn this on for SSB troubleshooting. + + If unsure, say N + +config SSB_SERIAL + bool + depends on SSB + # ChipCommon and ExtIf serial support routines. + +config SSB_DRIVER_PCICORE_POSSIBLE + bool + depends on SSB_PCIHOST + default y + +config SSB_DRIVER_PCICORE + bool "SSB PCI core driver" + depends on SSB_DRIVER_PCICORE_POSSIBLE + help + Driver for the Sonics Silicon Backplane attached + Broadcom PCI core. + + If unsure, say Y + +config SSB_PCICORE_HOSTMODE + bool "Hostmode support for SSB PCI core (EXPERIMENTAL)" + depends on SSB_DRIVER_PCICORE && SSB_DRIVER_MIPS && EXPERIMENTAL + help + PCIcore hostmode operation (external PCI bus). + +config SSB_DRIVER_MIPS + bool "SSB Broadcom MIPS core driver (EXPERIMENTAL)" + depends on SSB && MIPS && EXPERIMENTAL + select SSB_SERIAL + help + Driver for the Sonics Silicon Backplane attached + Broadcom MIPS core. + + If unsure, say N + +config SSB_DRIVER_EXTIF + bool "SSB Broadcom EXTIF core driver (EXPERIMENTAL)" + depends on SSB_DRIVER_MIPS && EXPERIMENTAL + help + Driver for the Sonics Silicon Backplane attached + Broadcom EXTIF core. + + If unsure, say N + +endmenu diff --git a/drivers/ssb/Makefile b/drivers/ssb/Makefile new file mode 100644 index 000000000000..7be397595805 --- /dev/null +++ b/drivers/ssb/Makefile @@ -0,0 +1,18 @@ +# core +ssb-y += main.o scan.o + +# host support +ssb-$(CONFIG_SSB_PCIHOST) += pci.o pcihost_wrapper.o +ssb-$(CONFIG_SSB_PCMCIAHOST) += pcmcia.o + +# built-in drivers +ssb-y += driver_chipcommon.o +ssb-$(CONFIG_SSB_DRIVER_MIPS) += driver_mipscore.o +ssb-$(CONFIG_SSB_DRIVER_EXTIF) += driver_extif.o +ssb-$(CONFIG_SSB_DRIVER_PCICORE) += driver_pcicore.o + +# b43 pci-ssb-bridge driver +# Not strictly a part of SSB, but kept here for convenience +ssb-$(CONFIG_SSB_PCIHOST) += b43_pci_bridge.o + +obj-$(CONFIG_SSB) += ssb.o diff --git a/drivers/ssb/b43_pci_bridge.c b/drivers/ssb/b43_pci_bridge.c new file mode 100644 index 000000000000..fa3bd292f5f7 --- /dev/null +++ b/drivers/ssb/b43_pci_bridge.c @@ -0,0 +1,46 @@ +/* + * Broadcom 43xx PCI-SSB bridge module + * + * This technically is a seperate PCI driver module, but + * because of its small size we include it in the SSB core + * instead of creating a standalone module. + * + * Copyright 2007 Michael Buesch + * + * Licensed under the GNU/GPL. See COPYING for details. + */ + +#include +#include + + +static const struct pci_device_id b43_pci_bridge_tbl[] = { + { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4301) }, + { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4307) }, + { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4311) }, + { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4312) }, + { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4318) }, + { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4319) }, + { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4320) }, + { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4321) }, + { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4324) }, + { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4325) }, + { 0, }, +}; +MODULE_DEVICE_TABLE(pci, b43_pci_bridge_tbl); + +static struct pci_driver b43_pci_bridge_driver = { + .name = "b43-pci-bridge", + .id_table = b43_pci_bridge_tbl, +}; + + +int __init b43_pci_ssb_bridge_init(void) +{ + return ssb_pcihost_register(&b43_pci_bridge_driver); +} + +void __exit b43_pci_ssb_bridge_exit(void) +{ + ssb_pcihost_unregister(&b43_pci_bridge_driver); +} diff --git a/drivers/ssb/driver_chipcommon.c b/drivers/ssb/driver_chipcommon.c new file mode 100644 index 000000000000..a890544e8fba --- /dev/null +++ b/drivers/ssb/driver_chipcommon.c @@ -0,0 +1,446 @@ +/* + * Sonics Silicon Backplane + * Broadcom ChipCommon core driver + * + * Copyright 2005, Broadcom Corporation + * Copyright 2006, 2007, Michael Buesch + * + * Licensed under the GNU/GPL. See COPYING for details. + */ + +#include +#include +#include + +#include "ssb_private.h" + + +/* Clock sources */ +enum ssb_clksrc { + /* PCI clock */ + SSB_CHIPCO_CLKSRC_PCI, + /* Crystal slow clock oscillator */ + SSB_CHIPCO_CLKSRC_XTALOS, + /* Low power oscillator */ + SSB_CHIPCO_CLKSRC_LOPWROS, +}; + + +static inline u32 chipco_read32(struct ssb_chipcommon *cc, + u16 offset) +{ + return ssb_read32(cc->dev, offset); +} + +static inline void chipco_write32(struct ssb_chipcommon *cc, + u16 offset, + u32 value) +{ + ssb_write32(cc->dev, offset, value); +} + +static inline void chipco_write32_masked(struct ssb_chipcommon *cc, u16 offset, + u32 mask, u32 value) +{ + value &= mask; + value |= chipco_read32(cc, offset) & ~mask; + chipco_write32(cc, offset, value); +} + +void ssb_chipco_set_clockmode(struct ssb_chipcommon *cc, + enum ssb_clkmode mode) +{ + struct ssb_device *ccdev = cc->dev; + struct ssb_bus *bus; + u32 tmp; + + if (!ccdev) + return; + bus = ccdev->bus; + /* chipcommon cores prior to rev6 don't support dynamic clock control */ + if (ccdev->id.revision < 6) + return; + /* chipcommon cores rev10 are a whole new ball game */ + if (ccdev->id.revision >= 10) + return; + if (!(cc->capabilities & SSB_CHIPCO_CAP_PCTL)) + return; + + switch (mode) { + case SSB_CLKMODE_SLOW: + tmp = chipco_read32(cc, SSB_CHIPCO_SLOWCLKCTL); + tmp |= SSB_CHIPCO_SLOWCLKCTL_FSLOW; + chipco_write32(cc, SSB_CHIPCO_SLOWCLKCTL, tmp); + break; + case SSB_CLKMODE_FAST: + ssb_pci_xtal(bus, SSB_GPIO_XTAL, 1); /* Force crystal on */ + tmp = chipco_read32(cc, SSB_CHIPCO_SLOWCLKCTL); + tmp &= ~SSB_CHIPCO_SLOWCLKCTL_FSLOW; + tmp |= SSB_CHIPCO_SLOWCLKCTL_IPLL; + chipco_write32(cc, SSB_CHIPCO_SLOWCLKCTL, tmp); + break; + case SSB_CLKMODE_DYNAMIC: + tmp = chipco_read32(cc, SSB_CHIPCO_SLOWCLKCTL); + tmp &= ~SSB_CHIPCO_SLOWCLKCTL_FSLOW; + tmp &= ~SSB_CHIPCO_SLOWCLKCTL_IPLL; + tmp &= ~SSB_CHIPCO_SLOWCLKCTL_ENXTAL; + if ((tmp & SSB_CHIPCO_SLOWCLKCTL_SRC) != SSB_CHIPCO_SLOWCLKCTL_SRC_XTAL) + tmp |= SSB_CHIPCO_SLOWCLKCTL_ENXTAL; + chipco_write32(cc, SSB_CHIPCO_SLOWCLKCTL, tmp); + + /* for dynamic control, we have to release our xtal_pu "force on" */ + if (tmp & SSB_CHIPCO_SLOWCLKCTL_ENXTAL) + ssb_pci_xtal(bus, SSB_GPIO_XTAL, 0); + break; + default: + SSB_WARN_ON(1); + } +} + +/* Get the Slow Clock Source */ +static enum ssb_clksrc chipco_pctl_get_slowclksrc(struct ssb_chipcommon *cc) +{ + struct ssb_bus *bus = cc->dev->bus; + u32 uninitialized_var(tmp); + + if (cc->dev->id.revision < 6) { + if (bus->bustype == SSB_BUSTYPE_SSB || + bus->bustype == SSB_BUSTYPE_PCMCIA) + return SSB_CHIPCO_CLKSRC_XTALOS; + if (bus->bustype == SSB_BUSTYPE_PCI) { + pci_read_config_dword(bus->host_pci, SSB_GPIO_OUT, &tmp); + if (tmp & 0x10) + return SSB_CHIPCO_CLKSRC_PCI; + return SSB_CHIPCO_CLKSRC_XTALOS; + } + } + if (cc->dev->id.revision < 10) { + tmp = chipco_read32(cc, SSB_CHIPCO_SLOWCLKCTL); + tmp &= 0x7; + if (tmp == 0) + return SSB_CHIPCO_CLKSRC_LOPWROS; + if (tmp == 1) + return SSB_CHIPCO_CLKSRC_XTALOS; + if (tmp == 2) + return SSB_CHIPCO_CLKSRC_PCI; + } + + return SSB_CHIPCO_CLKSRC_XTALOS; +} + +/* Get maximum or minimum (depending on get_max flag) slowclock frequency. */ +static int chipco_pctl_clockfreqlimit(struct ssb_chipcommon *cc, int get_max) +{ + int uninitialized_var(limit); + enum ssb_clksrc clocksrc; + int divisor = 1; + u32 tmp; + + clocksrc = chipco_pctl_get_slowclksrc(cc); + if (cc->dev->id.revision < 6) { + switch (clocksrc) { + case SSB_CHIPCO_CLKSRC_PCI: + divisor = 64; + break; + case SSB_CHIPCO_CLKSRC_XTALOS: + divisor = 32; + break; + default: + SSB_WARN_ON(1); + } + } else if (cc->dev->id.revision < 10) { + switch (clocksrc) { + case SSB_CHIPCO_CLKSRC_LOPWROS: + break; + case SSB_CHIPCO_CLKSRC_XTALOS: + case SSB_CHIPCO_CLKSRC_PCI: + tmp = chipco_read32(cc, SSB_CHIPCO_SLOWCLKCTL); + divisor = (tmp >> 16) + 1; + divisor *= 4; + break; + } + } else { + tmp = chipco_read32(cc, SSB_CHIPCO_SYSCLKCTL); + divisor = (tmp >> 16) + 1; + divisor *= 4; + } + + switch (clocksrc) { + case SSB_CHIPCO_CLKSRC_LOPWROS: + if (get_max) + limit = 43000; + else + limit = 25000; + break; + case SSB_CHIPCO_CLKSRC_XTALOS: + if (get_max) + limit = 20200000; + else + limit = 19800000; + break; + case SSB_CHIPCO_CLKSRC_PCI: + if (get_max) + limit = 34000000; + else + limit = 25000000; + break; + } + limit /= divisor; + + return limit; +} + +static void chipco_powercontrol_init(struct ssb_chipcommon *cc) +{ + struct ssb_bus *bus = cc->dev->bus; + + if (bus->chip_id == 0x4321) { + if (bus->chip_rev == 0) + chipco_write32(cc, SSB_CHIPCO_CHIPCTL, 0x3A4); + else if (bus->chip_rev == 1) + chipco_write32(cc, SSB_CHIPCO_CHIPCTL, 0xA4); + } + + if (!(cc->capabilities & SSB_CHIPCO_CAP_PCTL)) + return; + + if (cc->dev->id.revision >= 10) { + /* Set Idle Power clock rate to 1Mhz */ + chipco_write32(cc, SSB_CHIPCO_SYSCLKCTL, + (chipco_read32(cc, SSB_CHIPCO_SYSCLKCTL) & + 0x0000FFFF) | 0x00040000); + } else { + int maxfreq; + + maxfreq = chipco_pctl_clockfreqlimit(cc, 1); + chipco_write32(cc, SSB_CHIPCO_PLLONDELAY, + (maxfreq * 150 + 999999) / 1000000); + chipco_write32(cc, SSB_CHIPCO_FREFSELDELAY, + (maxfreq * 15 + 999999) / 1000000); + } +} + +static void calc_fast_powerup_delay(struct ssb_chipcommon *cc) +{ + struct ssb_bus *bus = cc->dev->bus; + int minfreq; + unsigned int tmp; + u32 pll_on_delay; + + if (bus->bustype != SSB_BUSTYPE_PCI) + return; + if (!(cc->capabilities & SSB_CHIPCO_CAP_PCTL)) + return; + + minfreq = chipco_pctl_clockfreqlimit(cc, 0); + pll_on_delay = chipco_read32(cc, SSB_CHIPCO_PLLONDELAY); + tmp = (((pll_on_delay + 2) * 1000000) + (minfreq - 1)) / minfreq; + SSB_WARN_ON(tmp & ~0xFFFF); + + cc->fast_pwrup_delay = tmp; +} + +void ssb_chipcommon_init(struct ssb_chipcommon *cc) +{ + if (!cc->dev) + return; /* We don't have a ChipCommon */ + chipco_powercontrol_init(cc); + ssb_chipco_set_clockmode(cc, SSB_CLKMODE_FAST); + calc_fast_powerup_delay(cc); +} + +void ssb_chipco_suspend(struct ssb_chipcommon *cc, pm_message_t state) +{ + if (!cc->dev) + return; + ssb_chipco_set_clockmode(cc, SSB_CLKMODE_SLOW); +} + +void ssb_chipco_resume(struct ssb_chipcommon *cc) +{ + if (!cc->dev) + return; + chipco_powercontrol_init(cc); + ssb_chipco_set_clockmode(cc, SSB_CLKMODE_FAST); +} + +/* Get the processor clock */ +void ssb_chipco_get_clockcpu(struct ssb_chipcommon *cc, + u32 *plltype, u32 *n, u32 *m) +{ + *n = chipco_read32(cc, SSB_CHIPCO_CLOCK_N); + *plltype = (cc->capabilities & SSB_CHIPCO_CAP_PLLT); + switch (*plltype) { + case SSB_PLLTYPE_2: + case SSB_PLLTYPE_4: + case SSB_PLLTYPE_6: + case SSB_PLLTYPE_7: + *m = chipco_read32(cc, SSB_CHIPCO_CLOCK_MIPS); + break; + case SSB_PLLTYPE_3: + /* 5350 uses m2 to control mips */ + *m = chipco_read32(cc, SSB_CHIPCO_CLOCK_M2); + break; + default: + *m = chipco_read32(cc, SSB_CHIPCO_CLOCK_SB); + break; + } +} + +/* Get the bus clock */ +void ssb_chipco_get_clockcontrol(struct ssb_chipcommon *cc, + u32 *plltype, u32 *n, u32 *m) +{ + *n = chipco_read32(cc, SSB_CHIPCO_CLOCK_N); + *plltype = (cc->capabilities & SSB_CHIPCO_CAP_PLLT); + switch (*plltype) { + case SSB_PLLTYPE_6: /* 100/200 or 120/240 only */ + *m = chipco_read32(cc, SSB_CHIPCO_CLOCK_MIPS); + break; + case SSB_PLLTYPE_3: /* 25Mhz, 2 dividers */ + if (cc->dev->bus->chip_id != 0x5365) { + *m = chipco_read32(cc, SSB_CHIPCO_CLOCK_M2); + break; + } + /* Fallthough */ + default: + *m = chipco_read32(cc, SSB_CHIPCO_CLOCK_SB); + } +} + +void ssb_chipco_timing_init(struct ssb_chipcommon *cc, + unsigned long ns) +{ + struct ssb_device *dev = cc->dev; + struct ssb_bus *bus = dev->bus; + u32 tmp; + + /* set register for external IO to control LED. */ + chipco_write32(cc, SSB_CHIPCO_PROG_CFG, 0x11); + tmp = DIV_ROUND_UP(10, ns) << SSB_PROG_WCNT_3_SHIFT; /* Waitcount-3 = 10ns */ + tmp |= DIV_ROUND_UP(40, ns) << SSB_PROG_WCNT_1_SHIFT; /* Waitcount-1 = 40ns */ + tmp |= DIV_ROUND_UP(240, ns); /* Waitcount-0 = 240ns */ + chipco_write32(cc, SSB_CHIPCO_PROG_WAITCNT, tmp); /* 0x01020a0c for a 100Mhz clock */ + + /* Set timing for the flash */ + tmp = DIV_ROUND_UP(10, ns) << SSB_FLASH_WCNT_3_SHIFT; /* Waitcount-3 = 10nS */ + tmp |= DIV_ROUND_UP(10, ns) << SSB_FLASH_WCNT_1_SHIFT; /* Waitcount-1 = 10nS */ + tmp |= DIV_ROUND_UP(120, ns); /* Waitcount-0 = 120nS */ + if ((bus->chip_id == 0x5365) || + (dev->id.revision < 9)) + chipco_write32(cc, SSB_CHIPCO_FLASH_WAITCNT, tmp); + if ((bus->chip_id == 0x5365) || + (dev->id.revision < 9) || + ((bus->chip_id == 0x5350) && (bus->chip_rev == 0))) + chipco_write32(cc, SSB_CHIPCO_PCMCIA_MEMWAIT, tmp); + + if (bus->chip_id == 0x5350) { + /* Enable EXTIF */ + tmp = DIV_ROUND_UP(10, ns) << SSB_PROG_WCNT_3_SHIFT; /* Waitcount-3 = 10ns */ + tmp |= DIV_ROUND_UP(20, ns) << SSB_PROG_WCNT_2_SHIFT; /* Waitcount-2 = 20ns */ + tmp |= DIV_ROUND_UP(100, ns) << SSB_PROG_WCNT_1_SHIFT; /* Waitcount-1 = 100ns */ + tmp |= DIV_ROUND_UP(120, ns); /* Waitcount-0 = 120ns */ + chipco_write32(cc, SSB_CHIPCO_PROG_WAITCNT, tmp); /* 0x01020a0c for a 100Mhz clock */ + } +} + +/* Set chip watchdog reset timer to fire in 'ticks' backplane cycles */ +void +ssb_chipco_watchdog_timer_set(struct ssb_chipcommon *cc, u32 ticks) +{ + /* instant NMI */ + chipco_write32(cc, SSB_CHIPCO_WATCHDOG, ticks); +} + +u32 ssb_chipco_gpio_in(struct ssb_chipcommon *cc, u32 mask) +{ + return chipco_read32(cc, SSB_CHIPCO_GPIOIN) & mask; +} + +void ssb_chipco_gpio_out(struct ssb_chipcommon *cc, u32 mask, u32 value) +{ + return chipco_write32_masked(cc, SSB_CHIPCO_GPIOOUT, mask, value); +} + +void ssb_chipco_gpio_outen(struct ssb_chipcommon *cc, u32 mask, u32 value) +{ + return chipco_write32_masked(cc, SSB_CHIPCO_GPIOOUTEN, mask, value); +} + +#ifdef CONFIG_SSB_SERIAL +int ssb_chipco_serial_init(struct ssb_chipcommon *cc, + struct ssb_serial_port *ports) +{ + struct ssb_bus *bus = cc->dev->bus; + int nr_ports = 0; + u32 plltype; + unsigned int irq; + u32 baud_base, div; + u32 i, n; + + plltype = (cc->capabilities & SSB_CHIPCO_CAP_PLLT); + irq = ssb_mips_irq(cc->dev); + + if (plltype == SSB_PLLTYPE_1) { + /* PLL clock */ + baud_base = ssb_calc_clock_rate(plltype, + chipco_read32(cc, SSB_CHIPCO_CLOCK_N), + chipco_read32(cc, SSB_CHIPCO_CLOCK_M2)); + div = 1; + } else { + if (cc->dev->id.revision >= 11) { + /* Fixed ALP clock */ + baud_base = 20000000; + div = 1; + /* Set the override bit so we don't divide it */ + chipco_write32(cc, SSB_CHIPCO_CORECTL, + SSB_CHIPCO_CORECTL_UARTCLK0); + } else if (cc->dev->id.revision >= 3) { + /* Internal backplane clock */ + baud_base = ssb_clockspeed(bus); + div = chipco_read32(cc, SSB_CHIPCO_CLKDIV) + & SSB_CHIPCO_CLKDIV_UART; + } else { + /* Fixed internal backplane clock */ + baud_base = 88000000; + div = 48; + } + + /* Clock source depends on strapping if UartClkOverride is unset */ + if ((cc->dev->id.revision > 0) && + !(chipco_read32(cc, SSB_CHIPCO_CORECTL) & SSB_CHIPCO_CORECTL_UARTCLK0)) { + if ((cc->capabilities & SSB_CHIPCO_CAP_UARTCLK) == + SSB_CHIPCO_CAP_UARTCLK_INT) { + /* Internal divided backplane clock */ + baud_base /= div; + } else { + /* Assume external clock of 1.8432 MHz */ + baud_base = 1843200; + } + } + } + + /* Determine the registers of the UARTs */ + n = (cc->capabilities & SSB_CHIPCO_CAP_NRUART); + for (i = 0; i < n; i++) { + void __iomem *cc_mmio; + void __iomem *uart_regs; + + cc_mmio = cc->dev->bus->mmio + (cc->dev->core_index * SSB_CORE_SIZE); + uart_regs = cc_mmio + SSB_CHIPCO_UART0_DATA; + /* Offset changed at after rev 0 */ + if (cc->dev->id.revision == 0) + uart_regs += (i * 8); + else + uart_regs += (i * 256); + + nr_ports++; + ports[i].regs = uart_regs; + ports[i].irq = irq; + ports[i].baud_base = baud_base; + ports[i].reg_shift = 0; + } + + return nr_ports; +} +#endif /* CONFIG_SSB_SERIAL */ diff --git a/drivers/ssb/driver_extif.c b/drivers/ssb/driver_extif.c new file mode 100644 index 000000000000..fe55eb8b038a --- /dev/null +++ b/drivers/ssb/driver_extif.c @@ -0,0 +1,129 @@ +/* + * Sonics Silicon Backplane + * Broadcom EXTIF core driver + * + * Copyright 2005, Broadcom Corporation + * Copyright 2006, 2007, Michael Buesch + * Copyright 2006, 2007, Felix Fietkau + * Copyright 2007, Aurelien Jarno + * + * Licensed under the GNU/GPL. See COPYING for details. + */ + +#include +#include +#include + +#include "ssb_private.h" + + +static inline u32 extif_read32(struct ssb_extif *extif, u16 offset) +{ + return ssb_read32(extif->dev, offset); +} + +static inline void extif_write32(struct ssb_extif *extif, u16 offset, u32 value) +{ + ssb_write32(extif->dev, offset, value); +} + +static inline void extif_write32_masked(struct ssb_extif *extif, u16 offset, + u32 mask, u32 value) +{ + value &= mask; + value |= extif_read32(extif, offset) & ~mask; + extif_write32(extif, offset, value); +} + +#ifdef CONFIG_SSB_SERIAL +static bool serial_exists(u8 *regs) +{ + u8 save_mcr, msr = 0; + + if (regs) { + save_mcr = regs[UART_MCR]; + regs[UART_MCR] = (UART_MCR_LOOP | UART_MCR_OUT2 | UART_MCR_RTS); + msr = regs[UART_MSR] & (UART_MSR_DCD | UART_MSR_RI + | UART_MSR_CTS | UART_MSR_DSR); + regs[UART_MCR] = save_mcr; + } + return (msr == (UART_MSR_DCD | UART_MSR_CTS)); +} + +int ssb_extif_serial_init(struct ssb_extif *extif, struct ssb_serial_port *ports) +{ + u32 i, nr_ports = 0; + + /* Disable GPIO interrupt initially */ + extif_write32(extif, SSB_EXTIF_GPIO_INTPOL, 0); + extif_write32(extif, SSB_EXTIF_GPIO_INTMASK, 0); + + for (i = 0; i < 2; i++) { + void __iomem *uart_regs; + + uart_regs = ioremap_nocache(SSB_EUART, 16); + if (uart_regs) { + uart_regs += (i * 8); + + if (serial_exists(uart_regs) && ports) { + extif_write32(extif, SSB_EXTIF_GPIO_INTMASK, 2); + + nr_ports++; + ports[i].regs = uart_regs; + ports[i].irq = 2; + ports[i].baud_base = 13500000; + ports[i].reg_shift = 0; + } + iounmap(uart_regs); + } + } + return nr_ports; +} +#endif /* CONFIG_SSB_SERIAL */ + +void ssb_extif_timing_init(struct ssb_extif *extif, unsigned long ns) +{ + u32 tmp; + + /* Initialize extif so we can get to the LEDs and external UART */ + extif_write32(extif, SSB_EXTIF_PROG_CFG, SSB_EXTCFG_EN); + + /* Set timing for the flash */ + tmp = DIV_ROUND_UP(10, ns) << SSB_PROG_WCNT_3_SHIFT; + tmp |= DIV_ROUND_UP(40, ns) << SSB_PROG_WCNT_1_SHIFT; + tmp |= DIV_ROUND_UP(120, ns); + extif_write32(extif, SSB_EXTIF_PROG_WAITCNT, tmp); + + /* Set programmable interface timing for external uart */ + tmp = DIV_ROUND_UP(10, ns) << SSB_PROG_WCNT_3_SHIFT; + tmp |= DIV_ROUND_UP(20, ns) << SSB_PROG_WCNT_2_SHIFT; + tmp |= DIV_ROUND_UP(100, ns) << SSB_PROG_WCNT_1_SHIFT; + tmp |= DIV_ROUND_UP(120, ns); + extif_write32(extif, SSB_EXTIF_PROG_WAITCNT, tmp); +} + +void ssb_extif_get_clockcontrol(struct ssb_extif *extif, + u32 *pll_type, u32 *n, u32 *m) +{ + *pll_type = SSB_PLLTYPE_1; + *n = extif_read32(extif, SSB_EXTIF_CLOCK_N); + *m = extif_read32(extif, SSB_EXTIF_CLOCK_SB); +} + +u32 ssb_extif_gpio_in(struct ssb_extif *extif, u32 mask) +{ + return extif_read32(extif, SSB_EXTIF_GPIO_IN) & mask; +} + +void ssb_extif_gpio_out(struct ssb_extif *extif, u32 mask, u32 value) +{ + return extif_write32_masked(extif, SSB_EXTIF_GPIO_OUT(0), + mask, value); +} + +void ssb_extif_gpio_outen(struct ssb_extif *extif, u32 mask, u32 value) +{ + return extif_write32_masked(extif, SSB_EXTIF_GPIO_OUTEN(0), + mask, value); +} + diff --git a/drivers/ssb/driver_mipscore.c b/drivers/ssb/driver_mipscore.c new file mode 100644 index 000000000000..ab8691a32580 --- /dev/null +++ b/drivers/ssb/driver_mipscore.c @@ -0,0 +1,223 @@ +/* + * Sonics Silicon Backplane + * Broadcom MIPS core driver + * + * Copyright 2005, Broadcom Corporation + * Copyright 2006, 2007, Michael Buesch + * + * Licensed under the GNU/GPL. See COPYING for details. + */ + +#include + +#include +#include +#include +#include + +#include "ssb_private.h" + + +static inline u32 mips_read32(struct ssb_mipscore *mcore, + u16 offset) +{ + return ssb_read32(mcore->dev, offset); +} + +static inline void mips_write32(struct ssb_mipscore *mcore, + u16 offset, + u32 value) +{ + ssb_write32(mcore->dev, offset, value); +} + +static const u32 ipsflag_irq_mask[] = { + 0, + SSB_IPSFLAG_IRQ1, + SSB_IPSFLAG_IRQ2, + SSB_IPSFLAG_IRQ3, + SSB_IPSFLAG_IRQ4, +}; + +static const u32 ipsflag_irq_shift[] = { + 0, + SSB_IPSFLAG_IRQ1_SHIFT, + SSB_IPSFLAG_IRQ2_SHIFT, + SSB_IPSFLAG_IRQ3_SHIFT, + SSB_IPSFLAG_IRQ4_SHIFT, +}; + +static inline u32 ssb_irqflag(struct ssb_device *dev) +{ + return ssb_read32(dev, SSB_TPSFLAG) & SSB_TPSFLAG_BPFLAG; +} + +/* Get the MIPS IRQ assignment for a specified device. + * If unassigned, 0 is returned. + */ +unsigned int ssb_mips_irq(struct ssb_device *dev) +{ + struct ssb_bus *bus = dev->bus; + u32 irqflag; + u32 ipsflag; + u32 tmp; + unsigned int irq; + + irqflag = ssb_irqflag(dev); + ipsflag = ssb_read32(bus->mipscore.dev, SSB_IPSFLAG); + for (irq = 1; irq <= 4; irq++) { + tmp = ((ipsflag & ipsflag_irq_mask[irq]) >> ipsflag_irq_shift[irq]); + if (tmp == irqflag) + break; + } + if (irq == 5) + irq = 0; + + return irq; +} + +static void clear_irq(struct ssb_bus *bus, unsigned int irq) +{ + struct ssb_device *dev = bus->mipscore.dev; + + /* Clear the IRQ in the MIPScore backplane registers */ + if (irq == 0) { + ssb_write32(dev, SSB_INTVEC, 0); + } else { + ssb_write32(dev, SSB_IPSFLAG, + ssb_read32(dev, SSB_IPSFLAG) | + ipsflag_irq_mask[irq]); + } +} + +static void set_irq(struct ssb_device *dev, unsigned int irq) +{ + unsigned int oldirq = ssb_mips_irq(dev); + struct ssb_bus *bus = dev->bus; + struct ssb_device *mdev = bus->mipscore.dev; + u32 irqflag = ssb_irqflag(dev); + + dev->irq = irq + 2; + + ssb_dprintk(KERN_INFO PFX + "set_irq: core 0x%04x, irq %d => %d\n", + dev->id.coreid, oldirq, irq); + /* clear the old irq */ + if (oldirq == 0) + ssb_write32(mdev, SSB_INTVEC, (~(1 << irqflag) & ssb_read32(mdev, SSB_INTVEC))); + else + clear_irq(bus, oldirq); + + /* assign the new one */ + if (irq == 0) + ssb_write32(mdev, SSB_INTVEC, ((1 << irqflag) & ssb_read32(mdev, SSB_INTVEC))); + + irqflag <<= ipsflag_irq_shift[irq]; + irqflag |= (ssb_read32(mdev, SSB_IPSFLAG) & ~ipsflag_irq_mask[irq]); + ssb_write32(mdev, SSB_IPSFLAG, irqflag); +} + +static void ssb_mips_serial_init(struct ssb_mipscore *mcore) +{ + struct ssb_bus *bus = mcore->dev->bus; + + if (bus->extif.dev) + mcore->nr_serial_ports = ssb_extif_serial_init(&bus->extif, mcore->serial_ports); + else if (bus->chipco.dev) + mcore->nr_serial_ports = ssb_chipco_serial_init(&bus->chipco, mcore->serial_ports); + else + mcore->nr_serial_ports = 0; +} + +static void ssb_mips_flash_detect(struct ssb_mipscore *mcore) +{ + struct ssb_bus *bus = mcore->dev->bus; + + mcore->flash_buswidth = 2; + if (bus->chipco.dev) { + mcore->flash_window = 0x1c000000; + mcore->flash_window_size = 0x02000000; + if ((ssb_read32(bus->chipco.dev, SSB_CHIPCO_FLASH_CFG) + & SSB_CHIPCO_CFG_DS16) == 0) + mcore->flash_buswidth = 1; + } else { + mcore->flash_window = 0x1fc00000; + mcore->flash_window_size = 0x00400000; + } +} + +u32 ssb_cpu_clock(struct ssb_mipscore *mcore) +{ + struct ssb_bus *bus = mcore->dev->bus; + u32 pll_type, n, m, rate = 0; + + if (bus->extif.dev) { + ssb_extif_get_clockcontrol(&bus->extif, &pll_type, &n, &m); + } else if (bus->chipco.dev) { + ssb_chipco_get_clockcpu(&bus->chipco, &pll_type, &n, &m); + } else + return 0; + + if ((pll_type == SSB_PLLTYPE_5) || (bus->chip_id == 0x5365)) { + rate = 200000000; + } else { + rate = ssb_calc_clock_rate(pll_type, n, m); + } + + if (pll_type == SSB_PLLTYPE_6) { + rate *= 2; + } + + return rate; +} + +void ssb_mipscore_init(struct ssb_mipscore *mcore) +{ + struct ssb_bus *bus = mcore->dev->bus; + struct ssb_device *dev; + unsigned long hz, ns; + unsigned int irq, i; + + if (!mcore->dev) + return; /* We don't have a MIPS core */ + + ssb_dprintk(KERN_INFO PFX "Initializing MIPS core...\n"); + + hz = ssb_clockspeed(bus); + if (!hz) + hz = 100000000; + ns = 1000000000 / hz; + + if (bus->extif.dev) + ssb_extif_timing_init(&bus->extif, ns); + else if (bus->chipco.dev) + ssb_chipco_timing_init(&bus->chipco, ns); + + /* Assign IRQs to all cores on the bus, start with irq line 2, because serial usually takes 1 */ + for (irq = 2, i = 0; i < bus->nr_devices; i++) { + dev = &(bus->devices[i]); + dev->irq = ssb_mips_irq(dev) + 2; + switch (dev->id.coreid) { + case SSB_DEV_USB11_HOST: + /* shouldn't need a separate irq line for non-4710, most of them have a proper + * external usb controller on the pci */ + if ((bus->chip_id == 0x4710) && (irq <= 4)) { + set_irq(dev, irq++); + break; + } + /* fallthrough */ + case SSB_DEV_PCI: + case SSB_DEV_ETHERNET: + case SSB_DEV_80211: + case SSB_DEV_USB20_HOST: + /* These devices get their own IRQ line if available, the rest goes on IRQ0 */ + if (irq <= 4) { + set_irq(dev, irq++); + break; + } + } + } + + ssb_mips_serial_init(mcore); + ssb_mips_flash_detect(mcore); +} diff --git a/drivers/ssb/driver_pcicore.c b/drivers/ssb/driver_pcicore.c new file mode 100644 index 000000000000..2faaa906d5d6 --- /dev/null +++ b/drivers/ssb/driver_pcicore.c @@ -0,0 +1,576 @@ +/* + * Sonics Silicon Backplane + * Broadcom PCI-core driver + * + * Copyright 2005, Broadcom Corporation + * Copyright 2006, 2007, Michael Buesch + * + * Licensed under the GNU/GPL. See COPYING for details. + */ + +#include +#include +#include + +#include "ssb_private.h" + + +static inline +u32 pcicore_read32(struct ssb_pcicore *pc, u16 offset) +{ + return ssb_read32(pc->dev, offset); +} + +static inline +void pcicore_write32(struct ssb_pcicore *pc, u16 offset, u32 value) +{ + ssb_write32(pc->dev, offset, value); +} + +/************************************************** + * Code for hostmode operation. + **************************************************/ + +#ifdef CONFIG_SSB_PCICORE_HOSTMODE + +#include +/* Probe a 32bit value on the bus and catch bus exceptions. + * Returns nonzero on a bus exception. + * This is MIPS specific */ +#define mips_busprobe32(val, addr) get_dbe((val), ((u32 *)(addr))) + +/* Assume one-hot slot wiring */ +#define SSB_PCI_SLOT_MAX 16 + +/* Global lock is OK, as we won't have more than one extpci anyway. */ +static DEFINE_SPINLOCK(cfgspace_lock); +/* Core to access the external PCI config space. Can only have one. */ +static struct ssb_pcicore *extpci_core; + +static u32 ssb_pcicore_pcibus_iobase = 0x100; +static u32 ssb_pcicore_pcibus_membase = SSB_PCI_DMA; + +int pcibios_plat_dev_init(struct pci_dev *d) +{ + struct resource *res; + int pos, size; + u32 *base; + + ssb_printk(KERN_INFO "PCI: Fixing up device %s\n", + pci_name(d)); + + /* Fix up resource bases */ + for (pos = 0; pos < 6; pos++) { + res = &d->resource[pos]; + if (res->flags & IORESOURCE_IO) + base = &ssb_pcicore_pcibus_iobase; + else + base = &ssb_pcicore_pcibus_membase; + if (res->end) { + size = res->end - res->start + 1; + if (*base & (size - 1)) + *base = (*base + size) & ~(size - 1); + res->start = *base; + res->end = res->start + size - 1; + *base += size; + pci_write_config_dword(d, PCI_BASE_ADDRESS_0 + (pos << 2), res->start); + } + /* Fix up PCI bridge BAR0 only */ + if (d->bus->number == 0 && PCI_SLOT(d->devfn) == 0) + break; + } + /* Fix up interrupt lines */ + d->irq = ssb_mips_irq(extpci_core->dev) + 2; + pci_write_config_byte(d, PCI_INTERRUPT_LINE, d->irq); + + return 0; +} + +static void __init ssb_fixup_pcibridge(struct pci_dev *dev) +{ + if (dev->bus->number != 0 || PCI_SLOT(dev->devfn) != 0) + return; + + ssb_printk(KERN_INFO "PCI: fixing up bridge\n"); + + /* Enable PCI bridge bus mastering and memory space */ + pci_set_master(dev); + pcibios_enable_device(dev, ~0); + + /* Enable PCI bridge BAR1 prefetch and burst */ + pci_write_config_dword(dev, SSB_BAR1_CONTROL, 3); + + /* Make sure our latency is high enough to handle the devices behind us */ + pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0xa8); +} +DECLARE_PCI_FIXUP_EARLY(PCI_ANY_ID, PCI_ANY_ID, ssb_fixup_pcibridge); + +int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) +{ + return ssb_mips_irq(extpci_core->dev) + 2; +} + +static u32 get_cfgspace_addr(struct ssb_pcicore *pc, + unsigned int bus, unsigned int dev, + unsigned int func, unsigned int off) +{ + u32 addr = 0; + u32 tmp; + + if (unlikely(pc->cardbusmode && dev > 1)) + goto out; + if (bus == 0) { + /* Type 0 transaction */ + if (unlikely(dev >= SSB_PCI_SLOT_MAX)) + goto out; + /* Slide the window */ + tmp = SSB_PCICORE_SBTOPCI_CFG0; + tmp |= ((1 << (dev + 16)) & SSB_PCICORE_SBTOPCI1_MASK); + pcicore_write32(pc, SSB_PCICORE_SBTOPCI1, tmp); + /* Calculate the address */ + addr = SSB_PCI_CFG; + addr |= ((1 << (dev + 16)) & ~SSB_PCICORE_SBTOPCI1_MASK); + addr |= (func << 8); + addr |= (off & ~3); + } else { + /* Type 1 transaction */ + pcicore_write32(pc, SSB_PCICORE_SBTOPCI1, + SSB_PCICORE_SBTOPCI_CFG1); + /* Calculate the address */ + addr = SSB_PCI_CFG; + addr |= (bus << 16); + addr |= (dev << 11); + addr |= (func << 8); + addr |= (off & ~3); + } +out: + return addr; +} + +static int ssb_extpci_read_config(struct ssb_pcicore *pc, + unsigned int bus, unsigned int dev, + unsigned int func, unsigned int off, + void *buf, int len) +{ + int err = -EINVAL; + u32 addr, val; + void __iomem *mmio; + + SSB_WARN_ON(!pc->hostmode); + if (unlikely(len != 1 && len != 2 && len != 4)) + goto out; + addr = get_cfgspace_addr(pc, bus, dev, func, off); + if (unlikely(!addr)) + goto out; + err = -ENOMEM; + mmio = ioremap_nocache(addr, len); + if (!mmio) + goto out; + + if (mips_busprobe32(val, mmio)) { + val = 0xffffffff; + goto unmap; + } + + val = readl(mmio); + val >>= (8 * (off & 3)); + + switch (len) { + case 1: + *((u8 *)buf) = (u8)val; + break; + case 2: + *((u16 *)buf) = (u16)val; + break; + case 4: + *((u32 *)buf) = (u32)val; + break; + } + err = 0; +unmap: + iounmap(mmio); +out: + return err; +} + +static int ssb_extpci_write_config(struct ssb_pcicore *pc, + unsigned int bus, unsigned int dev, + unsigned int func, unsigned int off, + const void *buf, int len) +{ + int err = -EINVAL; + u32 addr, val = 0; + void __iomem *mmio; + + SSB_WARN_ON(!pc->hostmode); + if (unlikely(len != 1 && len != 2 && len != 4)) + goto out; + addr = get_cfgspace_addr(pc, bus, dev, func, off); + if (unlikely(!addr)) + goto out; + err = -ENOMEM; + mmio = ioremap_nocache(addr, len); + if (!mmio) + goto out; + + if (mips_busprobe32(val, mmio)) { + val = 0xffffffff; + goto unmap; + } + + switch (len) { + case 1: + val = readl(mmio); + val &= ~(0xFF << (8 * (off & 3))); + val |= *((const u8 *)buf) << (8 * (off & 3)); + break; + case 2: + val = readl(mmio); + val &= ~(0xFFFF << (8 * (off & 3))); + val |= *((const u16 *)buf) << (8 * (off & 3)); + break; + case 4: + val = *((const u32 *)buf); + break; + } + writel(val, mmio); + + err = 0; +unmap: + iounmap(mmio); +out: + return err; +} + +static int ssb_pcicore_read_config(struct pci_bus *bus, unsigned int devfn, + int reg, int size, u32 *val) +{ + unsigned long flags; + int err; + + spin_lock_irqsave(&cfgspace_lock, flags); + err = ssb_extpci_read_config(extpci_core, bus->number, PCI_SLOT(devfn), + PCI_FUNC(devfn), reg, val, size); + spin_unlock_irqrestore(&cfgspace_lock, flags); + + return err ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL; +} + +static int ssb_pcicore_write_config(struct pci_bus *bus, unsigned int devfn, + int reg, int size, u32 val) +{ + unsigned long flags; + int err; + + spin_lock_irqsave(&cfgspace_lock, flags); + err = ssb_extpci_write_config(extpci_core, bus->number, PCI_SLOT(devfn), + PCI_FUNC(devfn), reg, &val, size); + spin_unlock_irqrestore(&cfgspace_lock, flags); + + return err ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL; +} + +static struct pci_ops ssb_pcicore_pciops = { + .read = ssb_pcicore_read_config, + .write = ssb_pcicore_write_config, +}; + +static struct resource ssb_pcicore_mem_resource = { + .name = "SSB PCIcore external memory", + .start = SSB_PCI_DMA, + .end = SSB_PCI_DMA + SSB_PCI_DMA_SZ - 1, + .flags = IORESOURCE_MEM, +}; + +static struct resource ssb_pcicore_io_resource = { + .name = "SSB PCIcore external I/O", + .start = 0x100, + .end = 0x7FF, + .flags = IORESOURCE_IO, +}; + +static struct pci_controller ssb_pcicore_controller = { + .pci_ops = &ssb_pcicore_pciops, + .io_resource = &ssb_pcicore_io_resource, + .mem_resource = &ssb_pcicore_mem_resource, + .mem_offset = 0x24000000, +}; + +static void ssb_pcicore_init_hostmode(struct ssb_pcicore *pc) +{ + u32 val; + + if (WARN_ON(extpci_core)) + return; + extpci_core = pc; + + ssb_dprintk(KERN_INFO PFX "PCIcore in host mode found\n"); + /* Reset devices on the external PCI bus */ + val = SSB_PCICORE_CTL_RST_OE; + val |= SSB_PCICORE_CTL_CLK_OE; + pcicore_write32(pc, SSB_PCICORE_CTL, val); + val |= SSB_PCICORE_CTL_CLK; /* Clock on */ + pcicore_write32(pc, SSB_PCICORE_CTL, val); + udelay(150); /* Assertion time demanded by the PCI standard */ + val |= SSB_PCICORE_CTL_RST; /* Deassert RST# */ + pcicore_write32(pc, SSB_PCICORE_CTL, val); + val = SSB_PCICORE_ARBCTL_INTERN; + pcicore_write32(pc, SSB_PCICORE_ARBCTL, val); + udelay(1); /* Assertion time demanded by the PCI standard */ + + /*TODO cardbus mode */ + + /* 64MB I/O window */ + pcicore_write32(pc, SSB_PCICORE_SBTOPCI0, + SSB_PCICORE_SBTOPCI_IO); + /* 64MB config space */ + pcicore_write32(pc, SSB_PCICORE_SBTOPCI1, + SSB_PCICORE_SBTOPCI_CFG0); + /* 1GB memory window */ + pcicore_write32(pc, SSB_PCICORE_SBTOPCI2, + SSB_PCICORE_SBTOPCI_MEM | SSB_PCI_DMA); + + /* Enable PCI bridge BAR0 prefetch and burst */ + val = PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY; + ssb_extpci_write_config(pc, 0, 0, 0, PCI_COMMAND, &val, 2); + /* Clear error conditions */ + val = 0; + ssb_extpci_write_config(pc, 0, 0, 0, PCI_STATUS, &val, 2); + + /* Enable PCI interrupts */ + pcicore_write32(pc, SSB_PCICORE_IMASK, + SSB_PCICORE_IMASK_INTA); + + /* Ok, ready to run, register it to the system. + * The following needs change, if we want to port hostmode + * to non-MIPS platform. */ + set_io_port_base((unsigned long)ioremap_nocache(SSB_PCI_MEM, 0x04000000)); + /* Give some time to the PCI controller to configure itself with the new + * values. Not waiting at this point causes crashes of the machine. */ + mdelay(10); + register_pci_controller(&ssb_pcicore_controller); +} + +static int pcicore_is_in_hostmode(struct ssb_pcicore *pc) +{ + struct ssb_bus *bus = pc->dev->bus; + u16 chipid_top; + u32 tmp; + + chipid_top = (bus->chip_id & 0xFF00); + if (chipid_top != 0x4700 && + chipid_top != 0x5300) + return 0; + + if (bus->sprom.r1.boardflags_lo & SSB_PCICORE_BFL_NOPCI) + return 0; + + /* The 200-pin BCM4712 package does not bond out PCI. Even when + * PCI is bonded out, some boards may leave the pins floating. */ + if (bus->chip_id == 0x4712) { + if (bus->chip_package == SSB_CHIPPACK_BCM4712S) + return 0; + if (bus->chip_package == SSB_CHIPPACK_BCM4712M) + return 0; + } + if (bus->chip_id == 0x5350) + return 0; + + return !mips_busprobe32(tmp, (bus->mmio + (pc->dev->core_index * SSB_CORE_SIZE))); +} +#endif /* CONFIG_SSB_PCICORE_HOSTMODE */ + + +/************************************************** + * Generic and Clientmode operation code. + **************************************************/ + +static void ssb_pcicore_init_clientmode(struct ssb_pcicore *pc) +{ + /* Disable PCI interrupts. */ + ssb_write32(pc->dev, SSB_INTVEC, 0); +} + +void ssb_pcicore_init(struct ssb_pcicore *pc) +{ + struct ssb_device *dev = pc->dev; + struct ssb_bus *bus; + + if (!dev) + return; + bus = dev->bus; + if (!ssb_device_is_enabled(dev)) + ssb_device_enable(dev, 0); + +#ifdef CONFIG_SSB_PCICORE_HOSTMODE + pc->hostmode = pcicore_is_in_hostmode(pc); + if (pc->hostmode) + ssb_pcicore_init_hostmode(pc); +#endif /* CONFIG_SSB_PCICORE_HOSTMODE */ + if (!pc->hostmode) + ssb_pcicore_init_clientmode(pc); +} + +static u32 ssb_pcie_read(struct ssb_pcicore *pc, u32 address) +{ + pcicore_write32(pc, 0x130, address); + return pcicore_read32(pc, 0x134); +} + +static void ssb_pcie_write(struct ssb_pcicore *pc, u32 address, u32 data) +{ + pcicore_write32(pc, 0x130, address); + pcicore_write32(pc, 0x134, data); +} + +static void ssb_pcie_mdio_write(struct ssb_pcicore *pc, u8 device, + u8 address, u16 data) +{ + const u16 mdio_control = 0x128; + const u16 mdio_data = 0x12C; + u32 v; + int i; + + v = 0x80; /* Enable Preamble Sequence */ + v |= 0x2; /* MDIO Clock Divisor */ + pcicore_write32(pc, mdio_control, v); + + v = (1 << 30); /* Start of Transaction */ + v |= (1 << 28); /* Write Transaction */ + v |= (1 << 17); /* Turnaround */ + v |= (u32)device << 22; + v |= (u32)address << 18; + v |= data; + pcicore_write32(pc, mdio_data, v); + /* Wait for the device to complete the transaction */ + udelay(10); + for (i = 0; i < 10; i++) { + v = pcicore_read32(pc, mdio_control); + if (v & 0x100 /* Trans complete */) + break; + msleep(1); + } + pcicore_write32(pc, mdio_control, 0); +} + +static void ssb_broadcast_value(struct ssb_device *dev, + u32 address, u32 data) +{ + /* This is used for both, PCI and ChipCommon core, so be careful. */ + BUILD_BUG_ON(SSB_PCICORE_BCAST_ADDR != SSB_CHIPCO_BCAST_ADDR); + BUILD_BUG_ON(SSB_PCICORE_BCAST_DATA != SSB_CHIPCO_BCAST_DATA); + + ssb_write32(dev, SSB_PCICORE_BCAST_ADDR, address); + ssb_read32(dev, SSB_PCICORE_BCAST_ADDR); /* flush */ + ssb_write32(dev, SSB_PCICORE_BCAST_DATA, data); + ssb_read32(dev, SSB_PCICORE_BCAST_DATA); /* flush */ +} + +static void ssb_commit_settings(struct ssb_bus *bus) +{ + struct ssb_device *dev; + + dev = bus->chipco.dev ? bus->chipco.dev : bus->pcicore.dev; + if (WARN_ON(!dev)) + return; + /* This forces an update of the cached registers. */ + ssb_broadcast_value(dev, 0xFD8, 0); +} + +int ssb_pcicore_dev_irqvecs_enable(struct ssb_pcicore *pc, + struct ssb_device *dev) +{ + struct ssb_device *pdev = pc->dev; + struct ssb_bus *bus; + int err = 0; + u32 tmp; + + might_sleep(); + + if (!pdev) + goto out; + bus = pdev->bus; + + /* Enable interrupts for this device. */ + if (bus->host_pci && + ((pdev->id.revision >= 6) || (pdev->id.coreid == SSB_DEV_PCIE))) { + u32 coremask; + + /* Calculate the "coremask" for the device. */ + coremask = (1 << dev->core_index); + + err = pci_read_config_dword(bus->host_pci, SSB_PCI_IRQMASK, &tmp); + if (err) + goto out; + tmp |= coremask << 8; + err = pci_write_config_dword(bus->host_pci, SSB_PCI_IRQMASK, tmp); + if (err) + goto out; + } else { + u32 intvec; + + intvec = ssb_read32(pdev, SSB_INTVEC); + if ((bus->chip_id & 0xFF00) == 0x4400) { + /* Workaround: On the BCM44XX the BPFLAG routing + * bit is wrong. Use a hardcoded constant. */ + intvec |= 0x00000002; + } else { + tmp = ssb_read32(dev, SSB_TPSFLAG); + tmp &= SSB_TPSFLAG_BPFLAG; + intvec |= tmp; + } + ssb_write32(pdev, SSB_INTVEC, intvec); + } + + /* Setup PCIcore operation. */ + if (pc->setup_done) + goto out; + if (pdev->id.coreid == SSB_DEV_PCI) { + tmp = pcicore_read32(pc, SSB_PCICORE_SBTOPCI2); + tmp |= SSB_PCICORE_SBTOPCI_PREF; + tmp |= SSB_PCICORE_SBTOPCI_BURST; + pcicore_write32(pc, SSB_PCICORE_SBTOPCI2, tmp); + + if (pdev->id.revision < 5) { + tmp = ssb_read32(pdev, SSB_IMCFGLO); + tmp &= ~SSB_IMCFGLO_SERTO; + tmp |= 2; + tmp &= ~SSB_IMCFGLO_REQTO; + tmp |= 3 << SSB_IMCFGLO_REQTO_SHIFT; + ssb_write32(pdev, SSB_IMCFGLO, tmp); + ssb_commit_settings(bus); + } else if (pdev->id.revision >= 11) { + tmp = pcicore_read32(pc, SSB_PCICORE_SBTOPCI2); + tmp |= SSB_PCICORE_SBTOPCI_MRM; + pcicore_write32(pc, SSB_PCICORE_SBTOPCI2, tmp); + } + } else { + WARN_ON(pdev->id.coreid != SSB_DEV_PCIE); + //TODO: Better make defines for all these magic PCIE values. + if ((pdev->id.revision == 0) || (pdev->id.revision == 1)) { + /* TLP Workaround register. */ + tmp = ssb_pcie_read(pc, 0x4); + tmp |= 0x8; + ssb_pcie_write(pc, 0x4, tmp); + } + if (pdev->id.revision == 0) { + const u8 serdes_rx_device = 0x1F; + + ssb_pcie_mdio_write(pc, serdes_rx_device, + 2 /* Timer */, 0x8128); + ssb_pcie_mdio_write(pc, serdes_rx_device, + 6 /* CDR */, 0x0100); + ssb_pcie_mdio_write(pc, serdes_rx_device, + 7 /* CDR BW */, 0x1466); + } else if (pdev->id.revision == 1) { + /* DLLP Link Control register. */ + tmp = ssb_pcie_read(pc, 0x100); + tmp |= 0x40; + ssb_pcie_write(pc, 0x100, tmp); + } + } + pc->setup_done = 1; +out: + return err; +} +EXPORT_SYMBOL(ssb_pcicore_dev_irqvecs_enable); diff --git a/drivers/ssb/main.c b/drivers/ssb/main.c new file mode 100644 index 000000000000..74d5182db4b2 --- /dev/null +++ b/drivers/ssb/main.c @@ -0,0 +1,1162 @@ +/* + * Sonics Silicon Backplane + * Subsystem core + * + * Copyright 2005, Broadcom Corporation + * Copyright 2006, 2007, Michael Buesch + * + * Licensed under the GNU/GPL. See COPYING for details. + */ + +#include "ssb_private.h" + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + + +MODULE_DESCRIPTION("Sonics Silicon Backplane driver"); +MODULE_LICENSE("GPL"); + + +/* Temporary list of yet-to-be-attached buses */ +static LIST_HEAD(attach_queue); +/* List if running buses */ +static LIST_HEAD(buses); +/* Software ID counter */ +static unsigned int next_busnumber; +/* buses_mutes locks the two buslists and the next_busnumber. + * Don't lock this directly, but use ssb_buses_[un]lock() below. */ +static DEFINE_MUTEX(buses_mutex); + +/* There are differences in the codeflow, if the bus is + * initialized from early boot, as various needed services + * are not available early. This is a mechanism to delay + * these initializations to after early boot has finished. + * It's also used to avoid mutex locking, as that's not + * available and needed early. */ +static bool ssb_is_early_boot = 1; + +static void ssb_buses_lock(void); +static void ssb_buses_unlock(void); + + +#ifdef CONFIG_SSB_PCIHOST +struct ssb_bus *ssb_pci_dev_to_bus(struct pci_dev *pdev) +{ + struct ssb_bus *bus; + + ssb_buses_lock(); + list_for_each_entry(bus, &buses, list) { + if (bus->bustype == SSB_BUSTYPE_PCI && + bus->host_pci == pdev) + goto found; + } + bus = NULL; +found: + ssb_buses_unlock(); + + return bus; +} +#endif /* CONFIG_SSB_PCIHOST */ + +static struct ssb_device *ssb_device_get(struct ssb_device *dev) +{ + if (dev) + get_device(dev->dev); + return dev; +} + +static void ssb_device_put(struct ssb_device *dev) +{ + if (dev) + put_device(dev->dev); +} + +static int ssb_bus_resume(struct ssb_bus *bus) +{ + int err; + + ssb_pci_xtal(bus, SSB_GPIO_XTAL | SSB_GPIO_PLL, 1); + err = ssb_pcmcia_init(bus); + if (err) { + /* No need to disable XTAL, as we don't have one on PCMCIA. */ + return err; + } + ssb_chipco_resume(&bus->chipco); + + return 0; +} + +static int ssb_device_resume(struct device *dev) +{ + struct ssb_device *ssb_dev = dev_to_ssb_dev(dev); + struct ssb_driver *ssb_drv; + struct ssb_bus *bus; + int err = 0; + + bus = ssb_dev->bus; + if (bus->suspend_cnt == bus->nr_devices) { + err = ssb_bus_resume(bus); + if (err) + return err; + } + bus->suspend_cnt--; + if (dev->driver) { + ssb_drv = drv_to_ssb_drv(dev->driver); + if (ssb_drv && ssb_drv->resume) + err = ssb_drv->resume(ssb_dev); + if (err) + goto out; + } +out: + return err; +} + +static void ssb_bus_suspend(struct ssb_bus *bus, pm_message_t state) +{ + ssb_chipco_suspend(&bus->chipco, state); + ssb_pci_xtal(bus, SSB_GPIO_XTAL | SSB_GPIO_PLL, 0); + + /* Reset HW state information in memory, so that HW is + * completely reinitialized on resume. */ + bus->mapped_device = NULL; +#ifdef CONFIG_SSB_DRIVER_PCICORE + bus->pcicore.setup_done = 0; +#endif +#ifdef CONFIG_SSB_DEBUG + bus->powered_up = 0; +#endif +} + +static int ssb_device_suspend(struct device *dev, pm_message_t state) +{ + struct ssb_device *ssb_dev = dev_to_ssb_dev(dev); + struct ssb_driver *ssb_drv; + struct ssb_bus *bus; + int err = 0; + + if (dev->driver) { + ssb_drv = drv_to_ssb_drv(dev->driver); + if (ssb_drv && ssb_drv->suspend) + err = ssb_drv->suspend(ssb_dev, state); + if (err) + goto out; + } + + bus = ssb_dev->bus; + bus->suspend_cnt++; + if (bus->suspend_cnt == bus->nr_devices) { + /* All devices suspended. Shutdown the bus. */ + ssb_bus_suspend(bus, state); + } + +out: + return err; +} + +#ifdef CONFIG_SSB_PCIHOST +int ssb_devices_freeze(struct ssb_bus *bus) +{ + struct ssb_device *dev; + struct ssb_driver *drv; + int err = 0; + int i; + pm_message_t state = PMSG_FREEZE; + + /* First check that we are capable to freeze all devices. */ + for (i = 0; i < bus->nr_devices; i++) { + dev = &(bus->devices[i]); + if (!dev->dev || + !dev->dev->driver || + !device_is_registered(dev->dev)) + continue; + drv = drv_to_ssb_drv(dev->dev->driver); + if (!drv) + continue; + if (!drv->suspend) { + /* Nope, can't suspend this one. */ + return -EOPNOTSUPP; + } + } + /* Now suspend all devices */ + for (i = 0; i < bus->nr_devices; i++) { + dev = &(bus->devices[i]); + if (!dev->dev || + !dev->dev->driver || + !device_is_registered(dev->dev)) + continue; + drv = drv_to_ssb_drv(dev->dev->driver); + if (!drv) + continue; + err = drv->suspend(dev, state); + if (err) { + ssb_printk(KERN_ERR PFX "Failed to freeze device %s\n", + dev->dev->bus_id); + goto err_unwind; + } + } + + return 0; +err_unwind: + for (i--; i >= 0; i--) { + dev = &(bus->devices[i]); + if (!dev->dev || + !dev->dev->driver || + !device_is_registered(dev->dev)) + continue; + drv = drv_to_ssb_drv(dev->dev->driver); + if (!drv) + continue; + if (drv->resume) + drv->resume(dev); + } + return err; +} + +int ssb_devices_thaw(struct ssb_bus *bus) +{ + struct ssb_device *dev; + struct ssb_driver *drv; + int err; + int i; + + for (i = 0; i < bus->nr_devices; i++) { + dev = &(bus->devices[i]); + if (!dev->dev || + !dev->dev->driver || + !device_is_registered(dev->dev)) + continue; + drv = drv_to_ssb_drv(dev->dev->driver); + if (!drv) + continue; + if (SSB_WARN_ON(!drv->resume)) + continue; + err = drv->resume(dev); + if (err) { + ssb_printk(KERN_ERR PFX "Failed to thaw device %s\n", + dev->dev->bus_id); + } + } + + return 0; +} +#endif /* CONFIG_SSB_PCIHOST */ + +static void ssb_device_shutdown(struct device *dev) +{ + struct ssb_device *ssb_dev = dev_to_ssb_dev(dev); + struct ssb_driver *ssb_drv; + + if (!dev->driver) + return; + ssb_drv = drv_to_ssb_drv(dev->driver); + if (ssb_drv && ssb_drv->shutdown) + ssb_drv->shutdown(ssb_dev); +} + +static int ssb_device_remove(struct device *dev) +{ + struct ssb_device *ssb_dev = dev_to_ssb_dev(dev); + struct ssb_driver *ssb_drv = drv_to_ssb_drv(dev->driver); + + if (ssb_drv && ssb_drv->remove) + ssb_drv->remove(ssb_dev); + ssb_device_put(ssb_dev); + + return 0; +} + +static int ssb_device_probe(struct device *dev) +{ + struct ssb_device *ssb_dev = dev_to_ssb_dev(dev); + struct ssb_driver *ssb_drv = drv_to_ssb_drv(dev->driver); + int err = 0; + + ssb_device_get(ssb_dev); + if (ssb_drv && ssb_drv->probe) + err = ssb_drv->probe(ssb_dev, &ssb_dev->id); + if (err) + ssb_device_put(ssb_dev); + + return err; +} + +static int ssb_match_devid(const struct ssb_device_id *tabid, + const struct ssb_device_id *devid) +{ + if ((tabid->vendor != devid->vendor) && + tabid->vendor != SSB_ANY_VENDOR) + return 0; + if ((tabid->coreid != devid->coreid) && + tabid->coreid != SSB_ANY_ID) + return 0; + if ((tabid->revision != devid->revision) && + tabid->revision != SSB_ANY_REV) + return 0; + return 1; +} + +static int ssb_bus_match(struct device *dev, struct device_driver *drv) +{ + struct ssb_device *ssb_dev = dev_to_ssb_dev(dev); + struct ssb_driver *ssb_drv = drv_to_ssb_drv(drv); + const struct ssb_device_id *id; + + for (id = ssb_drv->id_table; + id->vendor || id->coreid || id->revision; + id++) { + if (ssb_match_devid(id, &ssb_dev->id)) + return 1; /* found */ + } + + return 0; +} + +static int ssb_device_uevent(struct device *dev, char **envp, int num_envp, + char *buffer, int buffer_size) +{ + struct ssb_device *ssb_dev = dev_to_ssb_dev(dev); + int ret, i = 0, length = 0; + + if (!dev) + return -ENODEV; + + ret = add_uevent_var(envp, num_envp, &i, + buffer, buffer_size, &length, + "MODALIAS=ssb:v%04Xid%04Xrev%02X", + ssb_dev->id.vendor, ssb_dev->id.coreid, + ssb_dev->id.revision); + envp[i] = NULL; + + return ret; +} + +static struct bus_type ssb_bustype = { + .name = "ssb", + .match = ssb_bus_match, + .probe = ssb_device_probe, + .remove = ssb_device_remove, + .shutdown = ssb_device_shutdown, + .suspend = ssb_device_suspend, + .resume = ssb_device_resume, + .uevent = ssb_device_uevent, +}; + +static void ssb_buses_lock(void) +{ + /* See the comment at the ssb_is_early_boot definition */ + if (!ssb_is_early_boot) + mutex_lock(&buses_mutex); +} + +static void ssb_buses_unlock(void) +{ + /* See the comment at the ssb_is_early_boot definition */ + if (!ssb_is_early_boot) + mutex_unlock(&buses_mutex); +} + +static void ssb_devices_unregister(struct ssb_bus *bus) +{ + struct ssb_device *sdev; + int i; + + for (i = bus->nr_devices - 1; i >= 0; i--) { + sdev = &(bus->devices[i]); + if (sdev->dev) + device_unregister(sdev->dev); + } +} + +void ssb_bus_unregister(struct ssb_bus *bus) +{ + ssb_buses_lock(); + ssb_devices_unregister(bus); + list_del(&bus->list); + ssb_buses_unlock(); + + /* ssb_pcmcia_exit(bus); */ + ssb_pci_exit(bus); + ssb_iounmap(bus); +} +EXPORT_SYMBOL(ssb_bus_unregister); + +static void ssb_release_dev(struct device *dev) +{ + struct __ssb_dev_wrapper *devwrap; + + devwrap = container_of(dev, struct __ssb_dev_wrapper, dev); + kfree(devwrap); +} + +static int ssb_devices_register(struct ssb_bus *bus) +{ + struct ssb_device *sdev; + struct device *dev; + struct __ssb_dev_wrapper *devwrap; + int i, err = 0; + int dev_idx = 0; + + for (i = 0; i < bus->nr_devices; i++) { + sdev = &(bus->devices[i]); + + /* We don't register SSB-system devices to the kernel, + * as the drivers for them are built into SSB. */ + switch (sdev->id.coreid) { + case SSB_DEV_CHIPCOMMON: + case SSB_DEV_PCI: + case SSB_DEV_PCIE: + case SSB_DEV_PCMCIA: + case SSB_DEV_MIPS: + case SSB_DEV_MIPS_3302: + case SSB_DEV_EXTIF: + continue; + } + + devwrap = kzalloc(sizeof(*devwrap), GFP_KERNEL); + if (!devwrap) { + ssb_printk(KERN_ERR PFX + "Could not allocate device\n"); + err = -ENOMEM; + goto error; + } + dev = &devwrap->dev; + devwrap->sdev = sdev; + + dev->release = ssb_release_dev; + dev->bus = &ssb_bustype; + snprintf(dev->bus_id, sizeof(dev->bus_id), + "ssb%u:%d", bus->busnumber, dev_idx); + + switch (bus->bustype) { + case SSB_BUSTYPE_PCI: +#ifdef CONFIG_SSB_PCIHOST + sdev->irq = bus->host_pci->irq; + dev->parent = &bus->host_pci->dev; +#endif + break; + case SSB_BUSTYPE_PCMCIA: +#ifdef CONFIG_SSB_PCMCIAHOST + dev->parent = &bus->host_pcmcia->dev; +#endif + break; + case SSB_BUSTYPE_SSB: + break; + } + + sdev->dev = dev; + err = device_register(dev); + if (err) { + ssb_printk(KERN_ERR PFX + "Could not register %s\n", + dev->bus_id); + /* Set dev to NULL to not unregister + * dev on error unwinding. */ + sdev->dev = NULL; + kfree(devwrap); + goto error; + } + dev_idx++; + } + + return 0; +error: + /* Unwind the already registered devices. */ + ssb_devices_unregister(bus); + return err; +} + +/* Needs ssb_buses_lock() */ +static int ssb_attach_queued_buses(void) +{ + struct ssb_bus *bus, *n; + int err = 0; + int drop_them_all = 0; + + list_for_each_entry_safe(bus, n, &attach_queue, list) { + if (drop_them_all) { + list_del(&bus->list); + continue; + } + /* Can't init the PCIcore in ssb_bus_register(), as that + * is too early in boot for embedded systems + * (no udelay() available). So do it here in attach stage. + */ + err = ssb_bus_powerup(bus, 0); + if (err) + goto error; + ssb_pcicore_init(&bus->pcicore); + ssb_bus_may_powerdown(bus); + + err = ssb_devices_register(bus); +error: + if (err) { + drop_them_all = 1; + list_del(&bus->list); + continue; + } + list_move_tail(&bus->list, &buses); + } + + return err; +} + +static u16 ssb_ssb_read16(struct ssb_device *dev, u16 offset) +{ + struct ssb_bus *bus = dev->bus; + + offset += dev->core_index * SSB_CORE_SIZE; + return readw(bus->mmio + offset); +} + +static u32 ssb_ssb_read32(struct ssb_device *dev, u16 offset) +{ + struct ssb_bus *bus = dev->bus; + + offset += dev->core_index * SSB_CORE_SIZE; + return readl(bus->mmio + offset); +} + +static void ssb_ssb_write16(struct ssb_device *dev, u16 offset, u16 value) +{ + struct ssb_bus *bus = dev->bus; + + offset += dev->core_index * SSB_CORE_SIZE; + writew(value, bus->mmio + offset); +} + +static void ssb_ssb_write32(struct ssb_device *dev, u16 offset, u32 value) +{ + struct ssb_bus *bus = dev->bus; + + offset += dev->core_index * SSB_CORE_SIZE; + writel(value, bus->mmio + offset); +} + +/* Ops for the plain SSB bus without a host-device (no PCI or PCMCIA). */ +static const struct ssb_bus_ops ssb_ssb_ops = { + .read16 = ssb_ssb_read16, + .read32 = ssb_ssb_read32, + .write16 = ssb_ssb_write16, + .write32 = ssb_ssb_write32, +}; + +static int ssb_fetch_invariants(struct ssb_bus *bus, + ssb_invariants_func_t get_invariants) +{ + struct ssb_init_invariants iv; + int err; + + memset(&iv, 0, sizeof(iv)); + err = get_invariants(bus, &iv); + if (err) + goto out; + memcpy(&bus->boardinfo, &iv.boardinfo, sizeof(iv.boardinfo)); + memcpy(&bus->sprom, &iv.sprom, sizeof(iv.sprom)); +out: + return err; +} + +static int ssb_bus_register(struct ssb_bus *bus, + ssb_invariants_func_t get_invariants, + unsigned long baseaddr) +{ + int err; + + spin_lock_init(&bus->bar_lock); + INIT_LIST_HEAD(&bus->list); + + /* Powerup the bus */ + err = ssb_pci_xtal(bus, SSB_GPIO_XTAL | SSB_GPIO_PLL, 1); + if (err) + goto out; + ssb_buses_lock(); + bus->busnumber = next_busnumber; + /* Scan for devices (cores) */ + err = ssb_bus_scan(bus, baseaddr); + if (err) + goto err_disable_xtal; + + /* Init PCI-host device (if any) */ + err = ssb_pci_init(bus); + if (err) + goto err_unmap; + /* Init PCMCIA-host device (if any) */ + err = ssb_pcmcia_init(bus); + if (err) + goto err_pci_exit; + + /* Initialize basic system devices (if available) */ + err = ssb_bus_powerup(bus, 0); + if (err) + goto err_pcmcia_exit; + ssb_chipcommon_init(&bus->chipco); + ssb_mipscore_init(&bus->mipscore); + err = ssb_fetch_invariants(bus, get_invariants); + if (err) { + ssb_bus_may_powerdown(bus); + goto err_pcmcia_exit; + } + ssb_bus_may_powerdown(bus); + + /* Queue it for attach. + * See the comment at the ssb_is_early_boot definition. */ + list_add_tail(&bus->list, &attach_queue); + if (!ssb_is_early_boot) { + /* This is not early boot, so we must attach the bus now */ + err = ssb_attach_queued_buses(); + if (err) + goto err_dequeue; + } + next_busnumber++; + ssb_buses_unlock(); + +out: + return err; + +err_dequeue: + list_del(&bus->list); +err_pcmcia_exit: +/* ssb_pcmcia_exit(bus); */ +err_pci_exit: + ssb_pci_exit(bus); +err_unmap: + ssb_iounmap(bus); +err_disable_xtal: + ssb_buses_unlock(); + ssb_pci_xtal(bus, SSB_GPIO_XTAL | SSB_GPIO_PLL, 0); + return err; +} + +#ifdef CONFIG_SSB_PCIHOST +int ssb_bus_pcibus_register(struct ssb_bus *bus, + struct pci_dev *host_pci) +{ + int err; + + bus->bustype = SSB_BUSTYPE_PCI; + bus->host_pci = host_pci; + bus->ops = &ssb_pci_ops; + + err = ssb_bus_register(bus, ssb_pci_get_invariants, 0); + if (!err) { + ssb_printk(KERN_INFO PFX "Sonics Silicon Backplane found on " + "PCI device %s\n", host_pci->dev.bus_id); + } + + return err; +} +EXPORT_SYMBOL(ssb_bus_pcibus_register); +#endif /* CONFIG_SSB_PCIHOST */ + +#ifdef CONFIG_SSB_PCMCIAHOST +int ssb_bus_pcmciabus_register(struct ssb_bus *bus, + struct pcmcia_device *pcmcia_dev, + unsigned long baseaddr) +{ + int err; + + bus->bustype = SSB_BUSTYPE_PCMCIA; + bus->host_pcmcia = pcmcia_dev; + bus->ops = &ssb_pcmcia_ops; + + err = ssb_bus_register(bus, ssb_pcmcia_get_invariants, baseaddr); + if (!err) { + ssb_printk(KERN_INFO PFX "Sonics Silicon Backplane found on " + "PCMCIA device %s\n", pcmcia_dev->devname); + } + + return err; +} +EXPORT_SYMBOL(ssb_bus_pcmciabus_register); +#endif /* CONFIG_SSB_PCMCIAHOST */ + +int ssb_bus_ssbbus_register(struct ssb_bus *bus, + unsigned long baseaddr, + ssb_invariants_func_t get_invariants) +{ + int err; + + bus->bustype = SSB_BUSTYPE_SSB; + bus->ops = &ssb_ssb_ops; + + err = ssb_bus_register(bus, get_invariants, baseaddr); + if (!err) { + ssb_printk(KERN_INFO PFX "Sonics Silicon Backplane found at " + "address 0x%08lX\n", baseaddr); + } + + return err; +} + +int __ssb_driver_register(struct ssb_driver *drv, struct module *owner) +{ + drv->drv.name = drv->name; + drv->drv.bus = &ssb_bustype; + drv->drv.owner = owner; + + return driver_register(&drv->drv); +} +EXPORT_SYMBOL(__ssb_driver_register); + +void ssb_driver_unregister(struct ssb_driver *drv) +{ + driver_unregister(&drv->drv); +} +EXPORT_SYMBOL(ssb_driver_unregister); + +void ssb_set_devtypedata(struct ssb_device *dev, void *data) +{ + struct ssb_bus *bus = dev->bus; + struct ssb_device *ent; + int i; + + for (i = 0; i < bus->nr_devices; i++) { + ent = &(bus->devices[i]); + if (ent->id.vendor != dev->id.vendor) + continue; + if (ent->id.coreid != dev->id.coreid) + continue; + + ent->devtypedata = data; + } +} +EXPORT_SYMBOL(ssb_set_devtypedata); + +static u32 clkfactor_f6_resolve(u32 v) +{ + /* map the magic values */ + switch (v) { + case SSB_CHIPCO_CLK_F6_2: + return 2; + case SSB_CHIPCO_CLK_F6_3: + return 3; + case SSB_CHIPCO_CLK_F6_4: + return 4; + case SSB_CHIPCO_CLK_F6_5: + return 5; + case SSB_CHIPCO_CLK_F6_6: + return 6; + case SSB_CHIPCO_CLK_F6_7: + return 7; + } + return 0; +} + +/* Calculate the speed the backplane would run at a given set of clockcontrol values */ +u32 ssb_calc_clock_rate(u32 plltype, u32 n, u32 m) +{ + u32 n1, n2, clock, m1, m2, m3, mc; + + n1 = (n & SSB_CHIPCO_CLK_N1); + n2 = ((n & SSB_CHIPCO_CLK_N2) >> SSB_CHIPCO_CLK_N2_SHIFT); + + switch (plltype) { + case SSB_PLLTYPE_6: /* 100/200 or 120/240 only */ + if (m & SSB_CHIPCO_CLK_T6_MMASK) + return SSB_CHIPCO_CLK_T6_M0; + return SSB_CHIPCO_CLK_T6_M1; + case SSB_PLLTYPE_1: /* 48Mhz base, 3 dividers */ + case SSB_PLLTYPE_3: /* 25Mhz, 2 dividers */ + case SSB_PLLTYPE_4: /* 48Mhz, 4 dividers */ + case SSB_PLLTYPE_7: /* 25Mhz, 4 dividers */ + n1 = clkfactor_f6_resolve(n1); + n2 += SSB_CHIPCO_CLK_F5_BIAS; + break; + case SSB_PLLTYPE_2: /* 48Mhz, 4 dividers */ + n1 += SSB_CHIPCO_CLK_T2_BIAS; + n2 += SSB_CHIPCO_CLK_T2_BIAS; + SSB_WARN_ON(!((n1 >= 2) && (n1 <= 7))); + SSB_WARN_ON(!((n2 >= 5) && (n2 <= 23))); + break; + case SSB_PLLTYPE_5: /* 25Mhz, 4 dividers */ + return 100000000; + default: + SSB_WARN_ON(1); + } + + switch (plltype) { + case SSB_PLLTYPE_3: /* 25Mhz, 2 dividers */ + case SSB_PLLTYPE_7: /* 25Mhz, 4 dividers */ + clock = SSB_CHIPCO_CLK_BASE2 * n1 * n2; + break; + default: + clock = SSB_CHIPCO_CLK_BASE1 * n1 * n2; + } + if (!clock) + return 0; + + m1 = (m & SSB_CHIPCO_CLK_M1); + m2 = ((m & SSB_CHIPCO_CLK_M2) >> SSB_CHIPCO_CLK_M2_SHIFT); + m3 = ((m & SSB_CHIPCO_CLK_M3) >> SSB_CHIPCO_CLK_M3_SHIFT); + mc = ((m & SSB_CHIPCO_CLK_MC) >> SSB_CHIPCO_CLK_MC_SHIFT); + + switch (plltype) { + case SSB_PLLTYPE_1: /* 48Mhz base, 3 dividers */ + case SSB_PLLTYPE_3: /* 25Mhz, 2 dividers */ + case SSB_PLLTYPE_4: /* 48Mhz, 4 dividers */ + case SSB_PLLTYPE_7: /* 25Mhz, 4 dividers */ + m1 = clkfactor_f6_resolve(m1); + if ((plltype == SSB_PLLTYPE_1) || + (plltype == SSB_PLLTYPE_3)) + m2 += SSB_CHIPCO_CLK_F5_BIAS; + else + m2 = clkfactor_f6_resolve(m2); + m3 = clkfactor_f6_resolve(m3); + + switch (mc) { + case SSB_CHIPCO_CLK_MC_BYPASS: + return clock; + case SSB_CHIPCO_CLK_MC_M1: + return (clock / m1); + case SSB_CHIPCO_CLK_MC_M1M2: + return (clock / (m1 * m2)); + case SSB_CHIPCO_CLK_MC_M1M2M3: + return (clock / (m1 * m2 * m3)); + case SSB_CHIPCO_CLK_MC_M1M3: + return (clock / (m1 * m3)); + } + return 0; + case SSB_PLLTYPE_2: + m1 += SSB_CHIPCO_CLK_T2_BIAS; + m2 += SSB_CHIPCO_CLK_T2M2_BIAS; + m3 += SSB_CHIPCO_CLK_T2_BIAS; + SSB_WARN_ON(!((m1 >= 2) && (m1 <= 7))); + SSB_WARN_ON(!((m2 >= 3) && (m2 <= 10))); + SSB_WARN_ON(!((m3 >= 2) && (m3 <= 7))); + + if (!(mc & SSB_CHIPCO_CLK_T2MC_M1BYP)) + clock /= m1; + if (!(mc & SSB_CHIPCO_CLK_T2MC_M2BYP)) + clock /= m2; + if (!(mc & SSB_CHIPCO_CLK_T2MC_M3BYP)) + clock /= m3; + return clock; + default: + SSB_WARN_ON(1); + } + return 0; +} + +/* Get the current speed the backplane is running at */ +u32 ssb_clockspeed(struct ssb_bus *bus) +{ + u32 rate; + u32 plltype; + u32 clkctl_n, clkctl_m; + + if (ssb_extif_available(&bus->extif)) + ssb_extif_get_clockcontrol(&bus->extif, &plltype, + &clkctl_n, &clkctl_m); + else if (bus->chipco.dev) + ssb_chipco_get_clockcontrol(&bus->chipco, &plltype, + &clkctl_n, &clkctl_m); + else + return 0; + + if (bus->chip_id == 0x5365) { + rate = 100000000; + } else { + rate = ssb_calc_clock_rate(plltype, clkctl_n, clkctl_m); + if (plltype == SSB_PLLTYPE_3) /* 25Mhz, 2 dividers */ + rate /= 2; + } + + return rate; +} +EXPORT_SYMBOL(ssb_clockspeed); + +static u32 ssb_tmslow_reject_bitmask(struct ssb_device *dev) +{ + /* The REJECT bit changed position in TMSLOW between + * Backplane revisions. */ + switch (ssb_read32(dev, SSB_IDLOW) & SSB_IDLOW_SSBREV) { + case SSB_IDLOW_SSBREV_22: + return SSB_TMSLOW_REJECT_22; + case SSB_IDLOW_SSBREV_23: + return SSB_TMSLOW_REJECT_23; + default: + WARN_ON(1); + } + return (SSB_TMSLOW_REJECT_22 | SSB_TMSLOW_REJECT_23); +} + +int ssb_device_is_enabled(struct ssb_device *dev) +{ + u32 val; + u32 reject; + + reject = ssb_tmslow_reject_bitmask(dev); + val = ssb_read32(dev, SSB_TMSLOW); + val &= SSB_TMSLOW_CLOCK | SSB_TMSLOW_RESET | reject; + + return (val == SSB_TMSLOW_CLOCK); +} +EXPORT_SYMBOL(ssb_device_is_enabled); + +static void ssb_flush_tmslow(struct ssb_device *dev) +{ + /* Make _really_ sure the device has finished the TMSLOW + * register write transaction, as we risk running into + * a machine check exception otherwise. + * Do this by reading the register back to commit the + * PCI write and delay an additional usec for the device + * to react to the change. */ + ssb_read32(dev, SSB_TMSLOW); + udelay(1); +} + +void ssb_device_enable(struct ssb_device *dev, u32 core_specific_flags) +{ + u32 val; + + ssb_device_disable(dev, core_specific_flags); + ssb_write32(dev, SSB_TMSLOW, + SSB_TMSLOW_RESET | SSB_TMSLOW_CLOCK | + SSB_TMSLOW_FGC | core_specific_flags); + ssb_flush_tmslow(dev); + + /* Clear SERR if set. This is a hw bug workaround. */ + if (ssb_read32(dev, SSB_TMSHIGH) & SSB_TMSHIGH_SERR) + ssb_write32(dev, SSB_TMSHIGH, 0); + + val = ssb_read32(dev, SSB_IMSTATE); + if (val & (SSB_IMSTATE_IBE | SSB_IMSTATE_TO)) { + val &= ~(SSB_IMSTATE_IBE | SSB_IMSTATE_TO); + ssb_write32(dev, SSB_IMSTATE, val); + } + + ssb_write32(dev, SSB_TMSLOW, + SSB_TMSLOW_CLOCK | SSB_TMSLOW_FGC | + core_specific_flags); + ssb_flush_tmslow(dev); + + ssb_write32(dev, SSB_TMSLOW, SSB_TMSLOW_CLOCK | + core_specific_flags); + ssb_flush_tmslow(dev); +} +EXPORT_SYMBOL(ssb_device_enable); + +/* Wait for a bit in a register to get set or unset. + * timeout is in units of ten-microseconds */ +static int ssb_wait_bit(struct ssb_device *dev, u16 reg, u32 bitmask, + int timeout, int set) +{ + int i; + u32 val; + + for (i = 0; i < timeout; i++) { + val = ssb_read32(dev, reg); + if (set) { + if (val & bitmask) + return 0; + } else { + if (!(val & bitmask)) + return 0; + } + udelay(10); + } + printk(KERN_ERR PFX "Timeout waiting for bitmask %08X on " + "register %04X to %s.\n", + bitmask, reg, (set ? "set" : "clear")); + + return -ETIMEDOUT; +} + +void ssb_device_disable(struct ssb_device *dev, u32 core_specific_flags) +{ + u32 reject; + + if (ssb_read32(dev, SSB_TMSLOW) & SSB_TMSLOW_RESET) + return; + + reject = ssb_tmslow_reject_bitmask(dev); + ssb_write32(dev, SSB_TMSLOW, reject | SSB_TMSLOW_CLOCK); + ssb_wait_bit(dev, SSB_TMSLOW, reject, 1000, 1); + ssb_wait_bit(dev, SSB_TMSHIGH, SSB_TMSHIGH_BUSY, 1000, 0); + ssb_write32(dev, SSB_TMSLOW, + SSB_TMSLOW_FGC | SSB_TMSLOW_CLOCK | + reject | SSB_TMSLOW_RESET | + core_specific_flags); + ssb_flush_tmslow(dev); + + ssb_write32(dev, SSB_TMSLOW, + reject | SSB_TMSLOW_RESET | + core_specific_flags); + ssb_flush_tmslow(dev); +} +EXPORT_SYMBOL(ssb_device_disable); + +u32 ssb_dma_translation(struct ssb_device *dev) +{ + switch (dev->bus->bustype) { + case SSB_BUSTYPE_SSB: + return 0; + case SSB_BUSTYPE_PCI: + case SSB_BUSTYPE_PCMCIA: + return SSB_PCI_DMA; + } + return 0; +} +EXPORT_SYMBOL(ssb_dma_translation); + +int ssb_dma_set_mask(struct ssb_device *ssb_dev, u64 mask) +{ + struct device *dev = ssb_dev->dev; + +#ifdef CONFIG_SSB_PCIHOST + if (ssb_dev->bus->bustype == SSB_BUSTYPE_PCI && + !dma_supported(dev, mask)) + return -EIO; +#endif + dev->coherent_dma_mask = mask; + dev->dma_mask = &dev->coherent_dma_mask; + + return 0; +} +EXPORT_SYMBOL(ssb_dma_set_mask); + +int ssb_bus_may_powerdown(struct ssb_bus *bus) +{ + struct ssb_chipcommon *cc; + int err = 0; + + /* On buses where more than one core may be working + * at a time, we must not powerdown stuff if there are + * still cores that may want to run. */ + if (bus->bustype == SSB_BUSTYPE_SSB) + goto out; + + cc = &bus->chipco; + ssb_chipco_set_clockmode(cc, SSB_CLKMODE_SLOW); + err = ssb_pci_xtal(bus, SSB_GPIO_XTAL | SSB_GPIO_PLL, 0); + if (err) + goto error; +out: +#ifdef CONFIG_SSB_DEBUG + bus->powered_up = 0; +#endif + return err; +error: + ssb_printk(KERN_ERR PFX "Bus powerdown failed\n"); + goto out; +} +EXPORT_SYMBOL(ssb_bus_may_powerdown); + +int ssb_bus_powerup(struct ssb_bus *bus, bool dynamic_pctl) +{ + struct ssb_chipcommon *cc; + int err; + enum ssb_clkmode mode; + + err = ssb_pci_xtal(bus, SSB_GPIO_XTAL | SSB_GPIO_PLL, 1); + if (err) + goto error; + cc = &bus->chipco; + mode = dynamic_pctl ? SSB_CLKMODE_DYNAMIC : SSB_CLKMODE_FAST; + ssb_chipco_set_clockmode(cc, mode); + +#ifdef CONFIG_SSB_DEBUG + bus->powered_up = 1; +#endif + return 0; +error: + ssb_printk(KERN_ERR PFX "Bus powerup failed\n"); + return err; +} +EXPORT_SYMBOL(ssb_bus_powerup); + +u32 ssb_admatch_base(u32 adm) +{ + u32 base = 0; + + switch (adm & SSB_ADM_TYPE) { + case SSB_ADM_TYPE0: + base = (adm & SSB_ADM_BASE0); + break; + case SSB_ADM_TYPE1: + SSB_WARN_ON(adm & SSB_ADM_NEG); /* unsupported */ + base = (adm & SSB_ADM_BASE1); + break; + case SSB_ADM_TYPE2: + SSB_WARN_ON(adm & SSB_ADM_NEG); /* unsupported */ + base = (adm & SSB_ADM_BASE2); + break; + default: + SSB_WARN_ON(1); + } + + return base; +} +EXPORT_SYMBOL(ssb_admatch_base); + +u32 ssb_admatch_size(u32 adm) +{ + u32 size = 0; + + switch (adm & SSB_ADM_TYPE) { + case SSB_ADM_TYPE0: + size = ((adm & SSB_ADM_SZ0) >> SSB_ADM_SZ0_SHIFT); + break; + case SSB_ADM_TYPE1: + SSB_WARN_ON(adm & SSB_ADM_NEG); /* unsupported */ + size = ((adm & SSB_ADM_SZ1) >> SSB_ADM_SZ1_SHIFT); + break; + case SSB_ADM_TYPE2: + SSB_WARN_ON(adm & SSB_ADM_NEG); /* unsupported */ + size = ((adm & SSB_ADM_SZ2) >> SSB_ADM_SZ2_SHIFT); + break; + default: + SSB_WARN_ON(1); + } + size = (1 << (size + 1)); + + return size; +} +EXPORT_SYMBOL(ssb_admatch_size); + +static int __init ssb_modinit(void) +{ + int err; + + /* See the comment at the ssb_is_early_boot definition */ + ssb_is_early_boot = 0; + err = bus_register(&ssb_bustype); + if (err) + return err; + + /* Maybe we already registered some buses at early boot. + * Check for this and attach them + */ + ssb_buses_lock(); + err = ssb_attach_queued_buses(); + ssb_buses_unlock(); + if (err) + bus_unregister(&ssb_bustype); + + err = b43_pci_ssb_bridge_init(); + if (err) { + ssb_printk(KERN_ERR "Broadcom 43xx PCI-SSB-bridge " + "initialization failed"); + /* don't fail SSB init because of this */ + err = 0; + } + + return err; +} +subsys_initcall(ssb_modinit); + +static void __exit ssb_modexit(void) +{ + b43_pci_ssb_bridge_exit(); + bus_unregister(&ssb_bustype); +} +module_exit(ssb_modexit) diff --git a/drivers/ssb/pci.c b/drivers/ssb/pci.c new file mode 100644 index 000000000000..3d23ca4befe3 --- /dev/null +++ b/drivers/ssb/pci.c @@ -0,0 +1,740 @@ +/* + * Sonics Silicon Backplane PCI-Hostbus related functions. + * + * Copyright (C) 2005-2006 Michael Buesch + * Copyright (C) 2005 Martin Langer + * Copyright (C) 2005 Stefano Brivio + * Copyright (C) 2005 Danny van Dyk + * Copyright (C) 2005 Andreas Jaggi + * + * Derived from the Broadcom 4400 device driver. + * Copyright (C) 2002 David S. Miller (davem@redhat.com) + * Fixed by Pekka Pietikainen (pp@ee.oulu.fi) + * Copyright (C) 2006 Broadcom Corporation. + * + * Licensed under the GNU/GPL. See COPYING for details. + */ + +#include +#include +#include +#include + +#include "ssb_private.h" + + +/* Define the following to 1 to enable a printk on each coreswitch. */ +#define SSB_VERBOSE_PCICORESWITCH_DEBUG 0 + + +/* Lowlevel coreswitching */ +int ssb_pci_switch_coreidx(struct ssb_bus *bus, u8 coreidx) +{ + int err; + int attempts = 0; + u32 cur_core; + + while (1) { + err = pci_write_config_dword(bus->host_pci, SSB_BAR0_WIN, + (coreidx * SSB_CORE_SIZE) + + SSB_ENUM_BASE); + if (err) + goto error; + err = pci_read_config_dword(bus->host_pci, SSB_BAR0_WIN, + &cur_core); + if (err) + goto error; + cur_core = (cur_core - SSB_ENUM_BASE) + / SSB_CORE_SIZE; + if (cur_core == coreidx) + break; + + if (attempts++ > SSB_BAR0_MAX_RETRIES) + goto error; + udelay(10); + } + return 0; +error: + ssb_printk(KERN_ERR PFX "Failed to switch to core %u\n", coreidx); + return -ENODEV; +} + +int ssb_pci_switch_core(struct ssb_bus *bus, + struct ssb_device *dev) +{ + int err; + unsigned long flags; + +#if SSB_VERBOSE_PCICORESWITCH_DEBUG + ssb_printk(KERN_INFO PFX + "Switching to %s core, index %d\n", + ssb_core_name(dev->id.coreid), + dev->core_index); +#endif + + spin_lock_irqsave(&bus->bar_lock, flags); + err = ssb_pci_switch_coreidx(bus, dev->core_index); + if (!err) + bus->mapped_device = dev; + spin_unlock_irqrestore(&bus->bar_lock, flags); + + return err; +} + +/* Enable/disable the on board crystal oscillator and/or PLL. */ +int ssb_pci_xtal(struct ssb_bus *bus, u32 what, int turn_on) +{ + int err; + u32 in, out, outenable; + u16 pci_status; + + if (bus->bustype != SSB_BUSTYPE_PCI) + return 0; + + err = pci_read_config_dword(bus->host_pci, SSB_GPIO_IN, &in); + if (err) + goto err_pci; + err = pci_read_config_dword(bus->host_pci, SSB_GPIO_OUT, &out); + if (err) + goto err_pci; + err = pci_read_config_dword(bus->host_pci, SSB_GPIO_OUT_ENABLE, &outenable); + if (err) + goto err_pci; + + outenable |= what; + + if (turn_on) { + /* Avoid glitching the clock if GPRS is already using it. + * We can't actually read the state of the PLLPD so we infer it + * by the value of XTAL_PU which *is* readable via gpioin. + */ + if (!(in & SSB_GPIO_XTAL)) { + if (what & SSB_GPIO_XTAL) { + /* Turn the crystal on */ + out |= SSB_GPIO_XTAL; + if (what & SSB_GPIO_PLL) + out |= SSB_GPIO_PLL; + err = pci_write_config_dword(bus->host_pci, SSB_GPIO_OUT, out); + if (err) + goto err_pci; + err = pci_write_config_dword(bus->host_pci, SSB_GPIO_OUT_ENABLE, + outenable); + if (err) + goto err_pci; + msleep(1); + } + if (what & SSB_GPIO_PLL) { + /* Turn the PLL on */ + out &= ~SSB_GPIO_PLL; + err = pci_write_config_dword(bus->host_pci, SSB_GPIO_OUT, out); + if (err) + goto err_pci; + msleep(5); + } + } + + err = pci_read_config_word(bus->host_pci, PCI_STATUS, &pci_status); + if (err) + goto err_pci; + pci_status &= ~PCI_STATUS_SIG_TARGET_ABORT; + err = pci_write_config_word(bus->host_pci, PCI_STATUS, pci_status); + if (err) + goto err_pci; + } else { + if (what & SSB_GPIO_XTAL) { + /* Turn the crystal off */ + out &= ~SSB_GPIO_XTAL; + } + if (what & SSB_GPIO_PLL) { + /* Turn the PLL off */ + out |= SSB_GPIO_PLL; + } + err = pci_write_config_dword(bus->host_pci, SSB_GPIO_OUT, out); + if (err) + goto err_pci; + err = pci_write_config_dword(bus->host_pci, SSB_GPIO_OUT_ENABLE, outenable); + if (err) + goto err_pci; + } + +out: + return err; + +err_pci: + printk(KERN_ERR PFX "Error: ssb_pci_xtal() could not access PCI config space!\n"); + err = -EBUSY; + goto out; +} + +/* Get the word-offset for a SSB_SPROM_XXX define. */ +#define SPOFF(offset) (((offset) - SSB_SPROM_BASE) / sizeof(u16)) +/* Helper to extract some _offset, which is one of the SSB_SPROM_XXX defines. */ +#define SPEX(_outvar, _offset, _mask, _shift) \ + out->_outvar = ((in[SPOFF(_offset)] & (_mask)) >> (_shift)) + +static inline u8 ssb_crc8(u8 crc, u8 data) +{ + /* Polynomial: x^8 + x^7 + x^6 + x^4 + x^2 + 1 */ + static const u8 t[] = { + 0x00, 0xF7, 0xB9, 0x4E, 0x25, 0xD2, 0x9C, 0x6B, + 0x4A, 0xBD, 0xF3, 0x04, 0x6F, 0x98, 0xD6, 0x21, + 0x94, 0x63, 0x2D, 0xDA, 0xB1, 0x46, 0x08, 0xFF, + 0xDE, 0x29, 0x67, 0x90, 0xFB, 0x0C, 0x42, 0xB5, + 0x7F, 0x88, 0xC6, 0x31, 0x5A, 0xAD, 0xE3, 0x14, + 0x35, 0xC2, 0x8C, 0x7B, 0x10, 0xE7, 0xA9, 0x5E, + 0xEB, 0x1C, 0x52, 0xA5, 0xCE, 0x39, 0x77, 0x80, + 0xA1, 0x56, 0x18, 0xEF, 0x84, 0x73, 0x3D, 0xCA, + 0xFE, 0x09, 0x47, 0xB0, 0xDB, 0x2C, 0x62, 0x95, + 0xB4, 0x43, 0x0D, 0xFA, 0x91, 0x66, 0x28, 0xDF, + 0x6A, 0x9D, 0xD3, 0x24, 0x4F, 0xB8, 0xF6, 0x01, + 0x20, 0xD7, 0x99, 0x6E, 0x05, 0xF2, 0xBC, 0x4B, + 0x81, 0x76, 0x38, 0xCF, 0xA4, 0x53, 0x1D, 0xEA, + 0xCB, 0x3C, 0x72, 0x85, 0xEE, 0x19, 0x57, 0xA0, + 0x15, 0xE2, 0xAC, 0x5B, 0x30, 0xC7, 0x89, 0x7E, + 0x5F, 0xA8, 0xE6, 0x11, 0x7A, 0x8D, 0xC3, 0x34, + 0xAB, 0x5C, 0x12, 0xE5, 0x8E, 0x79, 0x37, 0xC0, + 0xE1, 0x16, 0x58, 0xAF, 0xC4, 0x33, 0x7D, 0x8A, + 0x3F, 0xC8, 0x86, 0x71, 0x1A, 0xED, 0xA3, 0x54, + 0x75, 0x82, 0xCC, 0x3B, 0x50, 0xA7, 0xE9, 0x1E, + 0xD4, 0x23, 0x6D, 0x9A, 0xF1, 0x06, 0x48, 0xBF, + 0x9E, 0x69, 0x27, 0xD0, 0xBB, 0x4C, 0x02, 0xF5, + 0x40, 0xB7, 0xF9, 0x0E, 0x65, 0x92, 0xDC, 0x2B, + 0x0A, 0xFD, 0xB3, 0x44, 0x2F, 0xD8, 0x96, 0x61, + 0x55, 0xA2, 0xEC, 0x1B, 0x70, 0x87, 0xC9, 0x3E, + 0x1F, 0xE8, 0xA6, 0x51, 0x3A, 0xCD, 0x83, 0x74, + 0xC1, 0x36, 0x78, 0x8F, 0xE4, 0x13, 0x5D, 0xAA, + 0x8B, 0x7C, 0x32, 0xC5, 0xAE, 0x59, 0x17, 0xE0, + 0x2A, 0xDD, 0x93, 0x64, 0x0F, 0xF8, 0xB6, 0x41, + 0x60, 0x97, 0xD9, 0x2E, 0x45, 0xB2, 0xFC, 0x0B, + 0xBE, 0x49, 0x07, 0xF0, 0x9B, 0x6C, 0x22, 0xD5, + 0xF4, 0x03, 0x4D, 0xBA, 0xD1, 0x26, 0x68, 0x9F, + }; + return t[crc ^ data]; +} + +static u8 ssb_sprom_crc(const u16 *sprom) +{ + int word; + u8 crc = 0xFF; + + for (word = 0; word < SSB_SPROMSIZE_WORDS - 1; word++) { + crc = ssb_crc8(crc, sprom[word] & 0x00FF); + crc = ssb_crc8(crc, (sprom[word] & 0xFF00) >> 8); + } + crc = ssb_crc8(crc, sprom[SPOFF(SSB_SPROM_REVISION)] & 0x00FF); + crc ^= 0xFF; + + return crc; +} + +static int sprom_check_crc(const u16 *sprom) +{ + u8 crc; + u8 expected_crc; + u16 tmp; + + crc = ssb_sprom_crc(sprom); + tmp = sprom[SPOFF(SSB_SPROM_REVISION)] & SSB_SPROM_REVISION_CRC; + expected_crc = tmp >> SSB_SPROM_REVISION_CRC_SHIFT; + if (crc != expected_crc) + return -EPROTO; + + return 0; +} + +static void sprom_do_read(struct ssb_bus *bus, u16 *sprom) +{ + int i; + + for (i = 0; i < SSB_SPROMSIZE_WORDS; i++) + sprom[i] = readw(bus->mmio + SSB_SPROM_BASE + (i * 2)); +} + +static int sprom_do_write(struct ssb_bus *bus, const u16 *sprom) +{ + struct pci_dev *pdev = bus->host_pci; + int i, err; + u32 spromctl; + + ssb_printk(KERN_NOTICE PFX "Writing SPROM. Do NOT turn off the power! Please stand by...\n"); + err = pci_read_config_dword(pdev, SSB_SPROMCTL, &spromctl); + if (err) + goto err_ctlreg; + spromctl |= SSB_SPROMCTL_WE; + err = pci_write_config_dword(pdev, SSB_SPROMCTL, spromctl); + if (err) + goto err_ctlreg; + ssb_printk(KERN_NOTICE PFX "[ 0%%"); + msleep(500); + for (i = 0; i < SSB_SPROMSIZE_WORDS; i++) { + if (i == SSB_SPROMSIZE_WORDS / 4) + ssb_printk("25%%"); + else if (i == SSB_SPROMSIZE_WORDS / 2) + ssb_printk("50%%"); + else if (i == (SSB_SPROMSIZE_WORDS / 4) * 3) + ssb_printk("75%%"); + else if (i % 2) + ssb_printk("."); + writew(sprom[i], bus->mmio + SSB_SPROM_BASE + (i * 2)); + mmiowb(); + msleep(20); + } + err = pci_read_config_dword(pdev, SSB_SPROMCTL, &spromctl); + if (err) + goto err_ctlreg; + spromctl &= ~SSB_SPROMCTL_WE; + err = pci_write_config_dword(pdev, SSB_SPROMCTL, spromctl); + if (err) + goto err_ctlreg; + msleep(500); + ssb_printk("100%% ]\n"); + ssb_printk(KERN_NOTICE PFX "SPROM written.\n"); + + return 0; +err_ctlreg: + ssb_printk(KERN_ERR PFX "Could not access SPROM control register.\n"); + return err; +} + +static void sprom_extract_r1(struct ssb_sprom_r1 *out, const u16 *in) +{ + int i; + u16 v; + + SPEX(pci_spid, SSB_SPROM1_SPID, 0xFFFF, 0); + SPEX(pci_svid, SSB_SPROM1_SVID, 0xFFFF, 0); + SPEX(pci_pid, SSB_SPROM1_PID, 0xFFFF, 0); + for (i = 0; i < 3; i++) { + v = in[SPOFF(SSB_SPROM1_IL0MAC) + i]; + *(((u16 *)out->il0mac) + i) = cpu_to_be16(v); + } + for (i = 0; i < 3; i++) { + v = in[SPOFF(SSB_SPROM1_ET0MAC) + i]; + *(((u16 *)out->et0mac) + i) = cpu_to_be16(v); + } + for (i = 0; i < 3; i++) { + v = in[SPOFF(SSB_SPROM1_ET1MAC) + i]; + *(((u16 *)out->et1mac) + i) = cpu_to_be16(v); + } + SPEX(et0phyaddr, SSB_SPROM1_ETHPHY, SSB_SPROM1_ETHPHY_ET0A, 0); + SPEX(et1phyaddr, SSB_SPROM1_ETHPHY, SSB_SPROM1_ETHPHY_ET1A, + SSB_SPROM1_ETHPHY_ET1A_SHIFT); + SPEX(et0mdcport, SSB_SPROM1_ETHPHY, SSB_SPROM1_ETHPHY_ET0M, 14); + SPEX(et1mdcport, SSB_SPROM1_ETHPHY, SSB_SPROM1_ETHPHY_ET1M, 15); + SPEX(board_rev, SSB_SPROM1_BINF, SSB_SPROM1_BINF_BREV, 0); + SPEX(country_code, SSB_SPROM1_BINF, SSB_SPROM1_BINF_CCODE, + SSB_SPROM1_BINF_CCODE_SHIFT); + SPEX(antenna_a, SSB_SPROM1_BINF, SSB_SPROM1_BINF_ANTA, + SSB_SPROM1_BINF_ANTA_SHIFT); + SPEX(antenna_bg, SSB_SPROM1_BINF, SSB_SPROM1_BINF_ANTBG, + SSB_SPROM1_BINF_ANTBG_SHIFT); + SPEX(pa0b0, SSB_SPROM1_PA0B0, 0xFFFF, 0); + SPEX(pa0b1, SSB_SPROM1_PA0B1, 0xFFFF, 0); + SPEX(pa0b2, SSB_SPROM1_PA0B2, 0xFFFF, 0); + SPEX(pa1b0, SSB_SPROM1_PA1B0, 0xFFFF, 0); + SPEX(pa1b1, SSB_SPROM1_PA1B1, 0xFFFF, 0); + SPEX(pa1b2, SSB_SPROM1_PA1B2, 0xFFFF, 0); + SPEX(gpio0, SSB_SPROM1_GPIOA, SSB_SPROM1_GPIOA_P0, 0); + SPEX(gpio1, SSB_SPROM1_GPIOA, SSB_SPROM1_GPIOA_P1, + SSB_SPROM1_GPIOA_P1_SHIFT); + SPEX(gpio2, SSB_SPROM1_GPIOB, SSB_SPROM1_GPIOB_P2, 0); + SPEX(gpio3, SSB_SPROM1_GPIOB, SSB_SPROM1_GPIOB_P3, + SSB_SPROM1_GPIOB_P3_SHIFT); + SPEX(maxpwr_a, SSB_SPROM1_MAXPWR, SSB_SPROM1_MAXPWR_A, + SSB_SPROM1_MAXPWR_A_SHIFT); + SPEX(maxpwr_bg, SSB_SPROM1_MAXPWR, SSB_SPROM1_MAXPWR_BG, 0); + SPEX(itssi_a, SSB_SPROM1_ITSSI, SSB_SPROM1_ITSSI_A, + SSB_SPROM1_ITSSI_A_SHIFT); + SPEX(itssi_bg, SSB_SPROM1_ITSSI, SSB_SPROM1_ITSSI_BG, 0); + SPEX(boardflags_lo, SSB_SPROM1_BFLLO, 0xFFFF, 0); + SPEX(antenna_gain_a, SSB_SPROM1_AGAIN, SSB_SPROM1_AGAIN_A, 0); + SPEX(antenna_gain_bg, SSB_SPROM1_AGAIN, SSB_SPROM1_AGAIN_BG, + SSB_SPROM1_AGAIN_BG_SHIFT); + for (i = 0; i < 4; i++) { + v = in[SPOFF(SSB_SPROM1_OEM) + i]; + *(((u16 *)out->oem) + i) = cpu_to_le16(v); + } +} + +static void sprom_extract_r2(struct ssb_sprom_r2 *out, const u16 *in) +{ + int i; + u16 v; + + SPEX(boardflags_hi, SSB_SPROM2_BFLHI, 0xFFFF, 0); + SPEX(maxpwr_a_hi, SSB_SPROM2_MAXP_A, SSB_SPROM2_MAXP_A_HI, 0); + SPEX(maxpwr_a_lo, SSB_SPROM2_MAXP_A, SSB_SPROM2_MAXP_A_LO, + SSB_SPROM2_MAXP_A_LO_SHIFT); + SPEX(pa1lob0, SSB_SPROM2_PA1LOB0, 0xFFFF, 0); + SPEX(pa1lob1, SSB_SPROM2_PA1LOB1, 0xFFFF, 0); + SPEX(pa1lob2, SSB_SPROM2_PA1LOB2, 0xFFFF, 0); + SPEX(pa1hib0, SSB_SPROM2_PA1HIB0, 0xFFFF, 0); + SPEX(pa1hib1, SSB_SPROM2_PA1HIB1, 0xFFFF, 0); + SPEX(pa1hib2, SSB_SPROM2_PA1HIB2, 0xFFFF, 0); + SPEX(ofdm_pwr_off, SSB_SPROM2_OPO, SSB_SPROM2_OPO_VALUE, 0); + for (i = 0; i < 4; i++) { + v = in[SPOFF(SSB_SPROM2_CCODE) + i]; + *(((u16 *)out->country_str) + i) = cpu_to_le16(v); + } +} + +static void sprom_extract_r3(struct ssb_sprom_r3 *out, const u16 *in) +{ + out->ofdmapo = (in[SPOFF(SSB_SPROM3_OFDMAPO) + 0] & 0xFF00) >> 8; + out->ofdmapo |= (in[SPOFF(SSB_SPROM3_OFDMAPO) + 0] & 0x00FF) << 8; + out->ofdmapo <<= 16; + out->ofdmapo |= (in[SPOFF(SSB_SPROM3_OFDMAPO) + 1] & 0xFF00) >> 8; + out->ofdmapo |= (in[SPOFF(SSB_SPROM3_OFDMAPO) + 1] & 0x00FF) << 8; + + out->ofdmalpo = (in[SPOFF(SSB_SPROM3_OFDMALPO) + 0] & 0xFF00) >> 8; + out->ofdmalpo |= (in[SPOFF(SSB_SPROM3_OFDMALPO) + 0] & 0x00FF) << 8; + out->ofdmalpo <<= 16; + out->ofdmalpo |= (in[SPOFF(SSB_SPROM3_OFDMALPO) + 1] & 0xFF00) >> 8; + out->ofdmalpo |= (in[SPOFF(SSB_SPROM3_OFDMALPO) + 1] & 0x00FF) << 8; + + out->ofdmahpo = (in[SPOFF(SSB_SPROM3_OFDMAHPO) + 0] & 0xFF00) >> 8; + out->ofdmahpo |= (in[SPOFF(SSB_SPROM3_OFDMAHPO) + 0] & 0x00FF) << 8; + out->ofdmahpo <<= 16; + out->ofdmahpo |= (in[SPOFF(SSB_SPROM3_OFDMAHPO) + 1] & 0xFF00) >> 8; + out->ofdmahpo |= (in[SPOFF(SSB_SPROM3_OFDMAHPO) + 1] & 0x00FF) << 8; + + SPEX(gpioldc_on_cnt, SSB_SPROM3_GPIOLDC, SSB_SPROM3_GPIOLDC_ON, + SSB_SPROM3_GPIOLDC_ON_SHIFT); + SPEX(gpioldc_off_cnt, SSB_SPROM3_GPIOLDC, SSB_SPROM3_GPIOLDC_OFF, + SSB_SPROM3_GPIOLDC_OFF_SHIFT); + SPEX(cckpo_1M, SSB_SPROM3_CCKPO, SSB_SPROM3_CCKPO_1M, 0); + SPEX(cckpo_2M, SSB_SPROM3_CCKPO, SSB_SPROM3_CCKPO_2M, + SSB_SPROM3_CCKPO_2M_SHIFT); + SPEX(cckpo_55M, SSB_SPROM3_CCKPO, SSB_SPROM3_CCKPO_55M, + SSB_SPROM3_CCKPO_55M_SHIFT); + SPEX(cckpo_11M, SSB_SPROM3_CCKPO, SSB_SPROM3_CCKPO_11M, + SSB_SPROM3_CCKPO_11M_SHIFT); + + out->ofdmgpo = (in[SPOFF(SSB_SPROM3_OFDMGPO) + 0] & 0xFF00) >> 8; + out->ofdmgpo |= (in[SPOFF(SSB_SPROM3_OFDMGPO) + 0] & 0x00FF) << 8; + out->ofdmgpo <<= 16; + out->ofdmgpo |= (in[SPOFF(SSB_SPROM3_OFDMGPO) + 1] & 0xFF00) >> 8; + out->ofdmgpo |= (in[SPOFF(SSB_SPROM3_OFDMGPO) + 1] & 0x00FF) << 8; +} + +static int sprom_extract(struct ssb_bus *bus, + struct ssb_sprom *out, const u16 *in) +{ + memset(out, 0, sizeof(*out)); + + SPEX(revision, SSB_SPROM_REVISION, SSB_SPROM_REVISION_REV, 0); + SPEX(crc, SSB_SPROM_REVISION, SSB_SPROM_REVISION_CRC, + SSB_SPROM_REVISION_CRC_SHIFT); + + if ((bus->chip_id & 0xFF00) == 0x4400) { + /* Workaround: The BCM44XX chip has a stupid revision + * number stored in the SPROM. + * Always extract r1. */ + sprom_extract_r1(&out->r1, in); + } else { + if (out->revision == 0) + goto unsupported; + if (out->revision >= 1 && out->revision <= 3) + sprom_extract_r1(&out->r1, in); + if (out->revision >= 2 && out->revision <= 3) + sprom_extract_r2(&out->r2, in); + if (out->revision == 3) + sprom_extract_r3(&out->r3, in); + if (out->revision >= 4) + goto unsupported; + } + + return 0; +unsupported: + ssb_printk(KERN_WARNING PFX "Unsupported SPROM revision %d " + "detected. Will extract v1\n", out->revision); + sprom_extract_r1(&out->r1, in); + return 0; +} + +static int ssb_pci_sprom_get(struct ssb_bus *bus, + struct ssb_sprom *sprom) +{ + int err = -ENOMEM; + u16 *buf; + + buf = kcalloc(SSB_SPROMSIZE_WORDS, sizeof(u16), GFP_KERNEL); + if (!buf) + goto out; + sprom_do_read(bus, buf); + err = sprom_check_crc(buf); + if (err) { + ssb_printk(KERN_WARNING PFX + "WARNING: Invalid SPROM CRC (corrupt SPROM)\n"); + } + err = sprom_extract(bus, sprom, buf); + + kfree(buf); +out: + return err; +} + +static void ssb_pci_get_boardinfo(struct ssb_bus *bus, + struct ssb_boardinfo *bi) +{ + pci_read_config_word(bus->host_pci, PCI_SUBSYSTEM_VENDOR_ID, + &bi->vendor); + pci_read_config_word(bus->host_pci, PCI_SUBSYSTEM_ID, + &bi->type); + pci_read_config_word(bus->host_pci, PCI_REVISION_ID, + &bi->rev); +} + +int ssb_pci_get_invariants(struct ssb_bus *bus, + struct ssb_init_invariants *iv) +{ + int err; + + err = ssb_pci_sprom_get(bus, &iv->sprom); + if (err) + goto out; + ssb_pci_get_boardinfo(bus, &iv->boardinfo); + +out: + return err; +} + +#ifdef CONFIG_SSB_DEBUG +static int ssb_pci_assert_buspower(struct ssb_bus *bus) +{ + if (likely(bus->powered_up)) + return 0; + + printk(KERN_ERR PFX "FATAL ERROR: Bus powered down " + "while accessing PCI MMIO space\n"); + if (bus->power_warn_count <= 10) { + bus->power_warn_count++; + dump_stack(); + } + + return -ENODEV; +} +#else /* DEBUG */ +static inline int ssb_pci_assert_buspower(struct ssb_bus *bus) +{ + return 0; +} +#endif /* DEBUG */ + +static u16 ssb_pci_read16(struct ssb_device *dev, u16 offset) +{ + struct ssb_bus *bus = dev->bus; + + if (unlikely(ssb_pci_assert_buspower(bus))) + return 0xFFFF; + if (unlikely(bus->mapped_device != dev)) { + if (unlikely(ssb_pci_switch_core(bus, dev))) + return 0xFFFF; + } + return readw(bus->mmio + offset); +} + +static u32 ssb_pci_read32(struct ssb_device *dev, u16 offset) +{ + struct ssb_bus *bus = dev->bus; + + if (unlikely(ssb_pci_assert_buspower(bus))) + return 0xFFFFFFFF; + if (unlikely(bus->mapped_device != dev)) { + if (unlikely(ssb_pci_switch_core(bus, dev))) + return 0xFFFFFFFF; + } + return readl(bus->mmio + offset); +} + +static void ssb_pci_write16(struct ssb_device *dev, u16 offset, u16 value) +{ + struct ssb_bus *bus = dev->bus; + + if (unlikely(ssb_pci_assert_buspower(bus))) + return; + if (unlikely(bus->mapped_device != dev)) { + if (unlikely(ssb_pci_switch_core(bus, dev))) + return; + } + writew(value, bus->mmio + offset); +} + +static void ssb_pci_write32(struct ssb_device *dev, u16 offset, u32 value) +{ + struct ssb_bus *bus = dev->bus; + + if (unlikely(ssb_pci_assert_buspower(bus))) + return; + if (unlikely(bus->mapped_device != dev)) { + if (unlikely(ssb_pci_switch_core(bus, dev))) + return; + } + writel(value, bus->mmio + offset); +} + +/* Not "static", as it's used in main.c */ +const struct ssb_bus_ops ssb_pci_ops = { + .read16 = ssb_pci_read16, + .read32 = ssb_pci_read32, + .write16 = ssb_pci_write16, + .write32 = ssb_pci_write32, +}; + +static int sprom2hex(const u16 *sprom, char *buf, size_t buf_len) +{ + int i, pos = 0; + + for (i = 0; i < SSB_SPROMSIZE_WORDS; i++) { + pos += snprintf(buf + pos, buf_len - pos - 1, + "%04X", swab16(sprom[i]) & 0xFFFF); + } + pos += snprintf(buf + pos, buf_len - pos - 1, "\n"); + + return pos + 1; +} + +static int hex2sprom(u16 *sprom, const char *dump, size_t len) +{ + char tmp[5] = { 0 }; + int cnt = 0; + unsigned long parsed; + + if (len < SSB_SPROMSIZE_BYTES * 2) + return -EINVAL; + + while (cnt < SSB_SPROMSIZE_WORDS) { + memcpy(tmp, dump, 4); + dump += 4; + parsed = simple_strtoul(tmp, NULL, 16); + sprom[cnt++] = swab16((u16)parsed); + } + + return 0; +} + +static ssize_t ssb_pci_attr_sprom_show(struct device *pcidev, + struct device_attribute *attr, + char *buf) +{ + struct pci_dev *pdev = container_of(pcidev, struct pci_dev, dev); + struct ssb_bus *bus; + u16 *sprom; + int err = -ENODEV; + ssize_t count = 0; + + bus = ssb_pci_dev_to_bus(pdev); + if (!bus) + goto out; + err = -ENOMEM; + sprom = kcalloc(SSB_SPROMSIZE_WORDS, sizeof(u16), GFP_KERNEL); + if (!sprom) + goto out; + + /* Use interruptible locking, as the SPROM write might + * be holding the lock for several seconds. So allow userspace + * to cancel operation. */ + err = -ERESTARTSYS; + if (mutex_lock_interruptible(&bus->pci_sprom_mutex)) + goto out_kfree; + sprom_do_read(bus, sprom); + mutex_unlock(&bus->pci_sprom_mutex); + + count = sprom2hex(sprom, buf, PAGE_SIZE); + err = 0; + +out_kfree: + kfree(sprom); +out: + return err ? err : count; +} + +static ssize_t ssb_pci_attr_sprom_store(struct device *pcidev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct pci_dev *pdev = container_of(pcidev, struct pci_dev, dev); + struct ssb_bus *bus; + u16 *sprom; + int res = 0, err = -ENODEV; + + bus = ssb_pci_dev_to_bus(pdev); + if (!bus) + goto out; + err = -ENOMEM; + sprom = kcalloc(SSB_SPROMSIZE_WORDS, sizeof(u16), GFP_KERNEL); + if (!sprom) + goto out; + err = hex2sprom(sprom, buf, count); + if (err) { + err = -EINVAL; + goto out_kfree; + } + err = sprom_check_crc(sprom); + if (err) { + err = -EINVAL; + goto out_kfree; + } + + /* Use interruptible locking, as the SPROM write might + * be holding the lock for several seconds. So allow userspace + * to cancel operation. */ + err = -ERESTARTSYS; + if (mutex_lock_interruptible(&bus->pci_sprom_mutex)) + goto out_kfree; + err = ssb_devices_freeze(bus); + if (err == -EOPNOTSUPP) { + ssb_printk(KERN_ERR PFX "SPROM write: Could not freeze devices. " + "No suspend support. Is CONFIG_PM enabled?\n"); + goto out_unlock; + } + if (err) { + ssb_printk(KERN_ERR PFX "SPROM write: Could not freeze all devices\n"); + goto out_unlock; + } + res = sprom_do_write(bus, sprom); + err = ssb_devices_thaw(bus); + if (err) + ssb_printk(KERN_ERR PFX "SPROM write: Could not thaw all devices\n"); +out_unlock: + mutex_unlock(&bus->pci_sprom_mutex); +out_kfree: + kfree(sprom); +out: + if (res) + return res; + return err ? err : count; +} + +static DEVICE_ATTR(ssb_sprom, 0600, + ssb_pci_attr_sprom_show, + ssb_pci_attr_sprom_store); + +void ssb_pci_exit(struct ssb_bus *bus) +{ + struct pci_dev *pdev; + + if (bus->bustype != SSB_BUSTYPE_PCI) + return; + + pdev = bus->host_pci; + device_remove_file(&pdev->dev, &dev_attr_ssb_sprom); +} + +int ssb_pci_init(struct ssb_bus *bus) +{ + struct pci_dev *pdev; + int err; + + if (bus->bustype != SSB_BUSTYPE_PCI) + return 0; + + pdev = bus->host_pci; + mutex_init(&bus->pci_sprom_mutex); + err = device_create_file(&pdev->dev, &dev_attr_ssb_sprom); + if (err) + goto out; + +out: + return err; +} diff --git a/drivers/ssb/pcihost_wrapper.c b/drivers/ssb/pcihost_wrapper.c new file mode 100644 index 000000000000..82a10abef640 --- /dev/null +++ b/drivers/ssb/pcihost_wrapper.c @@ -0,0 +1,104 @@ +/* + * Sonics Silicon Backplane + * PCI Hostdevice wrapper + * + * Copyright (c) 2005 Martin Langer + * Copyright (c) 2005 Stefano Brivio + * Copyright (c) 2005 Danny van Dyk + * Copyright (c) 2005 Andreas Jaggi + * Copyright (c) 2005-2007 Michael Buesch + * + * Licensed under the GNU/GPL. See COPYING for details. + */ + +#include +#include + + +#ifdef CONFIG_PM +static int ssb_pcihost_suspend(struct pci_dev *dev, pm_message_t state) +{ + pci_save_state(dev); + pci_disable_device(dev); + pci_set_power_state(dev, pci_choose_state(dev, state)); + + return 0; +} + +static int ssb_pcihost_resume(struct pci_dev *dev) +{ + int err; + + pci_set_power_state(dev, 0); + err = pci_enable_device(dev); + if (err) + return err; + pci_restore_state(dev); + + return 0; +} +#else /* CONFIG_PM */ +# define ssb_pcihost_suspend NULL +# define ssb_pcihost_resume NULL +#endif /* CONFIG_PM */ + +static int ssb_pcihost_probe(struct pci_dev *dev, + const struct pci_device_id *id) +{ + struct ssb_bus *ssb; + int err = -ENOMEM; + const char *name; + + ssb = kzalloc(sizeof(*ssb), GFP_KERNEL); + if (!ssb) + goto out; + err = pci_enable_device(dev); + if (err) + goto err_kfree_ssb; + name = dev->dev.bus_id; + if (dev->driver && dev->driver->name) + name = dev->driver->name; + err = pci_request_regions(dev, name); + if (err) + goto err_pci_disable; + pci_set_master(dev); + + err = ssb_bus_pcibus_register(ssb, dev); + if (err) + goto err_pci_release_regions; + + pci_set_drvdata(dev, ssb); + +out: + return err; + +err_pci_release_regions: + pci_release_regions(dev); +err_pci_disable: + pci_disable_device(dev); +err_kfree_ssb: + kfree(ssb); + return err; +} + +static void ssb_pcihost_remove(struct pci_dev *dev) +{ + struct ssb_bus *ssb = pci_get_drvdata(dev); + + ssb_bus_unregister(ssb); + pci_release_regions(dev); + pci_disable_device(dev); + kfree(ssb); + pci_set_drvdata(dev, NULL); +} + +int ssb_pcihost_register(struct pci_driver *driver) +{ + driver->probe = ssb_pcihost_probe; + driver->remove = ssb_pcihost_remove; + driver->suspend = ssb_pcihost_suspend; + driver->resume = ssb_pcihost_resume; + + return pci_register_driver(driver); +} +EXPORT_SYMBOL(ssb_pcihost_register); diff --git a/drivers/ssb/pcmcia.c b/drivers/ssb/pcmcia.c new file mode 100644 index 000000000000..7c773603b402 --- /dev/null +++ b/drivers/ssb/pcmcia.c @@ -0,0 +1,271 @@ +/* + * Sonics Silicon Backplane + * PCMCIA-Hostbus related functions + * + * Copyright 2006 Johannes Berg + * Copyright 2007 Michael Buesch + * + * Licensed under the GNU/GPL. See COPYING for details. + */ + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "ssb_private.h" + + +/* Define the following to 1 to enable a printk on each coreswitch. */ +#define SSB_VERBOSE_PCMCIACORESWITCH_DEBUG 0 + + +int ssb_pcmcia_switch_coreidx(struct ssb_bus *bus, + u8 coreidx) +{ + struct pcmcia_device *pdev = bus->host_pcmcia; + int err; + int attempts = 0; + u32 cur_core; + conf_reg_t reg; + u32 addr; + u32 read_addr; + + addr = (coreidx * SSB_CORE_SIZE) + SSB_ENUM_BASE; + while (1) { + reg.Action = CS_WRITE; + reg.Offset = 0x2E; + reg.Value = (addr & 0x0000F000) >> 12; + err = pcmcia_access_configuration_register(pdev, ®); + if (err != CS_SUCCESS) + goto error; + reg.Offset = 0x30; + reg.Value = (addr & 0x00FF0000) >> 16; + err = pcmcia_access_configuration_register(pdev, ®); + if (err != CS_SUCCESS) + goto error; + reg.Offset = 0x32; + reg.Value = (addr & 0xFF000000) >> 24; + err = pcmcia_access_configuration_register(pdev, ®); + if (err != CS_SUCCESS) + goto error; + + read_addr = 0; + + reg.Action = CS_READ; + reg.Offset = 0x2E; + err = pcmcia_access_configuration_register(pdev, ®); + if (err != CS_SUCCESS) + goto error; + read_addr |= (reg.Value & 0xF) << 12; + reg.Offset = 0x30; + err = pcmcia_access_configuration_register(pdev, ®); + if (err != CS_SUCCESS) + goto error; + read_addr |= reg.Value << 16; + reg.Offset = 0x32; + err = pcmcia_access_configuration_register(pdev, ®); + if (err != CS_SUCCESS) + goto error; + read_addr |= reg.Value << 24; + + cur_core = (read_addr - SSB_ENUM_BASE) / SSB_CORE_SIZE; + if (cur_core == coreidx) + break; + + if (attempts++ > SSB_BAR0_MAX_RETRIES) + goto error; + udelay(10); + } + + return 0; +error: + ssb_printk(KERN_ERR PFX "Failed to switch to core %u\n", coreidx); + return -ENODEV; +} + +int ssb_pcmcia_switch_core(struct ssb_bus *bus, + struct ssb_device *dev) +{ + int err; + unsigned long flags; + +#if SSB_VERBOSE_PCMCIACORESWITCH_DEBUG + ssb_printk(KERN_INFO PFX + "Switching to %s core, index %d\n", + ssb_core_name(dev->id.coreid), + dev->core_index); +#endif + + spin_lock_irqsave(&bus->bar_lock, flags); + err = ssb_pcmcia_switch_coreidx(bus, dev->core_index); + if (!err) + bus->mapped_device = dev; + spin_unlock_irqrestore(&bus->bar_lock, flags); + + return err; +} + +int ssb_pcmcia_switch_segment(struct ssb_bus *bus, u8 seg) +{ + int attempts = 0; + unsigned long flags; + conf_reg_t reg; + int res, err = 0; + + SSB_WARN_ON((seg != 0) && (seg != 1)); + reg.Offset = 0x34; + reg.Function = 0; + spin_lock_irqsave(&bus->bar_lock, flags); + while (1) { + reg.Action = CS_WRITE; + reg.Value = seg; + res = pcmcia_access_configuration_register(bus->host_pcmcia, ®); + if (unlikely(res != CS_SUCCESS)) + goto error; + reg.Value = 0xFF; + reg.Action = CS_READ; + res = pcmcia_access_configuration_register(bus->host_pcmcia, ®); + if (unlikely(res != CS_SUCCESS)) + goto error; + + if (reg.Value == seg) + break; + + if (unlikely(attempts++ > SSB_BAR0_MAX_RETRIES)) + goto error; + udelay(10); + } + bus->mapped_pcmcia_seg = seg; +out_unlock: + spin_unlock_irqrestore(&bus->bar_lock, flags); + return err; +error: + ssb_printk(KERN_ERR PFX "Failed to switch pcmcia segment\n"); + err = -ENODEV; + goto out_unlock; +} + +/* These are the main device register access functions. + * do_select_core is inline to have the likely hotpath inline. + * All unlikely codepaths are out-of-line. */ +static inline int do_select_core(struct ssb_bus *bus, + struct ssb_device *dev, + u16 *offset) +{ + int err; + u8 need_seg = (*offset >= 0x800) ? 1 : 0; + + if (unlikely(dev != bus->mapped_device)) { + err = ssb_pcmcia_switch_core(bus, dev); + if (unlikely(err)) + return err; + } + if (unlikely(need_seg != bus->mapped_pcmcia_seg)) { + err = ssb_pcmcia_switch_segment(bus, need_seg); + if (unlikely(err)) + return err; + } + if (need_seg == 1) + *offset -= 0x800; + + return 0; +} + +static u16 ssb_pcmcia_read16(struct ssb_device *dev, u16 offset) +{ + struct ssb_bus *bus = dev->bus; + u16 x; + + if (unlikely(do_select_core(bus, dev, &offset))) + return 0xFFFF; + x = readw(bus->mmio + offset); + + return x; +} + +static u32 ssb_pcmcia_read32(struct ssb_device *dev, u16 offset) +{ + struct ssb_bus *bus = dev->bus; + u32 x; + + if (unlikely(do_select_core(bus, dev, &offset))) + return 0xFFFFFFFF; + x = readl(bus->mmio + offset); + + return x; +} + +static void ssb_pcmcia_write16(struct ssb_device *dev, u16 offset, u16 value) +{ + struct ssb_bus *bus = dev->bus; + + if (unlikely(do_select_core(bus, dev, &offset))) + return; + writew(value, bus->mmio + offset); +} + +static void ssb_pcmcia_write32(struct ssb_device *dev, u16 offset, u32 value) +{ + struct ssb_bus *bus = dev->bus; + + if (unlikely(do_select_core(bus, dev, &offset))) + return; + readw(bus->mmio + offset); + writew(value >> 16, bus->mmio + offset + 2); + readw(bus->mmio + offset); + writew(value, bus->mmio + offset); +} + +/* Not "static", as it's used in main.c */ +const struct ssb_bus_ops ssb_pcmcia_ops = { + .read16 = ssb_pcmcia_read16, + .read32 = ssb_pcmcia_read32, + .write16 = ssb_pcmcia_write16, + .write32 = ssb_pcmcia_write32, +}; + +int ssb_pcmcia_get_invariants(struct ssb_bus *bus, + struct ssb_init_invariants *iv) +{ + //TODO + return 0; +} + +int ssb_pcmcia_init(struct ssb_bus *bus) +{ + conf_reg_t reg; + int err; + + if (bus->bustype != SSB_BUSTYPE_PCMCIA) + return 0; + + /* Switch segment to a known state and sync + * bus->mapped_pcmcia_seg with hardware state. */ + ssb_pcmcia_switch_segment(bus, 0); + + /* Init IRQ routing */ + reg.Action = CS_READ; + reg.Function = 0; + if (bus->chip_id == 0x4306) + reg.Offset = 0x00; + else + reg.Offset = 0x80; + err = pcmcia_access_configuration_register(bus->host_pcmcia, ®); + if (err != CS_SUCCESS) + goto error; + reg.Action = CS_WRITE; + reg.Value |= 0x04 | 0x01; + err = pcmcia_access_configuration_register(bus->host_pcmcia, ®); + if (err != CS_SUCCESS) + goto error; + + return 0; +error: + return -ENODEV; +} diff --git a/drivers/ssb/scan.c b/drivers/ssb/scan.c new file mode 100644 index 000000000000..96258c60919d --- /dev/null +++ b/drivers/ssb/scan.c @@ -0,0 +1,413 @@ +/* + * Sonics Silicon Backplane + * Bus scanning + * + * Copyright (C) 2005-2007 Michael Buesch + * Copyright (C) 2005 Martin Langer + * Copyright (C) 2005 Stefano Brivio + * Copyright (C) 2005 Danny van Dyk + * Copyright (C) 2005 Andreas Jaggi + * Copyright (C) 2006 Broadcom Corporation. + * + * Licensed under the GNU/GPL. See COPYING for details. + */ + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "ssb_private.h" + + +const char *ssb_core_name(u16 coreid) +{ + switch (coreid) { + case SSB_DEV_CHIPCOMMON: + return "ChipCommon"; + case SSB_DEV_ILINE20: + return "ILine 20"; + case SSB_DEV_SDRAM: + return "SDRAM"; + case SSB_DEV_PCI: + return "PCI"; + case SSB_DEV_MIPS: + return "MIPS"; + case SSB_DEV_ETHERNET: + return "Fast Ethernet"; + case SSB_DEV_V90: + return "V90"; + case SSB_DEV_USB11_HOSTDEV: + return "USB 1.1 Hostdev"; + case SSB_DEV_ADSL: + return "ADSL"; + case SSB_DEV_ILINE100: + return "ILine 100"; + case SSB_DEV_IPSEC: + return "IPSEC"; + case SSB_DEV_PCMCIA: + return "PCMCIA"; + case SSB_DEV_INTERNAL_MEM: + return "Internal Memory"; + case SSB_DEV_MEMC_SDRAM: + return "MEMC SDRAM"; + case SSB_DEV_EXTIF: + return "EXTIF"; + case SSB_DEV_80211: + return "IEEE 802.11"; + case SSB_DEV_MIPS_3302: + return "MIPS 3302"; + case SSB_DEV_USB11_HOST: + return "USB 1.1 Host"; + case SSB_DEV_USB11_DEV: + return "USB 1.1 Device"; + case SSB_DEV_USB20_HOST: + return "USB 2.0 Host"; + case SSB_DEV_USB20_DEV: + return "USB 2.0 Device"; + case SSB_DEV_SDIO_HOST: + return "SDIO Host"; + case SSB_DEV_ROBOSWITCH: + return "Roboswitch"; + case SSB_DEV_PARA_ATA: + return "PATA"; + case SSB_DEV_SATA_XORDMA: + return "SATA XOR-DMA"; + case SSB_DEV_ETHERNET_GBIT: + return "GBit Ethernet"; + case SSB_DEV_PCIE: + return "PCI-E"; + case SSB_DEV_MIMO_PHY: + return "MIMO PHY"; + case SSB_DEV_SRAM_CTRLR: + return "SRAM Controller"; + case SSB_DEV_MINI_MACPHY: + return "Mini MACPHY"; + case SSB_DEV_ARM_1176: + return "ARM 1176"; + case SSB_DEV_ARM_7TDMI: + return "ARM 7TDMI"; + } + return "UNKNOWN"; +} + +static u16 pcidev_to_chipid(struct pci_dev *pci_dev) +{ + u16 chipid_fallback = 0; + + switch (pci_dev->device) { + case 0x4301: + chipid_fallback = 0x4301; + break; + case 0x4305 ... 0x4307: + chipid_fallback = 0x4307; + break; + case 0x4403: + chipid_fallback = 0x4402; + break; + case 0x4610 ... 0x4615: + chipid_fallback = 0x4610; + break; + case 0x4710 ... 0x4715: + chipid_fallback = 0x4710; + break; + case 0x4320 ... 0x4325: + chipid_fallback = 0x4309; + break; + case PCI_DEVICE_ID_BCM4401: + case PCI_DEVICE_ID_BCM4401B0: + case PCI_DEVICE_ID_BCM4401B1: + chipid_fallback = 0x4401; + break; + default: + ssb_printk(KERN_ERR PFX + "PCI-ID not in fallback list\n"); + } + + return chipid_fallback; +} + +static u8 chipid_to_nrcores(u16 chipid) +{ + switch (chipid) { + case 0x5365: + return 7; + case 0x4306: + return 6; + case 0x4310: + return 8; + case 0x4307: + case 0x4301: + return 5; + case 0x4401: + case 0x4402: + return 3; + case 0x4710: + case 0x4610: + case 0x4704: + return 9; + default: + ssb_printk(KERN_ERR PFX + "CHIPID not in nrcores fallback list\n"); + } + + return 1; +} + +static u32 scan_read32(struct ssb_bus *bus, u8 current_coreidx, + u16 offset) +{ + switch (bus->bustype) { + case SSB_BUSTYPE_SSB: + offset += current_coreidx * SSB_CORE_SIZE; + break; + case SSB_BUSTYPE_PCI: + break; + case SSB_BUSTYPE_PCMCIA: + if (offset >= 0x800) { + ssb_pcmcia_switch_segment(bus, 1); + offset -= 0x800; + } else + ssb_pcmcia_switch_segment(bus, 0); + break; + } + return readl(bus->mmio + offset); +} + +static int scan_switchcore(struct ssb_bus *bus, u8 coreidx) +{ + switch (bus->bustype) { + case SSB_BUSTYPE_SSB: + break; + case SSB_BUSTYPE_PCI: + return ssb_pci_switch_coreidx(bus, coreidx); + case SSB_BUSTYPE_PCMCIA: + return ssb_pcmcia_switch_coreidx(bus, coreidx); + } + return 0; +} + +void ssb_iounmap(struct ssb_bus *bus) +{ + switch (bus->bustype) { + case SSB_BUSTYPE_SSB: + case SSB_BUSTYPE_PCMCIA: + iounmap(bus->mmio); + break; + case SSB_BUSTYPE_PCI: +#ifdef CONFIG_SSB_PCIHOST + pci_iounmap(bus->host_pci, bus->mmio); +#else + SSB_BUG_ON(1); /* Can't reach this code. */ +#endif + break; + } + bus->mmio = NULL; + bus->mapped_device = NULL; +} + +static void __iomem *ssb_ioremap(struct ssb_bus *bus, + unsigned long baseaddr) +{ + void __iomem *mmio = NULL; + + switch (bus->bustype) { + case SSB_BUSTYPE_SSB: + /* Only map the first core for now. */ + /* fallthrough... */ + case SSB_BUSTYPE_PCMCIA: + mmio = ioremap(baseaddr, SSB_CORE_SIZE); + break; + case SSB_BUSTYPE_PCI: +#ifdef CONFIG_SSB_PCIHOST + mmio = pci_iomap(bus->host_pci, 0, ~0UL); +#else + SSB_BUG_ON(1); /* Can't reach this code. */ +#endif + break; + } + + return mmio; +} + +static int we_support_multiple_80211_cores(struct ssb_bus *bus) +{ + /* More than one 802.11 core is only supported by special chips. + * There are chips with two 802.11 cores, but with dangling + * pins on the second core. Be careful and reject them here. + */ + +#ifdef CONFIG_SSB_PCIHOST + if (bus->bustype == SSB_BUSTYPE_PCI) { + if (bus->host_pci->vendor == PCI_VENDOR_ID_BROADCOM && + bus->host_pci->device == 0x4324) + return 1; + } +#endif /* CONFIG_SSB_PCIHOST */ + return 0; +} + +int ssb_bus_scan(struct ssb_bus *bus, + unsigned long baseaddr) +{ + int err = -ENOMEM; + void __iomem *mmio; + u32 idhi, cc, rev, tmp; + int dev_i, i; + struct ssb_device *dev; + int nr_80211_cores = 0; + + mmio = ssb_ioremap(bus, baseaddr); + if (!mmio) + goto out; + bus->mmio = mmio; + + err = scan_switchcore(bus, 0); /* Switch to first core */ + if (err) + goto err_unmap; + + idhi = scan_read32(bus, 0, SSB_IDHIGH); + cc = (idhi & SSB_IDHIGH_CC) >> SSB_IDHIGH_CC_SHIFT; + rev = (idhi & SSB_IDHIGH_RCLO); + rev |= (idhi & SSB_IDHIGH_RCHI) >> SSB_IDHIGH_RCHI_SHIFT; + + bus->nr_devices = 0; + if (cc == SSB_DEV_CHIPCOMMON) { + tmp = scan_read32(bus, 0, SSB_CHIPCO_CHIPID); + + bus->chip_id = (tmp & SSB_CHIPCO_IDMASK); + bus->chip_rev = (tmp & SSB_CHIPCO_REVMASK) >> + SSB_CHIPCO_REVSHIFT; + bus->chip_package = (tmp & SSB_CHIPCO_PACKMASK) >> + SSB_CHIPCO_PACKSHIFT; + if (rev >= 4) { + bus->nr_devices = (tmp & SSB_CHIPCO_NRCORESMASK) >> + SSB_CHIPCO_NRCORESSHIFT; + } + tmp = scan_read32(bus, 0, SSB_CHIPCO_CAP); + bus->chipco.capabilities = tmp; + } else { + if (bus->bustype == SSB_BUSTYPE_PCI) { + bus->chip_id = pcidev_to_chipid(bus->host_pci); + pci_read_config_word(bus->host_pci, PCI_REVISION_ID, + &bus->chip_rev); + bus->chip_package = 0; + } else { + bus->chip_id = 0x4710; + bus->chip_rev = 0; + bus->chip_package = 0; + } + } + if (!bus->nr_devices) + bus->nr_devices = chipid_to_nrcores(bus->chip_id); + if (bus->nr_devices > ARRAY_SIZE(bus->devices)) { + ssb_printk(KERN_ERR PFX + "More than %d ssb cores found (%d)\n", + SSB_MAX_NR_CORES, bus->nr_devices); + goto err_unmap; + } + if (bus->bustype == SSB_BUSTYPE_SSB) { + /* Now that we know the number of cores, + * remap the whole IO space for all cores. + */ + err = -ENOMEM; + iounmap(mmio); + mmio = ioremap(baseaddr, SSB_CORE_SIZE * bus->nr_devices); + if (!mmio) + goto out; + bus->mmio = mmio; + } + + /* Fetch basic information about each core/device */ + for (i = 0, dev_i = 0; i < bus->nr_devices; i++) { + err = scan_switchcore(bus, i); + if (err) + goto err_unmap; + dev = &(bus->devices[dev_i]); + + idhi = scan_read32(bus, i, SSB_IDHIGH); + dev->id.coreid = (idhi & SSB_IDHIGH_CC) >> SSB_IDHIGH_CC_SHIFT; + dev->id.revision = (idhi & SSB_IDHIGH_RCLO); + dev->id.revision |= (idhi & SSB_IDHIGH_RCHI) >> SSB_IDHIGH_RCHI_SHIFT; + dev->id.vendor = (idhi & SSB_IDHIGH_VC) >> SSB_IDHIGH_VC_SHIFT; + dev->core_index = i; + dev->bus = bus; + dev->ops = bus->ops; + + ssb_dprintk(KERN_INFO PFX + "Core %d found: %s " + "(cc 0x%03X, rev 0x%02X, vendor 0x%04X)\n", + i, ssb_core_name(dev->id.coreid), + dev->id.coreid, dev->id.revision, dev->id.vendor); + + switch (dev->id.coreid) { + case SSB_DEV_80211: + nr_80211_cores++; + if (nr_80211_cores > 1) { + if (!we_support_multiple_80211_cores(bus)) { + ssb_dprintk(KERN_INFO PFX "Ignoring additional " + "802.11 core\n"); + continue; + } + } + break; + case SSB_DEV_EXTIF: +#ifdef CONFIG_SSB_DRIVER_EXTIF + if (bus->extif.dev) { + ssb_printk(KERN_WARNING PFX + "WARNING: Multiple EXTIFs found\n"); + break; + } + bus->extif.dev = dev; +#endif /* CONFIG_SSB_DRIVER_EXTIF */ + break; + case SSB_DEV_CHIPCOMMON: + if (bus->chipco.dev) { + ssb_printk(KERN_WARNING PFX + "WARNING: Multiple ChipCommon found\n"); + break; + } + bus->chipco.dev = dev; + break; + case SSB_DEV_MIPS: + case SSB_DEV_MIPS_3302: +#ifdef CONFIG_SSB_DRIVER_MIPS + if (bus->mipscore.dev) { + ssb_printk(KERN_WARNING PFX + "WARNING: Multiple MIPS cores found\n"); + break; + } + bus->mipscore.dev = dev; +#endif /* CONFIG_SSB_DRIVER_MIPS */ + break; + case SSB_DEV_PCI: + case SSB_DEV_PCIE: +#ifdef CONFIG_SSB_DRIVER_PCICORE + if (bus->pcicore.dev) { + ssb_printk(KERN_WARNING PFX + "WARNING: Multiple PCI(E) cores found\n"); + break; + } + bus->pcicore.dev = dev; +#endif /* CONFIG_SSB_DRIVER_PCICORE */ + break; + default: + break; + } + + dev_i++; + } + bus->nr_devices = dev_i; + + err = 0; +out: + return err; +err_unmap: + ssb_iounmap(bus); + goto out; +} diff --git a/drivers/ssb/ssb_private.h b/drivers/ssb/ssb_private.h new file mode 100644 index 000000000000..a789364264a6 --- /dev/null +++ b/drivers/ssb/ssb_private.h @@ -0,0 +1,136 @@ +#ifndef LINUX_SSB_PRIVATE_H_ +#define LINUX_SSB_PRIVATE_H_ + +#include +#include + + +#define PFX "ssb: " + +#ifdef CONFIG_SSB_SILENT +# define ssb_printk(fmt, x...) do { /* nothing */ } while (0) +#else +# define ssb_printk printk +#endif /* CONFIG_SSB_SILENT */ + +/* dprintk: Debugging printk; vanishes for non-debug compilation */ +#ifdef CONFIG_SSB_DEBUG +# define ssb_dprintk(fmt, x...) ssb_printk(fmt , ##x) +#else +# define ssb_dprintk(fmt, x...) do { /* nothing */ } while (0) +#endif + +#ifdef CONFIG_SSB_DEBUG +# define SSB_WARN_ON(x) WARN_ON(x) +# define SSB_BUG_ON(x) BUG_ON(x) +#else +static inline int __ssb_do_nothing(int x) { return x; } +# define SSB_WARN_ON(x) __ssb_do_nothing(unlikely(!!(x))) +# define SSB_BUG_ON(x) __ssb_do_nothing(unlikely(!!(x))) +#endif + + +/* pci.c */ +#ifdef CONFIG_SSB_PCIHOST +extern int ssb_pci_switch_core(struct ssb_bus *bus, + struct ssb_device *dev); +extern int ssb_pci_switch_coreidx(struct ssb_bus *bus, + u8 coreidx); +extern int ssb_pci_xtal(struct ssb_bus *bus, u32 what, + int turn_on); +extern int ssb_pci_get_invariants(struct ssb_bus *bus, + struct ssb_init_invariants *iv); +extern void ssb_pci_exit(struct ssb_bus *bus); +extern int ssb_pci_init(struct ssb_bus *bus); +extern const struct ssb_bus_ops ssb_pci_ops; + +#else /* CONFIG_SSB_PCIHOST */ + +static inline int ssb_pci_switch_core(struct ssb_bus *bus, + struct ssb_device *dev) +{ + return 0; +} +static inline int ssb_pci_switch_coreidx(struct ssb_bus *bus, + u8 coreidx) +{ + return 0; +} +static inline int ssb_pci_xtal(struct ssb_bus *bus, u32 what, + int turn_on) +{ + return 0; +} +static inline void ssb_pci_exit(struct ssb_bus *bus) +{ +} +static inline int ssb_pci_init(struct ssb_bus *bus) +{ + return 0; +} +#endif /* CONFIG_SSB_PCIHOST */ + + +/* pcmcia.c */ +#ifdef CONFIG_SSB_PCMCIAHOST +extern int ssb_pcmcia_switch_core(struct ssb_bus *bus, + struct ssb_device *dev); +extern int ssb_pcmcia_switch_coreidx(struct ssb_bus *bus, + u8 coreidx); +extern int ssb_pcmcia_switch_segment(struct ssb_bus *bus, + u8 seg); +extern int ssb_pcmcia_get_invariants(struct ssb_bus *bus, + struct ssb_init_invariants *iv); +extern int ssb_pcmcia_init(struct ssb_bus *bus); +extern const struct ssb_bus_ops ssb_pcmcia_ops; +#else /* CONFIG_SSB_PCMCIAHOST */ +static inline int ssb_pcmcia_switch_core(struct ssb_bus *bus, + struct ssb_device *dev) +{ + return 0; +} +static inline int ssb_pcmcia_switch_coreidx(struct ssb_bus *bus, + u8 coreidx) +{ + return 0; +} +static inline int ssb_pcmcia_switch_segment(struct ssb_bus *bus, + u8 seg) +{ + return 0; +} +static inline int ssb_pcmcia_init(struct ssb_bus *bus) +{ + return 0; +} +#endif /* CONFIG_SSB_PCMCIAHOST */ + + +/* scan.c */ +extern const char *ssb_core_name(u16 coreid); +extern int ssb_bus_scan(struct ssb_bus *bus, + unsigned long baseaddr); +extern void ssb_iounmap(struct ssb_bus *ssb); + + +/* core.c */ +extern u32 ssb_calc_clock_rate(u32 plltype, u32 n, u32 m); +extern int ssb_devices_freeze(struct ssb_bus *bus); +extern int ssb_devices_thaw(struct ssb_bus *bus); +extern struct ssb_bus *ssb_pci_dev_to_bus(struct pci_dev *pdev); + +/* b43_pci_bridge.c */ +#ifdef CONFIG_SSB_PCIHOST +extern int __init b43_pci_ssb_bridge_init(void); +extern void __exit b43_pci_ssb_bridge_exit(void); +#else /* CONFIG_SSB_PCIHOST */ +static inline int b43_pci_ssb_bridge_init(void) +{ + return 0; +} +static inline void b43_pci_ssb_bridge_exit(void) +{ +} +#endif /* CONFIG_SSB_PCIHOST */ + +#endif /* LINUX_SSB_PRIVATE_H_ */ diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h index 4dc5fa8be781..0c522e6b0917 100644 --- a/include/linux/mod_devicetable.h +++ b/include/linux/mod_devicetable.h @@ -340,4 +340,19 @@ struct parisc_device_id { #define PA_HVERSION_ANY_ID 0xffff #define PA_SVERSION_ANY_ID 0xffffffff +/* SSB core, see drivers/ssb/ */ +struct ssb_device_id { + __u16 vendor; + __u16 coreid; + __u8 revision; +}; +#define SSB_DEVICE(_vendor, _coreid, _revision) \ + { .vendor = _vendor, .coreid = _coreid, .revision = _revision, } +#define SSB_DEVTABLE_END \ + { 0, }, + +#define SSB_ANY_VENDOR 0xFFFF +#define SSB_ANY_ID 0xFFFF +#define SSB_ANY_REV 0xFF + #endif /* LINUX_MOD_DEVICETABLE_H */ diff --git a/include/linux/ssb/ssb.h b/include/linux/ssb/ssb.h new file mode 100644 index 000000000000..2b5c312c4960 --- /dev/null +++ b/include/linux/ssb/ssb.h @@ -0,0 +1,424 @@ +#ifndef LINUX_SSB_H_ +#define LINUX_SSB_H_ + +#include +#include +#include +#include +#include +#include + +#include + + +struct pcmcia_device; +struct ssb_bus; +struct ssb_driver; + + +struct ssb_sprom_r1 { + u16 pci_spid; /* Subsystem Product ID for PCI */ + u16 pci_svid; /* Subsystem Vendor ID for PCI */ + u16 pci_pid; /* Product ID for PCI */ + u8 il0mac[6]; /* MAC address for 802.11b/g */ + u8 et0mac[6]; /* MAC address for Ethernet */ + u8 et1mac[6]; /* MAC address for 802.11a */ + u8 et0phyaddr:5; /* MII address for enet0 */ + u8 et1phyaddr:5; /* MII address for enet1 */ + u8 et0mdcport:1; /* MDIO for enet0 */ + u8 et1mdcport:1; /* MDIO for enet1 */ + u8 board_rev; /* Board revision */ + u8 country_code:4; /* Country Code */ + u8 antenna_a:2; /* Antenna 0/1 available for A-PHY */ + u8 antenna_bg:2; /* Antenna 0/1 available for B-PHY and G-PHY */ + u16 pa0b0; + u16 pa0b1; + u16 pa0b2; + u16 pa1b0; + u16 pa1b1; + u16 pa1b2; + u8 gpio0; /* GPIO pin 0 */ + u8 gpio1; /* GPIO pin 1 */ + u8 gpio2; /* GPIO pin 2 */ + u8 gpio3; /* GPIO pin 3 */ + u16 maxpwr_a; /* A-PHY Power Amplifier Max Power (in dBm Q5.2) */ + u16 maxpwr_bg; /* B/G-PHY Power Amplifier Max Power (in dBm Q5.2) */ + u8 itssi_a; /* Idle TSSI Target for A-PHY */ + u8 itssi_bg; /* Idle TSSI Target for B/G-PHY */ + u16 boardflags_lo; /* Boardflags (low 16 bits) */ + u8 antenna_gain_a; /* A-PHY Antenna gain (in dBm Q5.2) */ + u8 antenna_gain_bg; /* B/G-PHY Antenna gain (in dBm Q5.2) */ + u8 oem[8]; /* OEM string (rev 1 only) */ +}; + +struct ssb_sprom_r2 { + u16 boardflags_hi; /* Boardflags (high 16 bits) */ + u8 maxpwr_a_lo; /* A-PHY Max Power Low */ + u8 maxpwr_a_hi; /* A-PHY Max Power High */ + u16 pa1lob0; /* A-PHY PA Low Settings */ + u16 pa1lob1; /* A-PHY PA Low Settings */ + u16 pa1lob2; /* A-PHY PA Low Settings */ + u16 pa1hib0; /* A-PHY PA High Settings */ + u16 pa1hib1; /* A-PHY PA High Settings */ + u16 pa1hib2; /* A-PHY PA High Settings */ + u8 ofdm_pwr_off; /* OFDM Power Offset from CCK Level */ + u8 country_str[2]; /* Two char Country Code */ +}; + +struct ssb_sprom_r3 { + u32 ofdmapo; /* A-PHY OFDM Mid Power Offset */ + u32 ofdmalpo; /* A-PHY OFDM Low Power Offset */ + u32 ofdmahpo; /* A-PHY OFDM High Power Offset */ + u8 gpioldc_on_cnt; /* GPIO LED Powersave Duty Cycle ON count */ + u8 gpioldc_off_cnt; /* GPIO LED Powersave Duty Cycle OFF count */ + u8 cckpo_1M:4; /* CCK Power Offset for Rate 1M */ + u8 cckpo_2M:4; /* CCK Power Offset for Rate 2M */ + u8 cckpo_55M:4; /* CCK Power Offset for Rate 5.5M */ + u8 cckpo_11M:4; /* CCK Power Offset for Rate 11M */ + u32 ofdmgpo; /* G-PHY OFDM Power Offset */ +}; + +struct ssb_sprom_r4 { + /* TODO */ +}; + +struct ssb_sprom { + u8 revision; + u8 crc; + /* The valid r# fields are selected by the "revision". + * Revision 3 and lower inherit from lower revisions. + */ + union { + struct { + struct ssb_sprom_r1 r1; + struct ssb_sprom_r2 r2; + struct ssb_sprom_r3 r3; + }; + struct ssb_sprom_r4 r4; + }; +}; + +/* Information about the PCB the circuitry is soldered on. */ +struct ssb_boardinfo { + u16 vendor; + u16 type; + u16 rev; +}; + + +struct ssb_device; +/* Lowlevel read/write operations on the device MMIO. + * Internal, don't use that outside of ssb. */ +struct ssb_bus_ops { + u16 (*read16)(struct ssb_device *dev, u16 offset); + u32 (*read32)(struct ssb_device *dev, u16 offset); + void (*write16)(struct ssb_device *dev, u16 offset, u16 value); + void (*write32)(struct ssb_device *dev, u16 offset, u32 value); +}; + + +/* Core-ID values. */ +#define SSB_DEV_CHIPCOMMON 0x800 +#define SSB_DEV_ILINE20 0x801 +#define SSB_DEV_SDRAM 0x803 +#define SSB_DEV_PCI 0x804 +#define SSB_DEV_MIPS 0x805 +#define SSB_DEV_ETHERNET 0x806 +#define SSB_DEV_V90 0x807 +#define SSB_DEV_USB11_HOSTDEV 0x808 +#define SSB_DEV_ADSL 0x809 +#define SSB_DEV_ILINE100 0x80A +#define SSB_DEV_IPSEC 0x80B +#define SSB_DEV_PCMCIA 0x80D +#define SSB_DEV_INTERNAL_MEM 0x80E +#define SSB_DEV_MEMC_SDRAM 0x80F +#define SSB_DEV_EXTIF 0x811 +#define SSB_DEV_80211 0x812 +#define SSB_DEV_MIPS_3302 0x816 +#define SSB_DEV_USB11_HOST 0x817 +#define SSB_DEV_USB11_DEV 0x818 +#define SSB_DEV_USB20_HOST 0x819 +#define SSB_DEV_USB20_DEV 0x81A +#define SSB_DEV_SDIO_HOST 0x81B +#define SSB_DEV_ROBOSWITCH 0x81C +#define SSB_DEV_PARA_ATA 0x81D +#define SSB_DEV_SATA_XORDMA 0x81E +#define SSB_DEV_ETHERNET_GBIT 0x81F +#define SSB_DEV_PCIE 0x820 +#define SSB_DEV_MIMO_PHY 0x821 +#define SSB_DEV_SRAM_CTRLR 0x822 +#define SSB_DEV_MINI_MACPHY 0x823 +#define SSB_DEV_ARM_1176 0x824 +#define SSB_DEV_ARM_7TDMI 0x825 + +/* Vendor-ID values */ +#define SSB_VENDOR_BROADCOM 0x4243 + +/* Some kernel subsystems poke with dev->drvdata, so we must use the + * following ugly workaround to get from struct device to struct ssb_device */ +struct __ssb_dev_wrapper { + struct device dev; + struct ssb_device *sdev; +}; + +struct ssb_device { + /* Having a copy of the ops pointer in each dev struct + * is an optimization. */ + const struct ssb_bus_ops *ops; + + struct device *dev; + struct ssb_bus *bus; + struct ssb_device_id id; + + u8 core_index; + unsigned int irq; + + /* Internal-only stuff follows. */ + void *drvdata; /* Per-device data */ + void *devtypedata; /* Per-devicetype (eg 802.11) data */ +}; + +/* Go from struct device to struct ssb_device. */ +static inline +struct ssb_device * dev_to_ssb_dev(struct device *dev) +{ + struct __ssb_dev_wrapper *wrap; + wrap = container_of(dev, struct __ssb_dev_wrapper, dev); + return wrap->sdev; +} + +/* Device specific user data */ +static inline +void ssb_set_drvdata(struct ssb_device *dev, void *data) +{ + dev->drvdata = data; +} +static inline +void * ssb_get_drvdata(struct ssb_device *dev) +{ + return dev->drvdata; +} + +/* Devicetype specific user data. This is per device-type (not per device) */ +void ssb_set_devtypedata(struct ssb_device *dev, void *data); +static inline +void * ssb_get_devtypedata(struct ssb_device *dev) +{ + return dev->devtypedata; +} + + +struct ssb_driver { + const char *name; + const struct ssb_device_id *id_table; + + int (*probe)(struct ssb_device *dev, const struct ssb_device_id *id); + void (*remove)(struct ssb_device *dev); + int (*suspend)(struct ssb_device *dev, pm_message_t state); + int (*resume)(struct ssb_device *dev); + void (*shutdown)(struct ssb_device *dev); + + struct device_driver drv; +}; +#define drv_to_ssb_drv(_drv) container_of(_drv, struct ssb_driver, drv) + +extern int __ssb_driver_register(struct ssb_driver *drv, struct module *owner); +static inline int ssb_driver_register(struct ssb_driver *drv) +{ + return __ssb_driver_register(drv, THIS_MODULE); +} +extern void ssb_driver_unregister(struct ssb_driver *drv); + + + + +enum ssb_bustype { + SSB_BUSTYPE_SSB, /* This SSB bus is the system bus */ + SSB_BUSTYPE_PCI, /* SSB is connected to PCI bus */ + SSB_BUSTYPE_PCMCIA, /* SSB is connected to PCMCIA bus */ +}; + +/* board_vendor */ +#define SSB_BOARDVENDOR_BCM 0x14E4 /* Broadcom */ +#define SSB_BOARDVENDOR_DELL 0x1028 /* Dell */ +#define SSB_BOARDVENDOR_HP 0x0E11 /* HP */ +/* board_type */ +#define SSB_BOARD_BCM94306MP 0x0418 +#define SSB_BOARD_BCM4309G 0x0421 +#define SSB_BOARD_BCM4306CB 0x0417 +#define SSB_BOARD_BCM4309MP 0x040C +#define SSB_BOARD_MP4318 0x044A +#define SSB_BOARD_BU4306 0x0416 +#define SSB_BOARD_BU4309 0x040A +/* chip_package */ +#define SSB_CHIPPACK_BCM4712S 1 /* Small 200pin 4712 */ +#define SSB_CHIPPACK_BCM4712M 2 /* Medium 225pin 4712 */ +#define SSB_CHIPPACK_BCM4712L 0 /* Large 340pin 4712 */ + +#include +#include +#include +#include + +struct ssb_bus { + /* The MMIO area. */ + void __iomem *mmio; + + const struct ssb_bus_ops *ops; + + /* The core in the basic address register window. (PCI bus only) */ + struct ssb_device *mapped_device; + /* Currently mapped PCMCIA segment. (bustype == SSB_BUSTYPE_PCMCIA only) */ + u8 mapped_pcmcia_seg; + /* Lock for core and segment switching. */ + spinlock_t bar_lock; + + /* The bus this backplane is running on. */ + enum ssb_bustype bustype; + /* Pointer to the PCI bus (only valid if bustype == SSB_BUSTYPE_PCI). */ + struct pci_dev *host_pci; + /* Pointer to the PCMCIA device (only if bustype == SSB_BUSTYPE_PCMCIA). */ + struct pcmcia_device *host_pcmcia; + +#ifdef CONFIG_SSB_PCIHOST + /* Mutex to protect the SPROM writing. */ + struct mutex pci_sprom_mutex; +#endif + + /* ID information about the Chip. */ + u16 chip_id; + u16 chip_rev; + u8 chip_package; + + /* List of devices (cores) on the backplane. */ + struct ssb_device devices[SSB_MAX_NR_CORES]; + u8 nr_devices; + + /* Reference count. Number of suspended devices. */ + u8 suspend_cnt; + + /* Software ID number for this bus. */ + unsigned int busnumber; + + /* The ChipCommon device (if available). */ + struct ssb_chipcommon chipco; + /* The PCI-core device (if available). */ + struct ssb_pcicore pcicore; + /* The MIPS-core device (if available). */ + struct ssb_mipscore mipscore; + /* The EXTif-core device (if available). */ + struct ssb_extif extif; + + /* The following structure elements are not available in early + * SSB initialization. Though, they are available for regular + * registered drivers at any stage. So be careful when + * using them in the ssb core code. */ + + /* ID information about the PCB. */ + struct ssb_boardinfo boardinfo; + /* Contents of the SPROM. */ + struct ssb_sprom sprom; + + /* Internal-only stuff follows. Do not touch. */ + struct list_head list; +#ifdef CONFIG_SSB_DEBUG + /* Is the bus already powered up? */ + bool powered_up; + int power_warn_count; +#endif /* DEBUG */ +}; + +/* The initialization-invariants. */ +struct ssb_init_invariants { + struct ssb_boardinfo boardinfo; + struct ssb_sprom sprom; +}; +/* Type of function to fetch the invariants. */ +typedef int (*ssb_invariants_func_t)(struct ssb_bus *bus, + struct ssb_init_invariants *iv); + +/* Register a SSB system bus. get_invariants() is called after the + * basic system devices are initialized. + * The invariants are usually fetched from some NVRAM. + * Put the invariants into the struct pointed to by iv. */ +extern int ssb_bus_ssbbus_register(struct ssb_bus *bus, + unsigned long baseaddr, + ssb_invariants_func_t get_invariants); +#ifdef CONFIG_SSB_PCIHOST +extern int ssb_bus_pcibus_register(struct ssb_bus *bus, + struct pci_dev *host_pci); +#endif /* CONFIG_SSB_PCIHOST */ +#ifdef CONFIG_SSB_PCMCIAHOST +extern int ssb_bus_pcmciabus_register(struct ssb_bus *bus, + struct pcmcia_device *pcmcia_dev, + unsigned long baseaddr); +#endif /* CONFIG_SSB_PCMCIAHOST */ + +extern void ssb_bus_unregister(struct ssb_bus *bus); + +extern u32 ssb_clockspeed(struct ssb_bus *bus); + +/* Is the device enabled in hardware? */ +int ssb_device_is_enabled(struct ssb_device *dev); +/* Enable a device and pass device-specific SSB_TMSLOW flags. + * If no device-specific flags are available, use 0. */ +void ssb_device_enable(struct ssb_device *dev, u32 core_specific_flags); +/* Disable a device in hardware and pass SSB_TMSLOW flags (if any). */ +void ssb_device_disable(struct ssb_device *dev, u32 core_specific_flags); + + +/* Device MMIO register read/write functions. */ +static inline u16 ssb_read16(struct ssb_device *dev, u16 offset) +{ + return dev->ops->read16(dev, offset); +} +static inline u32 ssb_read32(struct ssb_device *dev, u16 offset) +{ + return dev->ops->read32(dev, offset); +} +static inline void ssb_write16(struct ssb_device *dev, u16 offset, u16 value) +{ + dev->ops->write16(dev, offset, value); +} +static inline void ssb_write32(struct ssb_device *dev, u16 offset, u32 value) +{ + dev->ops->write32(dev, offset, value); +} + + +/* Translation (routing) bits that need to be ORed to DMA + * addresses before they are given to a device. */ +extern u32 ssb_dma_translation(struct ssb_device *dev); +#define SSB_DMA_TRANSLATION_MASK 0xC0000000 +#define SSB_DMA_TRANSLATION_SHIFT 30 + +extern int ssb_dma_set_mask(struct ssb_device *ssb_dev, u64 mask); + + +#ifdef CONFIG_SSB_PCIHOST +/* PCI-host wrapper driver */ +extern int ssb_pcihost_register(struct pci_driver *driver); +static inline void ssb_pcihost_unregister(struct pci_driver *driver) +{ + pci_unregister_driver(driver); +} +#endif /* CONFIG_SSB_PCIHOST */ + + +/* If a driver is shutdown or suspended, call this to signal + * that the bus may be completely powered down. SSB will decide, + * if it's really time to power down the bus, based on if there + * are other devices that want to run. */ +extern int ssb_bus_may_powerdown(struct ssb_bus *bus); +/* Before initializing and enabling a device, call this to power-up the bus. + * If you want to allow use of dynamic-power-control, pass the flag. + * Otherwise static always-on powercontrol will be used. */ +extern int ssb_bus_powerup(struct ssb_bus *bus, bool dynamic_pctl); + + +/* Various helper functions */ +extern u32 ssb_admatch_base(u32 adm); +extern u32 ssb_admatch_size(u32 adm); + + +#endif /* LINUX_SSB_H_ */ diff --git a/include/linux/ssb/ssb_driver_chipcommon.h b/include/linux/ssb/ssb_driver_chipcommon.h new file mode 100644 index 000000000000..4cb995494662 --- /dev/null +++ b/include/linux/ssb/ssb_driver_chipcommon.h @@ -0,0 +1,396 @@ +#ifndef LINUX_SSB_CHIPCO_H_ +#define LINUX_SSB_CHIPCO_H_ + +/* SonicsSiliconBackplane CHIPCOMMON core hardware definitions + * + * The chipcommon core provides chip identification, SB control, + * jtag, 0/1/2 uarts, clock frequency control, a watchdog interrupt timer, + * gpio interface, extbus, and support for serial and parallel flashes. + * + * Copyright 2005, Broadcom Corporation + * Copyright 2006, Michael Buesch + * + * Licensed under the GPL version 2. See COPYING for details. + */ + +/** ChipCommon core registers. **/ + +#define SSB_CHIPCO_CHIPID 0x0000 +#define SSB_CHIPCO_IDMASK 0x0000FFFF +#define SSB_CHIPCO_REVMASK 0x000F0000 +#define SSB_CHIPCO_REVSHIFT 16 +#define SSB_CHIPCO_PACKMASK 0x00F00000 +#define SSB_CHIPCO_PACKSHIFT 20 +#define SSB_CHIPCO_NRCORESMASK 0x0F000000 +#define SSB_CHIPCO_NRCORESSHIFT 24 +#define SSB_CHIPCO_CAP 0x0004 /* Capabilities */ +#define SSB_CHIPCO_CAP_NRUART 0x00000003 /* # of UARTs */ +#define SSB_CHIPCO_CAP_MIPSEB 0x00000004 /* MIPS in BigEndian Mode */ +#define SSB_CHIPCO_CAP_UARTCLK 0x00000018 /* UART clock select */ +#define SSB_CHIPCO_CAP_UARTCLK_INT 0x00000008 /* UARTs are driven by internal divided clock */ +#define SSB_CHIPCO_CAP_UARTGPIO 0x00000020 /* UARTs on GPIO 15-12 */ +#define SSB_CHIPCO_CAP_EXTBUS 0x000000C0 /* External buses present */ +#define SSB_CHIPCO_CAP_FLASHT 0x00000700 /* Flash Type */ +#define SSB_CHIPCO_FLASHT_NONE 0x00000000 /* No flash */ +#define SSB_CHIPCO_FLASHT_STSER 0x00000100 /* ST serial flash */ +#define SSB_CHIPCO_FLASHT_ATSER 0x00000200 /* Atmel serial flash */ +#define SSB_CHIPCO_FLASHT_PARA 0x00000700 /* Parallel flash */ +#define SSB_CHIPCO_CAP_PLLT 0x00038000 /* PLL Type */ +#define SSB_PLLTYPE_NONE 0x00000000 +#define SSB_PLLTYPE_1 0x00010000 /* 48Mhz base, 3 dividers */ +#define SSB_PLLTYPE_2 0x00020000 /* 48Mhz, 4 dividers */ +#define SSB_PLLTYPE_3 0x00030000 /* 25Mhz, 2 dividers */ +#define SSB_PLLTYPE_4 0x00008000 /* 48Mhz, 4 dividers */ +#define SSB_PLLTYPE_5 0x00018000 /* 25Mhz, 4 dividers */ +#define SSB_PLLTYPE_6 0x00028000 /* 100/200 or 120/240 only */ +#define SSB_PLLTYPE_7 0x00038000 /* 25Mhz, 4 dividers */ +#define SSB_CHIPCO_CAP_PCTL 0x00040000 /* Power Control */ +#define SSB_CHIPCO_CAP_OTPS 0x00380000 /* OTP size */ +#define SSB_CHIPCO_CAP_OTPS_SHIFT 19 +#define SSB_CHIPCO_CAP_OTPS_BASE 5 +#define SSB_CHIPCO_CAP_JTAGM 0x00400000 /* JTAG master present */ +#define SSB_CHIPCO_CAP_BROM 0x00800000 /* Internal boot ROM active */ +#define SSB_CHIPCO_CAP_64BIT 0x08000000 /* 64-bit Backplane */ +#define SSB_CHIPCO_CORECTL 0x0008 +#define SSB_CHIPCO_CORECTL_UARTCLK0 0x00000001 /* Drive UART with internal clock */ +#define SSB_CHIPCO_CORECTL_SE 0x00000002 /* sync clk out enable (corerev >= 3) */ +#define SSB_CHIPCO_BIST 0x000C +#define SSB_CHIPCO_OTPS 0x0010 /* OTP status */ +#define SSB_CHIPCO_OTPS_PROGFAIL 0x80000000 +#define SSB_CHIPCO_OTPS_PROTECT 0x00000007 +#define SSB_CHIPCO_OTPS_HW_PROTECT 0x00000001 +#define SSB_CHIPCO_OTPS_SW_PROTECT 0x00000002 +#define SSB_CHIPCO_OTPS_CID_PROTECT 0x00000004 +#define SSB_CHIPCO_OTPC 0x0014 /* OTP control */ +#define SSB_CHIPCO_OTPC_RECWAIT 0xFF000000 +#define SSB_CHIPCO_OTPC_PROGWAIT 0x00FFFF00 +#define SSB_CHIPCO_OTPC_PRW_SHIFT 8 +#define SSB_CHIPCO_OTPC_MAXFAIL 0x00000038 +#define SSB_CHIPCO_OTPC_VSEL 0x00000006 +#define SSB_CHIPCO_OTPC_SELVL 0x00000001 +#define SSB_CHIPCO_OTPP 0x0018 /* OTP prog */ +#define SSB_CHIPCO_OTPP_COL 0x000000FF +#define SSB_CHIPCO_OTPP_ROW 0x0000FF00 +#define SSB_CHIPCO_OTPP_ROW_SHIFT 8 +#define SSB_CHIPCO_OTPP_READERR 0x10000000 +#define SSB_CHIPCO_OTPP_VALUE 0x20000000 +#define SSB_CHIPCO_OTPP_READ 0x40000000 +#define SSB_CHIPCO_OTPP_START 0x80000000 +#define SSB_CHIPCO_OTPP_BUSY 0x80000000 +#define SSB_CHIPCO_IRQSTAT 0x0020 +#define SSB_CHIPCO_IRQMASK 0x0024 +#define SSB_CHIPCO_IRQ_GPIO 0x00000001 /* gpio intr */ +#define SSB_CHIPCO_IRQ_EXT 0x00000002 /* ro: ext intr pin (corerev >= 3) */ +#define SSB_CHIPCO_IRQ_WDRESET 0x80000000 /* watchdog reset occurred */ +#define SSB_CHIPCO_CHIPCTL 0x0028 /* Rev >= 11 only */ +#define SSB_CHIPCO_CHIPSTAT 0x002C /* Rev >= 11 only */ +#define SSB_CHIPCO_JCMD 0x0030 /* Rev >= 10 only */ +#define SSB_CHIPCO_JCMD_START 0x80000000 +#define SSB_CHIPCO_JCMD_BUSY 0x80000000 +#define SSB_CHIPCO_JCMD_PAUSE 0x40000000 +#define SSB_CHIPCO_JCMD0_ACC_MASK 0x0000F000 +#define SSB_CHIPCO_JCMD0_ACC_IRDR 0x00000000 +#define SSB_CHIPCO_JCMD0_ACC_DR 0x00001000 +#define SSB_CHIPCO_JCMD0_ACC_IR 0x00002000 +#define SSB_CHIPCO_JCMD0_ACC_RESET 0x00003000 +#define SSB_CHIPCO_JCMD0_ACC_IRPDR 0x00004000 +#define SSB_CHIPCO_JCMD0_ACC_PDR 0x00005000 +#define SSB_CHIPCO_JCMD0_IRW_MASK 0x00000F00 +#define SSB_CHIPCO_JCMD_ACC_MASK 0x000F0000 /* Changes for corerev 11 */ +#define SSB_CHIPCO_JCMD_ACC_IRDR 0x00000000 +#define SSB_CHIPCO_JCMD_ACC_DR 0x00010000 +#define SSB_CHIPCO_JCMD_ACC_IR 0x00020000 +#define SSB_CHIPCO_JCMD_ACC_RESET 0x00030000 +#define SSB_CHIPCO_JCMD_ACC_IRPDR 0x00040000 +#define SSB_CHIPCO_JCMD_ACC_PDR 0x00050000 +#define SSB_CHIPCO_JCMD_IRW_MASK 0x00001F00 +#define SSB_CHIPCO_JCMD_IRW_SHIFT 8 +#define SSB_CHIPCO_JCMD_DRW_MASK 0x0000003F +#define SSB_CHIPCO_JIR 0x0034 /* Rev >= 10 only */ +#define SSB_CHIPCO_JDR 0x0038 /* Rev >= 10 only */ +#define SSB_CHIPCO_JCTL 0x003C /* Rev >= 10 only */ +#define SSB_CHIPCO_JCTL_FORCE_CLK 4 /* Force clock */ +#define SSB_CHIPCO_JCTL_EXT_EN 2 /* Enable external targets */ +#define SSB_CHIPCO_JCTL_EN 1 /* Enable Jtag master */ +#define SSB_CHIPCO_FLASHCTL 0x0040 +#define SSB_CHIPCO_FLASHCTL_START 0x80000000 +#define SSB_CHIPCO_FLASHCTL_BUSY SSB_CHIPCO_FLASHCTL_START +#define SSB_CHIPCO_FLASHADDR 0x0044 +#define SSB_CHIPCO_FLASHDATA 0x0048 +#define SSB_CHIPCO_BCAST_ADDR 0x0050 +#define SSB_CHIPCO_BCAST_DATA 0x0054 +#define SSB_CHIPCO_GPIOIN 0x0060 +#define SSB_CHIPCO_GPIOOUT 0x0064 +#define SSB_CHIPCO_GPIOOUTEN 0x0068 +#define SSB_CHIPCO_GPIOCTL 0x006C +#define SSB_CHIPCO_GPIOPOL 0x0070 +#define SSB_CHIPCO_GPIOIRQ 0x0074 +#define SSB_CHIPCO_WATCHDOG 0x0080 +#define SSB_CHIPCO_GPIOTIMER 0x0088 /* LED powersave (corerev >= 16) */ +#define SSB_CHIPCO_GPIOTIMER_ONTIME_SHIFT 16 +#define SSB_CHIPCO_GPIOTOUTM 0x008C /* LED powersave (corerev >= 16) */ +#define SSB_CHIPCO_CLOCK_N 0x0090 +#define SSB_CHIPCO_CLOCK_SB 0x0094 +#define SSB_CHIPCO_CLOCK_PCI 0x0098 +#define SSB_CHIPCO_CLOCK_M2 0x009C +#define SSB_CHIPCO_CLOCK_MIPS 0x00A0 +#define SSB_CHIPCO_CLKDIV 0x00A4 /* Rev >= 3 only */ +#define SSB_CHIPCO_CLKDIV_SFLASH 0x0F000000 +#define SSB_CHIPCO_CLKDIV_SFLASH_SHIFT 24 +#define SSB_CHIPCO_CLKDIV_OTP 0x000F0000 +#define SSB_CHIPCO_CLKDIV_OTP_SHIFT 16 +#define SSB_CHIPCO_CLKDIV_JTAG 0x00000F00 +#define SSB_CHIPCO_CLKDIV_JTAG_SHIFT 8 +#define SSB_CHIPCO_CLKDIV_UART 0x000000FF +#define SSB_CHIPCO_PLLONDELAY 0x00B0 /* Rev >= 4 only */ +#define SSB_CHIPCO_FREFSELDELAY 0x00B4 /* Rev >= 4 only */ +#define SSB_CHIPCO_SLOWCLKCTL 0x00B8 /* 6 <= Rev <= 9 only */ +#define SSB_CHIPCO_SLOWCLKCTL_SRC 0x00000007 /* slow clock source mask */ +#define SSB_CHIPCO_SLOWCLKCTL_SRC_LPO 0x00000000 /* source of slow clock is LPO */ +#define SSB_CHIPCO_SLOWCLKCTL_SRC_XTAL 0x00000001 /* source of slow clock is crystal */ +#define SSB_CHIPCO_SLOECLKCTL_SRC_PCI 0x00000002 /* source of slow clock is PCI */ +#define SSB_CHIPCO_SLOWCLKCTL_LPOFREQ 0x00000200 /* LPOFreqSel, 1: 160Khz, 0: 32KHz */ +#define SSB_CHIPCO_SLOWCLKCTL_LPOPD 0x00000400 /* LPOPowerDown, 1: LPO is disabled, 0: LPO is enabled */ +#define SSB_CHIPCO_SLOWCLKCTL_FSLOW 0x00000800 /* ForceSlowClk, 1: sb/cores running on slow clock, 0: power logic control */ +#define SSB_CHIPCO_SLOWCLKCTL_IPLL 0x00001000 /* IgnorePllOffReq, 1/0: power logic ignores/honors PLL clock disable requests from core */ +#define SSB_CHIPCO_SLOWCLKCTL_ENXTAL 0x00002000 /* XtalControlEn, 1/0: power logic does/doesn't disable crystal when appropriate */ +#define SSB_CHIPCO_SLOWCLKCTL_XTALPU 0x00004000 /* XtalPU (RO), 1/0: crystal running/disabled */ +#define SSB_CHIPCO_SLOWCLKCTL_CLKDIV 0xFFFF0000 /* ClockDivider (SlowClk = 1/(4+divisor)) */ +#define SSB_CHIPCO_SLOWCLKCTL_CLKDIV_SHIFT 16 +#define SSB_CHIPCO_SYSCLKCTL 0x00C0 /* Rev >= 3 only */ +#define SSB_CHIPCO_SYSCLKCTL_IDLPEN 0x00000001 /* ILPen: Enable Idle Low Power */ +#define SSB_CHIPCO_SYSCLKCTL_ALPEN 0x00000002 /* ALPen: Enable Active Low Power */ +#define SSB_CHIPCO_SYSCLKCTL_PLLEN 0x00000004 /* ForcePLLOn */ +#define SSB_CHIPCO_SYSCLKCTL_FORCEALP 0x00000008 /* Force ALP (or HT if ALPen is not set */ +#define SSB_CHIPCO_SYSCLKCTL_FORCEHT 0x00000010 /* Force HT */ +#define SSB_CHIPCO_SYSCLKCTL_CLKDIV 0xFFFF0000 /* ClkDiv (ILP = 1/(4+divisor)) */ +#define SSB_CHIPCO_SYSCLKCTL_CLKDIV_SHIFT 16 +#define SSB_CHIPCO_CLKSTSTR 0x00C4 /* Rev >= 3 only */ +#define SSB_CHIPCO_PCMCIA_CFG 0x0100 +#define SSB_CHIPCO_PCMCIA_MEMWAIT 0x0104 +#define SSB_CHIPCO_PCMCIA_ATTRWAIT 0x0108 +#define SSB_CHIPCO_PCMCIA_IOWAIT 0x010C +#define SSB_CHIPCO_IDE_CFG 0x0110 +#define SSB_CHIPCO_IDE_MEMWAIT 0x0114 +#define SSB_CHIPCO_IDE_ATTRWAIT 0x0118 +#define SSB_CHIPCO_IDE_IOWAIT 0x011C +#define SSB_CHIPCO_PROG_CFG 0x0120 +#define SSB_CHIPCO_PROG_WAITCNT 0x0124 +#define SSB_CHIPCO_FLASH_CFG 0x0128 +#define SSB_CHIPCO_FLASH_WAITCNT 0x012C +#define SSB_CHIPCO_UART0_DATA 0x0300 +#define SSB_CHIPCO_UART0_IMR 0x0304 +#define SSB_CHIPCO_UART0_FCR 0x0308 +#define SSB_CHIPCO_UART0_LCR 0x030C +#define SSB_CHIPCO_UART0_MCR 0x0310 +#define SSB_CHIPCO_UART0_LSR 0x0314 +#define SSB_CHIPCO_UART0_MSR 0x0318 +#define SSB_CHIPCO_UART0_SCRATCH 0x031C +#define SSB_CHIPCO_UART1_DATA 0x0400 +#define SSB_CHIPCO_UART1_IMR 0x0404 +#define SSB_CHIPCO_UART1_FCR 0x0408 +#define SSB_CHIPCO_UART1_LCR 0x040C +#define SSB_CHIPCO_UART1_MCR 0x0410 +#define SSB_CHIPCO_UART1_LSR 0x0414 +#define SSB_CHIPCO_UART1_MSR 0x0418 +#define SSB_CHIPCO_UART1_SCRATCH 0x041C + + + +/** Clockcontrol masks and values **/ + +/* SSB_CHIPCO_CLOCK_N */ +#define SSB_CHIPCO_CLK_N1 0x0000003F /* n1 control */ +#define SSB_CHIPCO_CLK_N2 0x00003F00 /* n2 control */ +#define SSB_CHIPCO_CLK_N2_SHIFT 8 +#define SSB_CHIPCO_CLK_PLLC 0x000F0000 /* pll control */ +#define SSB_CHIPCO_CLK_PLLC_SHIFT 16 + +/* SSB_CHIPCO_CLOCK_SB/PCI/UART */ +#define SSB_CHIPCO_CLK_M1 0x0000003F /* m1 control */ +#define SSB_CHIPCO_CLK_M2 0x00003F00 /* m2 control */ +#define SSB_CHIPCO_CLK_M2_SHIFT 8 +#define SSB_CHIPCO_CLK_M3 0x003F0000 /* m3 control */ +#define SSB_CHIPCO_CLK_M3_SHIFT 16 +#define SSB_CHIPCO_CLK_MC 0x1F000000 /* mux control */ +#define SSB_CHIPCO_CLK_MC_SHIFT 24 + +/* N3M Clock control magic field values */ +#define SSB_CHIPCO_CLK_F6_2 0x02 /* A factor of 2 in */ +#define SSB_CHIPCO_CLK_F6_3 0x03 /* 6-bit fields like */ +#define SSB_CHIPCO_CLK_F6_4 0x05 /* N1, M1 or M3 */ +#define SSB_CHIPCO_CLK_F6_5 0x09 +#define SSB_CHIPCO_CLK_F6_6 0x11 +#define SSB_CHIPCO_CLK_F6_7 0x21 + +#define SSB_CHIPCO_CLK_F5_BIAS 5 /* 5-bit fields get this added */ + +#define SSB_CHIPCO_CLK_MC_BYPASS 0x08 +#define SSB_CHIPCO_CLK_MC_M1 0x04 +#define SSB_CHIPCO_CLK_MC_M1M2 0x02 +#define SSB_CHIPCO_CLK_MC_M1M2M3 0x01 +#define SSB_CHIPCO_CLK_MC_M1M3 0x11 + +/* Type 2 Clock control magic field values */ +#define SSB_CHIPCO_CLK_T2_BIAS 2 /* n1, n2, m1 & m3 bias */ +#define SSB_CHIPCO_CLK_T2M2_BIAS 3 /* m2 bias */ + +#define SSB_CHIPCO_CLK_T2MC_M1BYP 1 +#define SSB_CHIPCO_CLK_T2MC_M2BYP 2 +#define SSB_CHIPCO_CLK_T2MC_M3BYP 4 + +/* Type 6 Clock control magic field values */ +#define SSB_CHIPCO_CLK_T6_MMASK 1 /* bits of interest in m */ +#define SSB_CHIPCO_CLK_T6_M0 120000000 /* sb clock for m = 0 */ +#define SSB_CHIPCO_CLK_T6_M1 100000000 /* sb clock for m = 1 */ +#define SSB_CHIPCO_CLK_SB2MIPS_T6(sb) (2 * (sb)) + +/* Common clock base */ +#define SSB_CHIPCO_CLK_BASE1 24000000 /* Half the clock freq */ +#define SSB_CHIPCO_CLK_BASE2 12500000 /* Alternate crystal on some PLL's */ + +/* Clock control values for 200Mhz in 5350 */ +#define SSB_CHIPCO_CLK_5350_N 0x0311 +#define SSB_CHIPCO_CLK_5350_M 0x04020009 + + +/** Bits in the config registers **/ + +#define SSB_CHIPCO_CFG_EN 0x0001 /* Enable */ +#define SSB_CHIPCO_CFG_EXTM 0x000E /* Extif Mode */ +#define SSB_CHIPCO_CFG_EXTM_ASYNC 0x0002 /* Async/Parallel flash */ +#define SSB_CHIPCO_CFG_EXTM_SYNC 0x0004 /* Synchronous */ +#define SSB_CHIPCO_CFG_EXTM_PCMCIA 0x0008 /* PCMCIA */ +#define SSB_CHIPCO_CFG_EXTM_IDE 0x000A /* IDE */ +#define SSB_CHIPCO_CFG_DS16 0x0010 /* Data size, 0=8bit, 1=16bit */ +#define SSB_CHIPCO_CFG_CLKDIV 0x0060 /* Sync: Clock divisor */ +#define SSB_CHIPCO_CFG_CLKEN 0x0080 /* Sync: Clock enable */ +#define SSB_CHIPCO_CFG_BSTRO 0x0100 /* Sync: Size/Bytestrobe */ + + +/** Flash-specific control/status values */ + +/* flashcontrol opcodes for ST flashes */ +#define SSB_CHIPCO_FLASHCTL_ST_WREN 0x0006 /* Write Enable */ +#define SSB_CHIPCO_FLASHCTL_ST_WRDIS 0x0004 /* Write Disable */ +#define SSB_CHIPCO_FLASHCTL_ST_RDSR 0x0105 /* Read Status Register */ +#define SSB_CHIPCO_FLASHCTL_ST_WRSR 0x0101 /* Write Status Register */ +#define SSB_CHIPCO_FLASHCTL_ST_READ 0x0303 /* Read Data Bytes */ +#define SSB_CHIPCO_FLASHCTL_ST_PP 0x0302 /* Page Program */ +#define SSB_CHIPCO_FLASHCTL_ST_SE 0x02D8 /* Sector Erase */ +#define SSB_CHIPCO_FLASHCTL_ST_BE 0x00C7 /* Bulk Erase */ +#define SSB_CHIPCO_FLASHCTL_ST_DP 0x00B9 /* Deep Power-down */ +#define SSB_CHIPCO_FLASHCTL_ST_RSIG 0x03AB /* Read Electronic Signature */ + +/* Status register bits for ST flashes */ +#define SSB_CHIPCO_FLASHSTA_ST_WIP 0x01 /* Write In Progress */ +#define SSB_CHIPCO_FLASHSTA_ST_WEL 0x02 /* Write Enable Latch */ +#define SSB_CHIPCO_FLASHSTA_ST_BP 0x1C /* Block Protect */ +#define SSB_CHIPCO_FLASHSTA_ST_BP_SHIFT 2 +#define SSB_CHIPCO_FLASHSTA_ST_SRWD 0x80 /* Status Register Write Disable */ + +/* flashcontrol opcodes for Atmel flashes */ +#define SSB_CHIPCO_FLASHCTL_AT_READ 0x07E8 +#define SSB_CHIPCO_FLASHCTL_AT_PAGE_READ 0x07D2 +#define SSB_CHIPCO_FLASHCTL_AT_BUF1_READ /* FIXME */ +#define SSB_CHIPCO_FLASHCTL_AT_BUF2_READ /* FIXME */ +#define SSB_CHIPCO_FLASHCTL_AT_STATUS 0x01D7 +#define SSB_CHIPCO_FLASHCTL_AT_BUF1_WRITE 0x0384 +#define SSB_CHIPCO_FLASHCTL_AT_BUF2_WRITE 0x0387 +#define SSB_CHIPCO_FLASHCTL_AT_BUF1_ERASE_PRGM 0x0283 /* Erase program */ +#define SSB_CHIPCO_FLASHCTL_AT_BUF2_ERASE_PRGM 0x0286 /* Erase program */ +#define SSB_CHIPCO_FLASHCTL_AT_BUF1_PROGRAM 0x0288 +#define SSB_CHIPCO_FLASHCTL_AT_BUF2_PROGRAM 0x0289 +#define SSB_CHIPCO_FLASHCTL_AT_PAGE_ERASE 0x0281 +#define SSB_CHIPCO_FLASHCTL_AT_BLOCK_ERASE 0x0250 +#define SSB_CHIPCO_FLASHCTL_AT_BUF1_WRER_PRGM 0x0382 /* Write erase program */ +#define SSB_CHIPCO_FLASHCTL_AT_BUF2_WRER_PRGM 0x0385 /* Write erase program */ +#define SSB_CHIPCO_FLASHCTL_AT_BUF1_LOAD 0x0253 +#define SSB_CHIPCO_FLASHCTL_AT_BUF2_LOAD 0x0255 +#define SSB_CHIPCO_FLASHCTL_AT_BUF1_COMPARE 0x0260 +#define SSB_CHIPCO_FLASHCTL_AT_BUF2_COMPARE 0x0261 +#define SSB_CHIPCO_FLASHCTL_AT_BUF1_REPROGRAM 0x0258 +#define SSB_CHIPCO_FLASHCTL_AT_BUF2_REPROGRAM 0x0259 + +/* Status register bits for Atmel flashes */ +#define SSB_CHIPCO_FLASHSTA_AT_READY 0x80 +#define SSB_CHIPCO_FLASHSTA_AT_MISMATCH 0x40 +#define SSB_CHIPCO_FLASHSTA_AT_ID 0x38 +#define SSB_CHIPCO_FLASHSTA_AT_ID_SHIFT 3 + + +/** OTP **/ + +/* OTP regions */ +#define SSB_CHIPCO_OTP_HW_REGION SSB_CHIPCO_OTPS_HW_PROTECT +#define SSB_CHIPCO_OTP_SW_REGION SSB_CHIPCO_OTPS_SW_PROTECT +#define SSB_CHIPCO_OTP_CID_REGION SSB_CHIPCO_OTPS_CID_PROTECT + +/* OTP regions (Byte offsets from otp size) */ +#define SSB_CHIPCO_OTP_SWLIM_OFF (-8) +#define SSB_CHIPCO_OTP_CIDBASE_OFF 0 +#define SSB_CHIPCO_OTP_CIDLIM_OFF 8 + +/* Predefined OTP words (Word offset from otp size) */ +#define SSB_CHIPCO_OTP_BOUNDARY_OFF (-4) +#define SSB_CHIPCO_OTP_HWSIGN_OFF (-3) +#define SSB_CHIPCO_OTP_SWSIGN_OFF (-2) +#define SSB_CHIPCO_OTP_CIDSIGN_OFF (-1) + +#define SSB_CHIPCO_OTP_CID_OFF 0 +#define SSB_CHIPCO_OTP_PKG_OFF 1 +#define SSB_CHIPCO_OTP_FID_OFF 2 +#define SSB_CHIPCO_OTP_RSV_OFF 3 +#define SSB_CHIPCO_OTP_LIM_OFF 4 + +#define SSB_CHIPCO_OTP_SIGNATURE 0x578A +#define SSB_CHIPCO_OTP_MAGIC 0x4E56 + + +struct ssb_device; +struct ssb_serial_port; + +struct ssb_chipcommon { + struct ssb_device *dev; + u32 capabilities; + /* Fast Powerup Delay constant */ + u16 fast_pwrup_delay; +}; + +extern void ssb_chipcommon_init(struct ssb_chipcommon *cc); + +#include +extern void ssb_chipco_suspend(struct ssb_chipcommon *cc, pm_message_t state); +extern void ssb_chipco_resume(struct ssb_chipcommon *cc); + +extern void ssb_chipco_get_clockcpu(struct ssb_chipcommon *cc, + u32 *plltype, u32 *n, u32 *m); +extern void ssb_chipco_get_clockcontrol(struct ssb_chipcommon *cc, + u32 *plltype, u32 *n, u32 *m); +extern void ssb_chipco_timing_init(struct ssb_chipcommon *cc, + unsigned long ns_per_cycle); + +enum ssb_clkmode { + SSB_CLKMODE_SLOW, + SSB_CLKMODE_FAST, + SSB_CLKMODE_DYNAMIC, +}; + +extern void ssb_chipco_set_clockmode(struct ssb_chipcommon *cc, + enum ssb_clkmode mode); + +extern void ssb_chipco_watchdog_timer_set(struct ssb_chipcommon *cc, + u32 ticks); + +u32 ssb_chipco_gpio_in(struct ssb_chipcommon *cc, u32 mask); + +void ssb_chipco_gpio_out(struct ssb_chipcommon *cc, u32 mask, u32 value); + +void ssb_chipco_gpio_outen(struct ssb_chipcommon *cc, u32 mask, u32 value); + +#ifdef CONFIG_SSB_SERIAL +extern int ssb_chipco_serial_init(struct ssb_chipcommon *cc, + struct ssb_serial_port *ports); +#endif /* CONFIG_SSB_SERIAL */ + +#endif /* LINUX_SSB_CHIPCO_H_ */ diff --git a/include/linux/ssb/ssb_driver_extif.h b/include/linux/ssb/ssb_driver_extif.h new file mode 100644 index 000000000000..a9164357b5ae --- /dev/null +++ b/include/linux/ssb/ssb_driver_extif.h @@ -0,0 +1,204 @@ +/* + * Hardware-specific External Interface I/O core definitions + * for the BCM47xx family of SiliconBackplane-based chips. + * + * The External Interface core supports a total of three external chip selects + * supporting external interfaces. One of the external chip selects is + * used for Flash, one is used for PCMCIA, and the other may be + * programmed to support either a synchronous interface or an + * asynchronous interface. The asynchronous interface can be used to + * support external devices such as UARTs and the BCM2019 Bluetooth + * baseband processor. + * The external interface core also contains 2 on-chip 16550 UARTs, clock + * frequency control, a watchdog interrupt timer, and a GPIO interface. + * + * Copyright 2005, Broadcom Corporation + * Copyright 2006, Michael Buesch + * + * Licensed under the GPL version 2. See COPYING for details. + */ +#ifndef LINUX_SSB_EXTIFCORE_H_ +#define LINUX_SSB_EXTIFCORE_H_ + +/* external interface address space */ +#define SSB_EXTIF_PCMCIA_MEMBASE(x) (x) +#define SSB_EXTIF_PCMCIA_IOBASE(x) ((x) + 0x100000) +#define SSB_EXTIF_PCMCIA_CFGBASE(x) ((x) + 0x200000) +#define SSB_EXTIF_CFGIF_BASE(x) ((x) + 0x800000) +#define SSB_EXTIF_FLASH_BASE(x) ((x) + 0xc00000) + +#define SSB_EXTIF_NR_GPIOOUT 5 +/* GPIO NOTE: + * The multiple instances of output and output enable registers + * are present to allow driver software for multiple cores to control + * gpio outputs without needing to share a single register pair. + * Use the following helper macro to get a register offset value. + */ +#define SSB_EXTIF_GPIO_OUT(index) ({ \ + BUILD_BUG_ON(index >= SSB_EXTIF_NR_GPIOOUT); \ + SSB_EXTIF_GPIO_OUT_BASE + ((index) * 8); \ + }) +#define SSB_EXTIF_GPIO_OUTEN(index) ({ \ + BUILD_BUG_ON(index >= SSB_EXTIF_NR_GPIOOUT); \ + SSB_EXTIF_GPIO_OUTEN_BASE + ((index) * 8); \ + }) + +/** EXTIF core registers **/ + +#define SSB_EXTIF_CTL 0x0000 +#define SSB_EXTIF_CTL_UARTEN (1 << 0) /* UART enable */ +#define SSB_EXTIF_EXTSTAT 0x0004 +#define SSB_EXTIF_EXTSTAT_EMODE (1 << 0) /* Endian mode (ro) */ +#define SSB_EXTIF_EXTSTAT_EIRQPIN (1 << 1) /* External interrupt pin (ro) */ +#define SSB_EXTIF_EXTSTAT_GPIOIRQPIN (1 << 2) /* GPIO interrupt pin (ro) */ +#define SSB_EXTIF_PCMCIA_CFG 0x0010 +#define SSB_EXTIF_PCMCIA_MEMWAIT 0x0014 +#define SSB_EXTIF_PCMCIA_ATTRWAIT 0x0018 +#define SSB_EXTIF_PCMCIA_IOWAIT 0x001C +#define SSB_EXTIF_PROG_CFG 0x0020 +#define SSB_EXTIF_PROG_WAITCNT 0x0024 +#define SSB_EXTIF_FLASH_CFG 0x0028 +#define SSB_EXTIF_FLASH_WAITCNT 0x002C +#define SSB_EXTIF_WATCHDOG 0x0040 +#define SSB_EXTIF_CLOCK_N 0x0044 +#define SSB_EXTIF_CLOCK_SB 0x0048 +#define SSB_EXTIF_CLOCK_PCI 0x004C +#define SSB_EXTIF_CLOCK_MII 0x0050 +#define SSB_EXTIF_GPIO_IN 0x0060 +#define SSB_EXTIF_GPIO_OUT_BASE 0x0064 +#define SSB_EXTIF_GPIO_OUTEN_BASE 0x0068 +#define SSB_EXTIF_EJTAG_OUTEN 0x0090 +#define SSB_EXTIF_GPIO_INTPOL 0x0094 +#define SSB_EXTIF_GPIO_INTMASK 0x0098 +#define SSB_EXTIF_UART_DATA 0x0300 +#define SSB_EXTIF_UART_TIMER 0x0310 +#define SSB_EXTIF_UART_FCR 0x0320 +#define SSB_EXTIF_UART_LCR 0x0330 +#define SSB_EXTIF_UART_MCR 0x0340 +#define SSB_EXTIF_UART_LSR 0x0350 +#define SSB_EXTIF_UART_MSR 0x0360 +#define SSB_EXTIF_UART_SCRATCH 0x0370 + + + + +/* pcmcia/prog/flash_config */ +#define SSB_EXTCFG_EN (1 << 0) /* enable */ +#define SSB_EXTCFG_MODE 0xE /* mode */ +#define SSB_EXTCFG_MODE_SHIFT 1 +#define SSB_EXTCFG_MODE_FLASH 0x0 /* flash/asynchronous mode */ +#define SSB_EXTCFG_MODE_SYNC 0x2 /* synchronous mode */ +#define SSB_EXTCFG_MODE_PCMCIA 0x4 /* pcmcia mode */ +#define SSB_EXTCFG_DS16 (1 << 4) /* destsize: 0=8bit, 1=16bit */ +#define SSB_EXTCFG_BSWAP (1 << 5) /* byteswap */ +#define SSB_EXTCFG_CLKDIV 0xC0 /* clock divider */ +#define SSB_EXTCFG_CLKDIV_SHIFT 6 +#define SSB_EXTCFG_CLKDIV_2 0x0 /* backplane/2 */ +#define SSB_EXTCFG_CLKDIV_3 0x40 /* backplane/3 */ +#define SSB_EXTCFG_CLKDIV_4 0x80 /* backplane/4 */ +#define SSB_EXTCFG_CLKEN (1 << 8) /* clock enable */ +#define SSB_EXTCFG_STROBE (1 << 9) /* size/bytestrobe (synch only) */ + +/* pcmcia_memwait */ +#define SSB_PCMCIA_MEMW_0 0x0000003F /* waitcount0 */ +#define SSB_PCMCIA_MEMW_1 0x00001F00 /* waitcount1 */ +#define SSB_PCMCIA_MEMW_1_SHIFT 8 +#define SSB_PCMCIA_MEMW_2 0x001F0000 /* waitcount2 */ +#define SSB_PCMCIA_MEMW_2_SHIFT 16 +#define SSB_PCMCIA_MEMW_3 0x1F000000 /* waitcount3 */ +#define SSB_PCMCIA_MEMW_3_SHIFT 24 + +/* pcmcia_attrwait */ +#define SSB_PCMCIA_ATTW_0 0x0000003F /* waitcount0 */ +#define SSB_PCMCIA_ATTW_1 0x00001F00 /* waitcount1 */ +#define SSB_PCMCIA_ATTW_1_SHIFT 8 +#define SSB_PCMCIA_ATTW_2 0x001F0000 /* waitcount2 */ +#define SSB_PCMCIA_ATTW_2_SHIFT 16 +#define SSB_PCMCIA_ATTW_3 0x1F000000 /* waitcount3 */ +#define SSB_PCMCIA_ATTW_3_SHIFT 24 + +/* pcmcia_iowait */ +#define SSB_PCMCIA_IOW_0 0x0000003F /* waitcount0 */ +#define SSB_PCMCIA_IOW_1 0x00001F00 /* waitcount1 */ +#define SSB_PCMCIA_IOW_1_SHIFT 8 +#define SSB_PCMCIA_IOW_2 0x001F0000 /* waitcount2 */ +#define SSB_PCMCIA_IOW_2_SHIFT 16 +#define SSB_PCMCIA_IOW_3 0x1F000000 /* waitcount3 */ +#define SSB_PCMCIA_IOW_3_SHIFT 24 + +/* prog_waitcount */ +#define SSB_PROG_WCNT_0 0x0000001F /* waitcount0 */ +#define SSB_PROG_WCNT_1 0x00001F00 /* waitcount1 */ +#define SSB_PROG_WCNT_1_SHIFT 8 +#define SSB_PROG_WCNT_2 0x001F0000 /* waitcount2 */ +#define SSB_PROG_WCNT_2_SHIFT 16 +#define SSB_PROG_WCNT_3 0x1F000000 /* waitcount3 */ +#define SSB_PROG_WCNT_3_SHIFT 24 + +#define SSB_PROG_W0 0x0000000C +#define SSB_PROG_W1 0x00000A00 +#define SSB_PROG_W2 0x00020000 +#define SSB_PROG_W3 0x01000000 + +/* flash_waitcount */ +#define SSB_FLASH_WCNT_0 0x0000001F /* waitcount0 */ +#define SSB_FLASH_WCNT_1 0x00001F00 /* waitcount1 */ +#define SSB_FLASH_WCNT_1_SHIFT 8 +#define SSB_FLASH_WCNT_2 0x001F0000 /* waitcount2 */ +#define SSB_FLASH_WCNT_2_SHIFT 16 +#define SSB_FLASH_WCNT_3 0x1F000000 /* waitcount3 */ +#define SSB_FLASH_WCNT_3_SHIFT 24 + +/* watchdog */ +#define SSB_EXTIF_WATCHDOG_CLK 48000000 /* Hz */ + + + +#ifdef CONFIG_SSB_DRIVER_EXTIF + +struct ssb_extif { + struct ssb_device *dev; +}; + +static inline bool ssb_extif_available(struct ssb_extif *extif) +{ + return (extif->dev != NULL); +} + +extern void ssb_extif_get_clockcontrol(struct ssb_extif *extif, + u32 *plltype, u32 *n, u32 *m); + +extern void ssb_extif_timing_init(struct ssb_extif *extif, + unsigned long ns); + +u32 ssb_extif_gpio_in(struct ssb_extif *extif, u32 mask); + +void ssb_extif_gpio_out(struct ssb_extif *extif, u32 mask, u32 value); + +void ssb_extif_gpio_outen(struct ssb_extif *extif, u32 mask, u32 value); + +#ifdef CONFIG_SSB_SERIAL +extern int ssb_extif_serial_init(struct ssb_extif *extif, + struct ssb_serial_port *ports); +#endif /* CONFIG_SSB_SERIAL */ + + +#else /* CONFIG_SSB_DRIVER_EXTIF */ +/* extif disabled */ + +struct ssb_extif { +}; + +static inline bool ssb_extif_available(struct ssb_extif *extif) +{ + return 0; +} + +static inline +void ssb_extif_get_clockcontrol(struct ssb_extif *extif, + u32 *plltype, u32 *n, u32 *m) +{ +} + +#endif /* CONFIG_SSB_DRIVER_EXTIF */ +#endif /* LINUX_SSB_EXTIFCORE_H_ */ diff --git a/include/linux/ssb/ssb_driver_mips.h b/include/linux/ssb/ssb_driver_mips.h new file mode 100644 index 000000000000..5f44e9740cd2 --- /dev/null +++ b/include/linux/ssb/ssb_driver_mips.h @@ -0,0 +1,46 @@ +#ifndef LINUX_SSB_MIPSCORE_H_ +#define LINUX_SSB_MIPSCORE_H_ + +#ifdef CONFIG_SSB_DRIVER_MIPS + +struct ssb_device; + +struct ssb_serial_port { + void *regs; + unsigned long clockspeed; + unsigned int irq; + unsigned int baud_base; + unsigned int reg_shift; +}; + + +struct ssb_mipscore { + struct ssb_device *dev; + + int nr_serial_ports; + struct ssb_serial_port serial_ports[4]; + + u8 flash_buswidth; + u32 flash_window; + u32 flash_window_size; +}; + +extern void ssb_mipscore_init(struct ssb_mipscore *mcore); +extern u32 ssb_cpu_clock(struct ssb_mipscore *mcore); + +extern unsigned int ssb_mips_irq(struct ssb_device *dev); + + +#else /* CONFIG_SSB_DRIVER_MIPS */ + +struct ssb_mipscore { +}; + +static inline +void ssb_mipscore_init(struct ssb_mipscore *mcore) +{ +} + +#endif /* CONFIG_SSB_DRIVER_MIPS */ + +#endif /* LINUX_SSB_MIPSCORE_H_ */ diff --git a/include/linux/ssb/ssb_driver_pci.h b/include/linux/ssb/ssb_driver_pci.h new file mode 100644 index 000000000000..9cfffb7b1a27 --- /dev/null +++ b/include/linux/ssb/ssb_driver_pci.h @@ -0,0 +1,106 @@ +#ifndef LINUX_SSB_PCICORE_H_ +#define LINUX_SSB_PCICORE_H_ + +#ifdef CONFIG_SSB_DRIVER_PCICORE + +/* PCI core registers. */ +#define SSB_PCICORE_CTL 0x0000 /* PCI Control */ +#define SSB_PCICORE_CTL_RST_OE 0x00000001 /* PCI_RESET Output Enable */ +#define SSB_PCICORE_CTL_RST 0x00000002 /* PCI_RESET driven out to pin */ +#define SSB_PCICORE_CTL_CLK_OE 0x00000004 /* Clock gate Output Enable */ +#define SSB_PCICORE_CTL_CLK 0x00000008 /* Gate for clock driven out to pin */ +#define SSB_PCICORE_ARBCTL 0x0010 /* PCI Arbiter Control */ +#define SSB_PCICORE_ARBCTL_INTERN 0x00000001 /* Use internal arbiter */ +#define SSB_PCICORE_ARBCTL_EXTERN 0x00000002 /* Use external arbiter */ +#define SSB_PCICORE_ARBCTL_PARKID 0x00000006 /* Mask, selects which agent is parked on an idle bus */ +#define SSB_PCICORE_ARBCTL_PARKID_LAST 0x00000000 /* Last requestor */ +#define SSB_PCICORE_ARBCTL_PARKID_4710 0x00000002 /* 4710 */ +#define SSB_PCICORE_ARBCTL_PARKID_EXT0 0x00000004 /* External requestor 0 */ +#define SSB_PCICORE_ARBCTL_PARKID_EXT1 0x00000006 /* External requestor 1 */ +#define SSB_PCICORE_ISTAT 0x0020 /* Interrupt status */ +#define SSB_PCICORE_ISTAT_INTA 0x00000001 /* PCI INTA# */ +#define SSB_PCICORE_ISTAT_INTB 0x00000002 /* PCI INTB# */ +#define SSB_PCICORE_ISTAT_SERR 0x00000004 /* PCI SERR# (write to clear) */ +#define SSB_PCICORE_ISTAT_PERR 0x00000008 /* PCI PERR# (write to clear) */ +#define SSB_PCICORE_ISTAT_PME 0x00000010 /* PCI PME# */ +#define SSB_PCICORE_IMASK 0x0024 /* Interrupt mask */ +#define SSB_PCICORE_IMASK_INTA 0x00000001 /* PCI INTA# */ +#define SSB_PCICORE_IMASK_INTB 0x00000002 /* PCI INTB# */ +#define SSB_PCICORE_IMASK_SERR 0x00000004 /* PCI SERR# */ +#define SSB_PCICORE_IMASK_PERR 0x00000008 /* PCI PERR# */ +#define SSB_PCICORE_IMASK_PME 0x00000010 /* PCI PME# */ +#define SSB_PCICORE_MBOX 0x0028 /* Backplane to PCI Mailbox */ +#define SSB_PCICORE_MBOX_F0_0 0x00000100 /* PCI function 0, INT 0 */ +#define SSB_PCICORE_MBOX_F0_1 0x00000200 /* PCI function 0, INT 1 */ +#define SSB_PCICORE_MBOX_F1_0 0x00000400 /* PCI function 1, INT 0 */ +#define SSB_PCICORE_MBOX_F1_1 0x00000800 /* PCI function 1, INT 1 */ +#define SSB_PCICORE_MBOX_F2_0 0x00001000 /* PCI function 2, INT 0 */ +#define SSB_PCICORE_MBOX_F2_1 0x00002000 /* PCI function 2, INT 1 */ +#define SSB_PCICORE_MBOX_F3_0 0x00004000 /* PCI function 3, INT 0 */ +#define SSB_PCICORE_MBOX_F3_1 0x00008000 /* PCI function 3, INT 1 */ +#define SSB_PCICORE_BCAST_ADDR 0x0050 /* Backplane Broadcast Address */ +#define SSB_PCICORE_BCAST_ADDR_MASK 0x000000FF +#define SSB_PCICORE_BCAST_DATA 0x0054 /* Backplane Broadcast Data */ +#define SSB_PCICORE_GPIO_IN 0x0060 /* rev >= 2 only */ +#define SSB_PCICORE_GPIO_OUT 0x0064 /* rev >= 2 only */ +#define SSB_PCICORE_GPIO_ENABLE 0x0068 /* rev >= 2 only */ +#define SSB_PCICORE_GPIO_CTL 0x006C /* rev >= 2 only */ +#define SSB_PCICORE_SBTOPCI0 0x0100 /* Backplane to PCI translation 0 (sbtopci0) */ +#define SSB_PCICORE_SBTOPCI0_MASK 0xFC000000 +#define SSB_PCICORE_SBTOPCI1 0x0104 /* Backplane to PCI translation 1 (sbtopci1) */ +#define SSB_PCICORE_SBTOPCI1_MASK 0xFC000000 +#define SSB_PCICORE_SBTOPCI2 0x0108 /* Backplane to PCI translation 2 (sbtopci2) */ +#define SSB_PCICORE_SBTOPCI2_MASK 0xC0000000 + +/* SBtoPCIx */ +#define SSB_PCICORE_SBTOPCI_MEM 0x00000000 +#define SSB_PCICORE_SBTOPCI_IO 0x00000001 +#define SSB_PCICORE_SBTOPCI_CFG0 0x00000002 +#define SSB_PCICORE_SBTOPCI_CFG1 0x00000003 +#define SSB_PCICORE_SBTOPCI_PREF 0x00000004 /* Prefetch enable */ +#define SSB_PCICORE_SBTOPCI_BURST 0x00000008 /* Burst enable */ +#define SSB_PCICORE_SBTOPCI_MRM 0x00000020 /* Memory Read Multiple */ +#define SSB_PCICORE_SBTOPCI_RC 0x00000030 /* Read Command mask (rev >= 11) */ +#define SSB_PCICORE_SBTOPCI_RC_READ 0x00000000 /* Memory read */ +#define SSB_PCICORE_SBTOPCI_RC_READL 0x00000010 /* Memory read line */ +#define SSB_PCICORE_SBTOPCI_RC_READM 0x00000020 /* Memory read multiple */ + + +/* PCIcore specific boardflags */ +#define SSB_PCICORE_BFL_NOPCI 0x00000400 /* Board leaves PCI floating */ + + +struct ssb_pcicore { + struct ssb_device *dev; + u8 setup_done:1; + u8 hostmode:1; + u8 cardbusmode:1; +}; + +extern void ssb_pcicore_init(struct ssb_pcicore *pc); + +/* Enable IRQ routing for a specific device */ +extern int ssb_pcicore_dev_irqvecs_enable(struct ssb_pcicore *pc, + struct ssb_device *dev); + + +#else /* CONFIG_SSB_DRIVER_PCICORE */ + + +struct ssb_pcicore { +}; + +static inline +void ssb_pcicore_init(struct ssb_pcicore *pc) +{ +} + +static inline +int ssb_pcicore_dev_irqvecs_enable(struct ssb_pcicore *pc, + struct ssb_device *dev) +{ + return 0; +} + +#endif /* CONFIG_SSB_DRIVER_PCICORE */ +#endif /* LINUX_SSB_PCICORE_H_ */ diff --git a/include/linux/ssb/ssb_regs.h b/include/linux/ssb/ssb_regs.h new file mode 100644 index 000000000000..47c7c71a5acf --- /dev/null +++ b/include/linux/ssb/ssb_regs.h @@ -0,0 +1,292 @@ +#ifndef LINUX_SSB_REGS_H_ +#define LINUX_SSB_REGS_H_ + + +/* SiliconBackplane Address Map. + * All regions may not exist on all chips. + */ +#define SSB_SDRAM_BASE 0x00000000U /* Physical SDRAM */ +#define SSB_PCI_MEM 0x08000000U /* Host Mode sb2pcitranslation0 (64 MB) */ +#define SSB_PCI_CFG 0x0c000000U /* Host Mode sb2pcitranslation1 (64 MB) */ +#define SSB_SDRAM_SWAPPED 0x10000000U /* Byteswapped Physical SDRAM */ +#define SSB_ENUM_BASE 0x18000000U /* Enumeration space base */ +#define SSB_ENUM_LIMIT 0x18010000U /* Enumeration space limit */ + +#define SSB_FLASH2 0x1c000000U /* Flash Region 2 (region 1 shadowed here) */ +#define SSB_FLASH2_SZ 0x02000000U /* Size of Flash Region 2 */ + +#define SSB_EXTIF_BASE 0x1f000000U /* External Interface region base address */ +#define SSB_FLASH1 0x1fc00000U /* Flash Region 1 */ +#define SSB_FLASH1_SZ 0x00400000U /* Size of Flash Region 1 */ + +#define SSB_PCI_DMA 0x40000000U /* Client Mode sb2pcitranslation2 (1 GB) */ +#define SSB_PCI_DMA_SZ 0x40000000U /* Client Mode sb2pcitranslation2 size in bytes */ +#define SSB_PCIE_DMA_L32 0x00000000U /* PCIE Client Mode sb2pcitranslation2 (2 ZettaBytes), low 32 bits */ +#define SSB_PCIE_DMA_H32 0x80000000U /* PCIE Client Mode sb2pcitranslation2 (2 ZettaBytes), high 32 bits */ +#define SSB_EUART (SSB_EXTIF_BASE + 0x00800000) +#define SSB_LED (SSB_EXTIF_BASE + 0x00900000) + + +/* Enumeration space constants */ +#define SSB_CORE_SIZE 0x1000 /* Size of a core MMIO area */ +#define SSB_MAX_NR_CORES ((SSB_ENUM_LIMIT - SSB_ENUM_BASE) / SSB_CORE_SIZE) + + +/* mips address */ +#define SSB_EJTAG 0xff200000 /* MIPS EJTAG space (2M) */ + + +/* SSB PCI config space registers. */ +#define SSB_PMCSR 0x44 +#define SSB_PE 0x100 +#define SSB_BAR0_WIN 0x80 /* Backplane address space 0 */ +#define SSB_BAR1_WIN 0x84 /* Backplane address space 1 */ +#define SSB_SPROMCTL 0x88 /* SPROM control */ +#define SSB_SPROMCTL_WE 0x10 /* SPROM write enable */ +#define SSB_BAR1_CONTROL 0x8c /* Address space 1 burst control */ +#define SSB_PCI_IRQS 0x90 /* PCI interrupts */ +#define SSB_PCI_IRQMASK 0x94 /* PCI IRQ control and mask (pcirev >= 6 only) */ +#define SSB_BACKPLANE_IRQS 0x98 /* Backplane Interrupts */ +#define SSB_GPIO_IN 0xB0 /* GPIO Input (pcirev >= 3 only) */ +#define SSB_GPIO_OUT 0xB4 /* GPIO Output (pcirev >= 3 only) */ +#define SSB_GPIO_OUT_ENABLE 0xB8 /* GPIO Output Enable/Disable (pcirev >= 3 only) */ +#define SSB_GPIO_SCS 0x10 /* PCI config space bit 4 for 4306c0 slow clock source */ +#define SSB_GPIO_HWRAD 0x20 /* PCI config space GPIO 13 for hw radio disable */ +#define SSB_GPIO_XTAL 0x40 /* PCI config space GPIO 14 for Xtal powerup */ +#define SSB_GPIO_PLL 0x80 /* PCI config space GPIO 15 for PLL powerdown */ + + +#define SSB_BAR0_MAX_RETRIES 50 + +/* Silicon backplane configuration register definitions */ +#define SSB_IPSFLAG 0x0F08 +#define SSB_IPSFLAG_IRQ1 0x0000003F /* which sbflags get routed to mips interrupt 1 */ +#define SSB_IPSFLAG_IRQ1_SHIFT 0 +#define SSB_IPSFLAG_IRQ2 0x00003F00 /* which sbflags get routed to mips interrupt 2 */ +#define SSB_IPSFLAG_IRQ2_SHIFT 8 +#define SSB_IPSFLAG_IRQ3 0x003F0000 /* which sbflags get routed to mips interrupt 3 */ +#define SSB_IPSFLAG_IRQ3_SHIFT 16 +#define SSB_IPSFLAG_IRQ4 0x3F000000 /* which sbflags get routed to mips interrupt 4 */ +#define SSB_IPSFLAG_IRQ4_SHIFT 24 +#define SSB_TPSFLAG 0x0F18 +#define SSB_TPSFLAG_BPFLAG 0x0000003F /* Backplane flag # */ +#define SSB_TPSFLAG_ALWAYSIRQ 0x00000040 /* IRQ is always sent on the Backplane */ +#define SSB_TMERRLOGA 0x0F48 +#define SSB_TMERRLOG 0x0F50 +#define SSB_ADMATCH3 0x0F60 +#define SSB_ADMATCH2 0x0F68 +#define SSB_ADMATCH1 0x0F70 +#define SSB_IMSTATE 0x0F90 /* SB Initiator Agent State */ +#define SSB_IMSTATE_PC 0x0000000f /* Pipe Count */ +#define SSB_IMSTATE_AP_MASK 0x00000030 /* Arbitration Priority */ +#define SSB_IMSTATE_AP_BOTH 0x00000000 /* Use both timeslices and token */ +#define SSB_IMSTATE_AP_TS 0x00000010 /* Use timeslices only */ +#define SSB_IMSTATE_AP_TK 0x00000020 /* Use token only */ +#define SSB_IMSTATE_AP_RSV 0x00000030 /* Reserved */ +#define SSB_IMSTATE_IBE 0x00020000 /* In Band Error */ +#define SSB_IMSTATE_TO 0x00040000 /* Timeout */ +#define SSB_INTVEC 0x0F94 /* SB Interrupt Mask */ +#define SSB_INTVEC_PCI 0x00000001 /* Enable interrupts for PCI */ +#define SSB_INTVEC_ENET0 0x00000002 /* Enable interrupts for enet 0 */ +#define SSB_INTVEC_ILINE20 0x00000004 /* Enable interrupts for iline20 */ +#define SSB_INTVEC_CODEC 0x00000008 /* Enable interrupts for v90 codec */ +#define SSB_INTVEC_USB 0x00000010 /* Enable interrupts for usb */ +#define SSB_INTVEC_EXTIF 0x00000020 /* Enable interrupts for external i/f */ +#define SSB_INTVEC_ENET1 0x00000040 /* Enable interrupts for enet 1 */ +#define SSB_TMSLOW 0x0F98 /* SB Target State Low */ +#define SSB_TMSLOW_RESET 0x00000001 /* Reset */ +#define SSB_TMSLOW_REJECT_22 0x00000002 /* Reject (Backplane rev 2.2) */ +#define SSB_TMSLOW_REJECT_23 0x00000004 /* Reject (Backplane rev 2.3) */ +#define SSB_TMSLOW_CLOCK 0x00010000 /* Clock Enable */ +#define SSB_TMSLOW_FGC 0x00020000 /* Force Gated Clocks On */ +#define SSB_TMSLOW_PE 0x40000000 /* Power Management Enable */ +#define SSB_TMSLOW_BE 0x80000000 /* BIST Enable */ +#define SSB_TMSHIGH 0x0F9C /* SB Target State High */ +#define SSB_TMSHIGH_SERR 0x00000001 /* S-error */ +#define SSB_TMSHIGH_INT 0x00000002 /* Interrupt */ +#define SSB_TMSHIGH_BUSY 0x00000004 /* Busy */ +#define SSB_TMSHIGH_TO 0x00000020 /* Timeout. Backplane rev >= 2.3 only */ +#define SSB_TMSHIGH_COREFL 0x1FFF0000 /* Core specific flags */ +#define SSB_TMSHIGH_COREFL_SHIFT 16 +#define SSB_TMSHIGH_DMA64 0x10000000 /* 64bit DMA supported */ +#define SSB_TMSHIGH_GCR 0x20000000 /* Gated Clock Request */ +#define SSB_TMSHIGH_BISTF 0x40000000 /* BIST Failed */ +#define SSB_TMSHIGH_BISTD 0x80000000 /* BIST Done */ +#define SSB_BWA0 0x0FA0 +#define SSB_IMCFGLO 0x0FA8 +#define SSB_IMCFGLO_SERTO 0x00000007 /* Service timeout */ +#define SSB_IMCFGLO_REQTO 0x00000070 /* Request timeout */ +#define SSB_IMCFGLO_REQTO_SHIFT 4 +#define SSB_IMCFGLO_CONNID 0x00FF0000 /* Connection ID */ +#define SSB_IMCFGLO_CONNID_SHIFT 16 +#define SSB_IMCFGHI 0x0FAC +#define SSB_ADMATCH0 0x0FB0 +#define SSB_TMCFGLO 0x0FB8 +#define SSB_TMCFGHI 0x0FBC +#define SSB_BCONFIG 0x0FC0 +#define SSB_BSTATE 0x0FC8 +#define SSB_ACTCFG 0x0FD8 +#define SSB_FLAGST 0x0FE8 +#define SSB_IDLOW 0x0FF8 +#define SSB_IDLOW_CFGSP 0x00000003 /* Config Space */ +#define SSB_IDLOW_ADDRNGE 0x00000038 /* Address Ranges supported */ +#define SSB_IDLOW_ADDRNGE_SHIFT 3 +#define SSB_IDLOW_SYNC 0x00000040 +#define SSB_IDLOW_INITIATOR 0x00000080 +#define SSB_IDLOW_MIBL 0x00000F00 /* Minimum Backplane latency */ +#define SSB_IDLOW_MIBL_SHIFT 8 +#define SSB_IDLOW_MABL 0x0000F000 /* Maximum Backplane latency */ +#define SSB_IDLOW_MABL_SHIFT 12 +#define SSB_IDLOW_TIF 0x00010000 /* This Initiator is first */ +#define SSB_IDLOW_CCW 0x000C0000 /* Cycle counter width */ +#define SSB_IDLOW_CCW_SHIFT 18 +#define SSB_IDLOW_TPT 0x00F00000 /* Target ports */ +#define SSB_IDLOW_TPT_SHIFT 20 +#define SSB_IDLOW_INITP 0x0F000000 /* Initiator ports */ +#define SSB_IDLOW_INITP_SHIFT 24 +#define SSB_IDLOW_SSBREV 0xF0000000 /* Sonics Backplane Revision code */ +#define SSB_IDLOW_SSBREV_22 0x00000000 /* <= 2.2 */ +#define SSB_IDLOW_SSBREV_23 0x10000000 /* 2.3 */ +#define SSB_IDHIGH 0x0FFC /* SB Identification High */ +#define SSB_IDHIGH_RCLO 0x0000000F /* Revision Code (low part) */ +#define SSB_IDHIGH_CC 0x00008FF0 /* Core Code */ +#define SSB_IDHIGH_CC_SHIFT 4 +#define SSB_IDHIGH_RCHI 0x00007000 /* Revision Code (high part) */ +#define SSB_IDHIGH_RCHI_SHIFT 8 /* yes, shift 8 is right */ +#define SSB_IDHIGH_VC 0xFFFF0000 /* Vendor Code */ +#define SSB_IDHIGH_VC_SHIFT 16 + +/* SPROM shadow area. If not otherwise noted, fields are + * two bytes wide. Note that the SPROM can _only_ be read + * in two-byte quantinies. + */ +#define SSB_SPROMSIZE_WORDS 64 +#define SSB_SPROMSIZE_BYTES (SSB_SPROMSIZE_WORDS * sizeof(u16)) +#define SSB_SPROM_BASE 0x1000 +#define SSB_SPROM_REVISION 0x107E +#define SSB_SPROM_REVISION_REV 0x00FF /* SPROM Revision number */ +#define SSB_SPROM_REVISION_CRC 0xFF00 /* SPROM CRC8 value */ +#define SSB_SPROM_REVISION_CRC_SHIFT 8 +/* SPROM Revision 1 */ +#define SSB_SPROM1_SPID 0x1004 /* Subsystem Product ID for PCI */ +#define SSB_SPROM1_SVID 0x1006 /* Subsystem Vendor ID for PCI */ +#define SSB_SPROM1_PID 0x1008 /* Product ID for PCI */ +#define SSB_SPROM1_IL0MAC 0x1048 /* 6 bytes MAC address for 802.11b/g */ +#define SSB_SPROM1_ET0MAC 0x104E /* 6 bytes MAC address for Ethernet */ +#define SSB_SPROM1_ET1MAC 0x1054 /* 6 bytes MAC address for 802.11a */ +#define SSB_SPROM1_ETHPHY 0x105A /* Ethernet PHY settings */ +#define SSB_SPROM1_ETHPHY_ET0A 0x001F /* MII Address for enet0 */ +#define SSB_SPROM1_ETHPHY_ET1A 0x03E0 /* MII Address for enet1 */ +#define SSB_SPROM1_ETHPHY_ET1A_SHIFT 5 +#define SSB_SPROM1_ETHPHY_ET0M (1<<14) /* MDIO for enet0 */ +#define SSB_SPROM1_ETHPHY_ET1M (1<<15) /* MDIO for enet1 */ +#define SSB_SPROM1_BINF 0x105C /* Board info */ +#define SSB_SPROM1_BINF_BREV 0x00FF /* Board Revision */ +#define SSB_SPROM1_BINF_CCODE 0x0F00 /* Country Code */ +#define SSB_SPROM1_BINF_CCODE_SHIFT 8 +#define SSB_SPROM1_BINF_ANTA 0x3000 /* Available A-PHY antennas */ +#define SSB_SPROM1_BINF_ANTA_SHIFT 12 +#define SSB_SPROM1_BINF_ANTBG 0xC000 /* Available B-PHY antennas */ +#define SSB_SPROM1_BINF_ANTBG_SHIFT 14 +#define SSB_SPROM1_PA0B0 0x105E +#define SSB_SPROM1_PA0B1 0x1060 +#define SSB_SPROM1_PA0B2 0x1062 +#define SSB_SPROM1_GPIOA 0x1064 /* General Purpose IO pins 0 and 1 */ +#define SSB_SPROM1_GPIOA_P0 0x00FF /* Pin 0 */ +#define SSB_SPROM1_GPIOA_P1 0xFF00 /* Pin 1 */ +#define SSB_SPROM1_GPIOA_P1_SHIFT 8 +#define SSB_SPROM1_GPIOB 0x1066 /* General Purpuse IO pins 2 and 3 */ +#define SSB_SPROM1_GPIOB_P2 0x00FF /* Pin 2 */ +#define SSB_SPROM1_GPIOB_P3 0xFF00 /* Pin 3 */ +#define SSB_SPROM1_GPIOB_P3_SHIFT 8 +#define SSB_SPROM1_MAXPWR 0x1068 /* Power Amplifier Max Power */ +#define SSB_SPROM1_MAXPWR_BG 0x00FF /* B-PHY and G-PHY (in dBm Q5.2) */ +#define SSB_SPROM1_MAXPWR_A 0xFF00 /* A-PHY (in dBm Q5.2) */ +#define SSB_SPROM1_MAXPWR_A_SHIFT 8 +#define SSB_SPROM1_PA1B0 0x106A +#define SSB_SPROM1_PA1B1 0x106C +#define SSB_SPROM1_PA1B2 0x106E +#define SSB_SPROM1_ITSSI 0x1070 /* Idle TSSI Target */ +#define SSB_SPROM1_ITSSI_BG 0x00FF /* B-PHY and G-PHY*/ +#define SSB_SPROM1_ITSSI_A 0xFF00 /* A-PHY */ +#define SSB_SPROM1_ITSSI_A_SHIFT 8 +#define SSB_SPROM1_BFLLO 0x1072 /* Boardflags (low 16 bits) */ +#define SSB_SPROM1_AGAIN 0x1074 /* Antenna Gain (in dBm Q5.2) */ +#define SSB_SPROM1_AGAIN_A 0x00FF /* A-PHY */ +#define SSB_SPROM1_AGAIN_BG 0xFF00 /* B-PHY and G-PHY */ +#define SSB_SPROM1_AGAIN_BG_SHIFT 8 +#define SSB_SPROM1_OEM 0x1076 /* 8 bytes OEM string (rev 1 only) */ +/* SPROM Revision 2 (inherits from rev 1) */ +#define SSB_SPROM2_BFLHI 0x1038 /* Boardflags (high 16 bits) */ +#define SSB_SPROM2_MAXP_A 0x103A /* A-PHY Max Power */ +#define SSB_SPROM2_MAXP_A_HI 0x00FF /* Max Power High */ +#define SSB_SPROM2_MAXP_A_LO 0xFF00 /* Max Power Low */ +#define SSB_SPROM2_MAXP_A_LO_SHIFT 8 +#define SSB_SPROM2_PA1LOB0 0x103C /* A-PHY PowerAmplifier Low Settings */ +#define SSB_SPROM2_PA1LOB1 0x103E /* A-PHY PowerAmplifier Low Settings */ +#define SSB_SPROM2_PA1LOB2 0x1040 /* A-PHY PowerAmplifier Low Settings */ +#define SSB_SPROM2_PA1HIB0 0x1042 /* A-PHY PowerAmplifier High Settings */ +#define SSB_SPROM2_PA1HIB1 0x1044 /* A-PHY PowerAmplifier High Settings */ +#define SSB_SPROM2_PA1HIB2 0x1046 /* A-PHY PowerAmplifier High Settings */ +#define SSB_SPROM2_OPO 0x1078 /* OFDM Power Offset from CCK Level */ +#define SSB_SPROM2_OPO_VALUE 0x00FF +#define SSB_SPROM2_OPO_UNUSED 0xFF00 +#define SSB_SPROM2_CCODE 0x107C /* Two char Country Code */ +/* SPROM Revision 3 (inherits from rev 2) */ +#define SSB_SPROM3_OFDMAPO 0x102C /* A-PHY OFDM Mid Power Offset (4 bytes, BigEndian) */ +#define SSB_SPROM3_OFDMALPO 0x1030 /* A-PHY OFDM Low Power Offset (4 bytes, BigEndian) */ +#define SSB_SPROM3_OFDMAHPO 0x1034 /* A-PHY OFDM High Power Offset (4 bytes, BigEndian) */ +#define SSB_SPROM3_GPIOLDC 0x1042 /* GPIO LED Powersave Duty Cycle (4 bytes, BigEndian) */ +#define SSB_SPROM3_GPIOLDC_OFF 0x0000FF00 /* Off Count */ +#define SSB_SPROM3_GPIOLDC_OFF_SHIFT 8 +#define SSB_SPROM3_GPIOLDC_ON 0x00FF0000 /* On Count */ +#define SSB_SPROM3_GPIOLDC_ON_SHIFT 16 +#define SSB_SPROM3_CCKPO 0x1078 /* CCK Power Offset */ +#define SSB_SPROM3_CCKPO_1M 0x000F /* 1M Rate PO */ +#define SSB_SPROM3_CCKPO_2M 0x00F0 /* 2M Rate PO */ +#define SSB_SPROM3_CCKPO_2M_SHIFT 4 +#define SSB_SPROM3_CCKPO_55M 0x0F00 /* 5.5M Rate PO */ +#define SSB_SPROM3_CCKPO_55M_SHIFT 8 +#define SSB_SPROM3_CCKPO_11M 0xF000 /* 11M Rate PO */ +#define SSB_SPROM3_CCKPO_11M_SHIFT 12 +#define SSB_SPROM3_OFDMGPO 0x107A /* G-PHY OFDM Power Offset (4 bytes, BigEndian) */ + +/* Values for SSB_SPROM1_BINF_CCODE */ +enum { + SSB_SPROM1CCODE_WORLD = 0, + SSB_SPROM1CCODE_THAILAND, + SSB_SPROM1CCODE_ISRAEL, + SSB_SPROM1CCODE_JORDAN, + SSB_SPROM1CCODE_CHINA, + SSB_SPROM1CCODE_JAPAN, + SSB_SPROM1CCODE_USA_CANADA_ANZ, + SSB_SPROM1CCODE_EUROPE, + SSB_SPROM1CCODE_USA_LOW, + SSB_SPROM1CCODE_JAPAN_HIGH, + SSB_SPROM1CCODE_ALL, + SSB_SPROM1CCODE_NONE, +}; + +/* Address-Match values and masks (SSB_ADMATCHxxx) */ +#define SSB_ADM_TYPE 0x00000003 /* Address type */ +#define SSB_ADM_TYPE0 0 +#define SSB_ADM_TYPE1 1 +#define SSB_ADM_TYPE2 2 +#define SSB_ADM_AD64 0x00000004 +#define SSB_ADM_SZ0 0x000000F8 /* Type0 size */ +#define SSB_ADM_SZ0_SHIFT 3 +#define SSB_ADM_SZ1 0x000001F8 /* Type1 size */ +#define SSB_ADM_SZ1_SHIFT 3 +#define SSB_ADM_SZ2 0x000001F8 /* Type2 size */ +#define SSB_ADM_SZ2_SHIFT 3 +#define SSB_ADM_EN 0x00000400 /* Enable */ +#define SSB_ADM_NEG 0x00000800 /* Negative decode */ +#define SSB_ADM_BASE0 0xFFFFFF00 /* Type0 base address */ +#define SSB_ADM_BASE0_SHIFT 8 +#define SSB_ADM_BASE1 0xFFFFF000 /* Type1 base address for the core */ +#define SSB_ADM_BASE1_SHIFT 12 +#define SSB_ADM_BASE2 0xFFFF0000 /* Type2 base address for the core */ +#define SSB_ADM_BASE2_SHIFT 16 + + +#endif /* LINUX_SSB_REGS_H_ */ diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c index 8a09021d8c59..895ba3ac6208 100644 --- a/scripts/mod/file2alias.c +++ b/scripts/mod/file2alias.c @@ -484,6 +484,21 @@ static int do_parisc_entry(const char *filename, struct parisc_device_id *id, return 1; } +/* Looks like: ssb:vNidNrevN. */ +static int do_ssb_entry(const char *filename, + struct ssb_device_id *id, char *alias) +{ + id->vendor = TO_NATIVE(id->vendor); + id->coreid = TO_NATIVE(id->coreid); + id->revision = TO_NATIVE(id->revision); + + strcpy(alias, "ssb:"); + ADD(alias, "v", id->vendor != SSB_ANY_VENDOR, id->vendor); + ADD(alias, "id", id->coreid != SSB_ANY_ID, id->coreid); + ADD(alias, "rev", id->revision != SSB_ANY_REV, id->revision); + return 1; +} + /* Ignore any prefix, eg. v850 prepends _ */ static inline int sym_is(const char *symbol, const char *name) { @@ -599,6 +614,10 @@ void handle_moddevtable(struct module *mod, struct elf_info *info, do_table(symval, sym->st_size, sizeof(struct parisc_device_id), "parisc", do_parisc_entry, mod); + else if (sym_is(symname, "__mod_ssb_device_table")) + do_table(symval, sym->st_size, + sizeof(struct ssb_device_id), "ssb", + do_ssb_entry, mod); } /* Now add out buffered information to the generated C source */ -- cgit v1.2.3 From 0795af5729b18218767fab27c44b1384f72dc9ad Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Wed, 3 Oct 2007 17:59:30 -0700 Subject: [NET]: Introduce and use print_mac() and DECLARE_MAC_BUF() This is nicer than the MAC_FMT stuff. Signed-off-by: Joe Perches Signed-off-by: David S. Miller --- drivers/net/3c503.c | 4 +- drivers/net/3c505.c | 10 +- drivers/net/3c507.c | 6 +- drivers/net/3c509.c | 18 +-- drivers/net/3c515.c | 4 +- drivers/net/3c523.c | 22 ++- drivers/net/3c527.c | 7 +- drivers/net/3c59x.c | 7 +- drivers/net/8139cp.c | 8 +- drivers/net/8139too.c | 8 +- drivers/net/82596.c | 18 +-- drivers/net/a2065.c | 6 +- drivers/net/ac3200.c | 8 +- drivers/net/acenic.c | 7 +- drivers/net/amd8111e.c | 12 +- drivers/net/apne.c | 9 +- drivers/net/ariadne.c | 44 +++--- drivers/net/arm/am79c961a.c | 8 +- drivers/net/arm/at91_ether.c | 18 +-- drivers/net/arm/ether1.c | 8 +- drivers/net/arm/ether3.c | 8 +- drivers/net/arm/etherh.c | 8 +- drivers/net/at1700.c | 4 +- drivers/net/atarilance.c | 43 +++-- drivers/net/atp.c | 8 +- drivers/net/b44.c | 9 +- drivers/net/bmac.c | 6 +- drivers/net/bnx2.c | 12 +- drivers/net/bonding/bond_main.c | 34 ++-- drivers/net/bonding/bond_sysfs.c | 11 +- drivers/net/cassini.c | 11 +- drivers/net/cris/eth_v10.c | 8 +- drivers/net/cs89x0.c | 15 +- drivers/net/de600.c | 6 +- drivers/net/de620.c | 8 +- drivers/net/declance.c | 14 +- drivers/net/depca.c | 13 +- drivers/net/dgrs.c | 18 +-- drivers/net/dl2k.c | 7 +- drivers/net/dm9000.c | 9 +- drivers/net/e100.c | 9 +- drivers/net/e1000/e1000_main.c | 5 +- drivers/net/eepro.c | 5 +- drivers/net/eepro100.c | 9 +- drivers/net/epic100.c | 9 +- drivers/net/es3210.c | 22 +-- drivers/net/ewrk3.c | 16 +- drivers/net/fealnx.c | 9 +- drivers/net/fec.c | 7 +- drivers/net/forcedeth.c | 12 +- drivers/net/gianfar.c | 7 +- drivers/net/hamachi.c | 8 +- drivers/net/hamradio/bpqether.c | 23 +-- drivers/net/hp-plus.c | 6 +- drivers/net/hp.c | 5 +- drivers/net/hp100.c | 6 +- drivers/net/hydra.c | 7 +- drivers/net/ibm_emac/ibm_emac_core.c | 14 +- drivers/net/ibmlana.c | 6 +- drivers/net/ibmveth.c | 9 +- drivers/net/ioc3-eth.c | 12 +- drivers/net/isa-skeleton.c | 5 +- drivers/net/jazzsonic.c | 10 +- drivers/net/lance.c | 6 +- drivers/net/lguest_net.c | 4 +- drivers/net/lib82596.c | 18 +-- drivers/net/lne390.c | 9 +- drivers/net/mac89x0.c | 11 +- drivers/net/macb.c | 6 +- drivers/net/mace.c | 9 +- drivers/net/macmace.c | 6 +- drivers/net/macsonic.c | 21 +-- drivers/net/meth.c | 6 +- drivers/net/mv643xx_eth.c | 5 +- drivers/net/mvme147.c | 11 +- drivers/net/myri10ge/myri10ge.c | 11 +- drivers/net/myri_sbus.c | 29 ++-- drivers/net/natsemi.c | 11 +- drivers/net/ne-h8300.c | 8 +- drivers/net/ne.c | 5 +- drivers/net/ne2.c | 17 +- drivers/net/ne2k-pci.c | 11 +- drivers/net/ne3210.c | 11 +- drivers/net/netconsole.c | 14 +- drivers/net/netxen/netxen_nic_main.c | 13 +- drivers/net/netxen/netxen_nic_niu.c | 14 +- drivers/net/ni5010.c | 4 +- drivers/net/ns83820.c | 7 +- drivers/net/pasemi_mac.c | 6 +- drivers/net/pci-skeleton.c | 9 +- drivers/net/pcmcia/3c574_cs.c | 9 +- drivers/net/pcmcia/3c589_cs.c | 10 +- drivers/net/pcmcia/axnet_cs.c | 9 +- drivers/net/pcmcia/fmvj18x_cs.c | 8 +- drivers/net/pcmcia/nmclan_cs.c | 9 +- drivers/net/pcmcia/pcnet_cs.c | 7 +- drivers/net/pcmcia/smc91c92_cs.c | 8 +- drivers/net/pcmcia/xirc2ps_cs.c | 9 +- drivers/net/pppoe.c | 8 +- drivers/net/ps3_gelic_net.c | 7 +- drivers/net/qla3xxx.c | 7 +- drivers/net/rionet.c | 6 +- drivers/net/rrunner.c | 8 +- drivers/net/s2io.c | 11 +- drivers/net/sb1250-mac.c | 7 +- drivers/net/seeq8005.c | 4 +- drivers/net/sgiseeq.c | 6 +- drivers/net/sis190.c | 10 +- drivers/net/sis900.c | 9 +- drivers/net/skge.c | 7 +- drivers/net/sky2.c | 7 +- drivers/net/smc-mca.c | 8 +- drivers/net/smc-ultra.c | 8 +- drivers/net/smc-ultra32.c | 8 +- drivers/net/smc9194.c | 7 +- drivers/net/smc91x.c | 9 +- drivers/net/starfire.c | 26 ++-- drivers/net/sun3lance.c | 36 ++--- drivers/net/sunbmac.c | 8 +- drivers/net/sundance.c | 10 +- drivers/net/sungem.c | 12 +- drivers/net/sunhme.c | 12 +- drivers/net/sunlance.c | 9 +- drivers/net/tokenring/abyss.c | 12 +- drivers/net/tokenring/ibmtr.c | 26 ++-- drivers/net/tokenring/lanstreamer.c | 64 ++++---- drivers/net/tokenring/madgemc.c | 19 +-- drivers/net/tokenring/olympic.c | 138 +++++++---------- drivers/net/tokenring/proteon.c | 8 +- drivers/net/tokenring/skisa.c | 8 +- drivers/net/tokenring/tmspci.c | 10 +- drivers/net/tsi108_eth.c | 7 +- drivers/net/tulip/de2104x.c | 9 +- drivers/net/tulip/de4x5.c | 33 ++-- drivers/net/tulip/dmfe.c | 15 +- drivers/net/tulip/tulip_core.c | 15 +- drivers/net/tulip/uli526x.c | 9 +- drivers/net/tulip/winbond-840.c | 29 ++-- drivers/net/tulip/xircom_cb.c | 7 +- drivers/net/tun.c | 33 ++-- drivers/net/typhoon.c | 10 +- drivers/net/usb/pegasus.c | 11 +- drivers/net/usb/usbnet.c | 8 +- drivers/net/via-rhine.c | 13 +- drivers/net/wd.c | 7 +- drivers/net/wireless/adm8211.c | 5 +- drivers/net/wireless/airo.c | 32 ++-- drivers/net/wireless/arlan-main.c | 23 +-- drivers/net/wireless/atmel.c | 7 +- drivers/net/wireless/b43/main.c | 5 +- drivers/net/wireless/b43legacy/main.c | 3 +- drivers/net/wireless/bcm43xx/bcm43xx.h | 6 - drivers/net/wireless/hostap/hostap_80211_rx.c | 49 +++--- drivers/net/wireless/hostap/hostap_80211_tx.c | 13 +- drivers/net/wireless/hostap/hostap_ap.c | 198 +++++++++++++---------- drivers/net/wireless/hostap/hostap_common.h | 3 - drivers/net/wireless/hostap/hostap_hw.c | 11 +- drivers/net/wireless/hostap/hostap_info.c | 17 +- drivers/net/wireless/hostap/hostap_ioctl.c | 15 +- drivers/net/wireless/hostap/hostap_main.c | 30 ++-- drivers/net/wireless/hostap/hostap_proc.c | 15 +- drivers/net/wireless/ipw2100.c | 48 +++--- drivers/net/wireless/ipw2200.c | 207 ++++++++++++++----------- drivers/net/wireless/iwlwifi/iwl-3945-rs.c | 5 +- drivers/net/wireless/iwlwifi/iwl-3945.c | 34 ++-- drivers/net/wireless/iwlwifi/iwl-4965-rs.c | 17 +- drivers/net/wireless/iwlwifi/iwl-4965.c | 73 +++++---- drivers/net/wireless/iwlwifi/iwl3945-base.c | 65 +++++--- drivers/net/wireless/iwlwifi/iwl4965-base.c | 59 ++++--- drivers/net/wireless/libertas/assoc.c | 19 ++- drivers/net/wireless/libertas/cmdresp.c | 5 +- drivers/net/wireless/libertas/debugfs.c | 5 +- drivers/net/wireless/libertas/join.c | 16 +- drivers/net/wireless/libertas/main.c | 12 +- drivers/net/wireless/libertas/scan.c | 14 +- drivers/net/wireless/libertas/wext.c | 5 +- drivers/net/wireless/netwave_cs.c | 14 +- drivers/net/wireless/orinoco.c | 7 +- drivers/net/wireless/prism54/isl_ioctl.c | 50 ++---- drivers/net/wireless/ray_cs.c | 13 +- drivers/net/wireless/rt2x00/rt2400pci.c | 4 +- drivers/net/wireless/rt2x00/rt2500pci.c | 5 +- drivers/net/wireless/rt2x00/rt2500usb.c | 4 +- drivers/net/wireless/rt2x00/rt61pci.c | 4 +- drivers/net/wireless/rt2x00/rt73usb.c | 4 +- drivers/net/wireless/rtl8187_dev.c | 5 +- drivers/net/wireless/wavelan.c | 53 +++---- drivers/net/wireless/wavelan_cs.c | 54 +++---- drivers/net/wireless/wl3501_cs.c | 22 +-- drivers/net/wireless/zd1211rw/zd_chip.c | 3 +- drivers/net/wireless/zd1211rw/zd_mac.c | 8 +- drivers/net/yellowfin.c | 19 ++- drivers/net/znet.c | 11 +- drivers/net/zorro8390.c | 15 +- include/linux/if_ether.h | 8 + include/net/ieee80211.h | 5 - include/net/mac80211.h | 4 - net/802/tr.c | 28 ++-- net/appletalk/aarp.c | 9 +- net/atm/br2684.c | 16 +- net/atm/lec.c | 29 ++-- net/core/netpoll.c | 12 +- net/core/pktgen.c | 17 +- net/ethernet/eth.c | 8 + net/ieee80211/ieee80211_crypt_ccmp.c | 27 ++-- net/ieee80211/ieee80211_crypt_tkip.c | 31 ++-- net/ieee80211/ieee80211_rx.c | 59 +++---- net/ieee80211/ieee80211_wx.c | 5 +- net/ieee80211/softmac/ieee80211softmac_assoc.c | 4 +- net/ieee80211/softmac/ieee80211softmac_auth.c | 35 +++-- net/ieee80211/softmac/ieee80211softmac_wx.c | 1 + net/irda/irlan/irlan_client.c | 6 +- net/llc/llc_proc.c | 12 +- net/mac80211/debugfs_key.c | 3 +- net/mac80211/debugfs_netdev.c | 3 +- net/mac80211/debugfs_sta.c | 6 +- net/mac80211/event.c | 5 +- net/mac80211/ieee80211.c | 5 +- net/mac80211/ieee80211_ioctl.c | 5 +- net/mac80211/ieee80211_sta.c | 180 +++++++++++---------- net/mac80211/key.c | 10 +- net/mac80211/rc80211_simple.c | 5 +- net/mac80211/rx.c | 103 ++++++------ net/mac80211/sta_info.c | 13 +- net/mac80211/tkip.c | 10 +- net/mac80211/tx.c | 32 ++-- net/mac80211/wpa.c | 19 ++- net/tipc/eth_media.c | 4 +- 228 files changed, 1875 insertions(+), 1952 deletions(-) (limited to 'include/linux') diff --git a/drivers/net/3c503.c b/drivers/net/3c503.c index f9e7ffbcb772..9c23336750e2 100644 --- a/drivers/net/3c503.c +++ b/drivers/net/3c503.c @@ -177,6 +177,7 @@ el2_probe1(struct net_device *dev, int ioaddr) int i, iobase_reg, membase_reg, saved_406, wordlength, retval; static unsigned version_printed; unsigned long vendor_id; + DECLARE_MAC_BUF(mac); if (!request_region(ioaddr, EL2_IO_EXTENT, DRV_NAME)) return -EBUSY; @@ -226,7 +227,8 @@ el2_probe1(struct net_device *dev, int ioaddr) /* Retrieve and print the ethernet address. */ for (i = 0; i < 6; i++) - printk(" %2.2x", dev->dev_addr[i] = inb(ioaddr + i)); + dev->dev_addr[i] = inb(ioaddr + i); + printk("%s", print_mac(mac, dev->dev_addr)); /* Map the 8390 back into the window. */ outb(ECNTRL_THIN, ioaddr + 0x406); diff --git a/drivers/net/3c505.c b/drivers/net/3c505.c index c05bb3fc57a2..9c6573419f5a 100644 --- a/drivers/net/3c505.c +++ b/drivers/net/3c505.c @@ -1386,6 +1386,7 @@ static int __init elplus_setup(struct net_device *dev) unsigned long timeout; unsigned long cookie = 0; int err = -ENODEV; + DECLARE_MAC_BUF(mac); /* * setup adapter structure @@ -1521,11 +1522,10 @@ static int __init elplus_setup(struct net_device *dev) /* * print remainder of startup message */ - printk(KERN_INFO "%s: 3c505 at %#lx, irq %d, dma %d, ", - dev->name, dev->base_addr, dev->irq, dev->dma); - printk("addr %02x:%02x:%02x:%02x:%02x:%02x, ", - dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2], - dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]); + printk(KERN_INFO "%s: 3c505 at %#lx, irq %d, dma %d, " + "addr %s, ", + dev->name, dev->base_addr, dev->irq, dev->dma, + print_mac(mac, dev->dev_addr)); /* * read more information from the adapter diff --git a/drivers/net/3c507.c b/drivers/net/3c507.c index 3d06271c3a8b..964d31ac9449 100644 --- a/drivers/net/3c507.c +++ b/drivers/net/3c507.c @@ -357,6 +357,7 @@ static int __init el16_probe1(struct net_device *dev, int ioaddr) static unsigned char init_ID_done, version_printed; int i, irq, irqval, retval; struct net_local *lp; + DECLARE_MAC_BUF(mac); if (init_ID_done == 0) { ushort lrs_state = 0xff; @@ -402,10 +403,9 @@ static int __init el16_probe1(struct net_device *dev, int ioaddr) dev->base_addr = ioaddr; outb(0x01, ioaddr + MISC_CTRL); - for (i = 0; i < 6; i++) { + for (i = 0; i < 6; i++) dev->dev_addr[i] = inb(ioaddr + i); - printk(" %02x", dev->dev_addr[i]); - } + printk(" %s", print_mac(mac, dev->dev_addr)); if (mem_start) net_debug = mem_start & 7; diff --git a/drivers/net/3c509.c b/drivers/net/3c509.c index 7466987d8451..c576fe76d54f 100644 --- a/drivers/net/3c509.c +++ b/drivers/net/3c509.c @@ -313,8 +313,9 @@ static int nopnp; static int __init el3_common_init(struct net_device *dev) { struct el3_private *lp = netdev_priv(dev); - short i; int err; + DECLARE_MAC_BUF(mac); + const char *if_names[] = {"10baseT", "AUI", "undefined", "BNC"}; spin_lock_init(&lp->lock); @@ -346,17 +347,10 @@ static int __init el3_common_init(struct net_device *dev) return err; } - { - const char *if_names[] = {"10baseT", "AUI", "undefined", "BNC"}; - printk("%s: 3c5x9 found at %#3.3lx, %s port, address ", - dev->name, dev->base_addr, - if_names[(dev->if_port & 0x03)]); - } - - /* Read in the station address. */ - for (i = 0; i < 6; i++) - printk(" %2.2x", dev->dev_addr[i]); - printk(", IRQ %d.\n", dev->irq); + printk(KERN_INFO "%s: 3c5x9 found at %#3.3lx, %s port, " + "address %s, IRQ %d.\n", + dev->name, dev->base_addr, if_names[(dev->if_port & 0x03)], + print_mac(mac, dev->dev_addr), dev->irq); if (el3_debug > 0) printk(KERN_INFO "%s", version); diff --git a/drivers/net/3c515.c b/drivers/net/3c515.c index 38a2ebea9b45..275e7510ebaf 100644 --- a/drivers/net/3c515.c +++ b/drivers/net/3c515.c @@ -569,6 +569,7 @@ static int corkscrew_setup(struct net_device *dev, int ioaddr, unsigned int eeprom[0x40], checksum = 0; /* EEPROM contents */ int i; int irq; + DECLARE_MAC_BUF(mac); if (idev) { irq = pnp_irq(idev, 0); @@ -630,8 +631,7 @@ static int corkscrew_setup(struct net_device *dev, int ioaddr, checksum = (checksum ^ (checksum >> 8)) & 0xff; if (checksum != 0x00) printk(" ***INVALID CHECKSUM %4.4x*** ", checksum); - for (i = 0; i < 6; i++) - printk("%c%2.2x", i ? ':' : ' ', dev->dev_addr[i]); + printk(" %s", print_mac(mac, dev->dev_addr)); if (eeprom[16] == 0x11c7) { /* Corkscrew */ if (request_dma(dev->dma, "3c515")) { printk(", DMA %d allocation failed", dev->dma); diff --git a/drivers/net/3c523.c b/drivers/net/3c523.c index 10852b2a40ab..239fc42fb8df 100644 --- a/drivers/net/3c523.c +++ b/drivers/net/3c523.c @@ -383,8 +383,8 @@ void alloc586(struct net_device *dev) static int elmc_getinfo(char *buf, int slot, void *d) { int len = 0; - struct net_device *dev = (struct net_device *) d; - int i; + struct net_device *dev = d; + DECLARE_MAC_BUF(mac); if (dev == NULL) return len; @@ -399,12 +399,8 @@ static int elmc_getinfo(char *buf, int slot, void *d) len += sprintf(buf + len, "Transceiver: %s\n", dev->if_port ? "External" : "Internal"); len += sprintf(buf + len, "Device: %s\n", dev->name); - len += sprintf(buf + len, "Hardware Address:"); - for (i = 0; i < 6; i++) { - len += sprintf(buf + len, " %02x", dev->dev_addr[i]); - } - buf[len++] = '\n'; - buf[len] = 0; + len += sprintf(buf + len, "Hardware Address: %s\n", + print_mac(mac, dev->dev_addr)); return len; } /* elmc_getinfo() */ @@ -422,6 +418,7 @@ static int __init do_elmc_probe(struct net_device *dev) unsigned int size = 0; int retval; struct priv *pr = dev->priv; + DECLARE_MAC_BUF(mac); if (MCA_bus == 0) { return -ENODEV; @@ -544,12 +541,11 @@ static int __init do_elmc_probe(struct net_device *dev) /* The hardware address for the 3c523 is stored in the first six bytes of the IO address. */ - printk(KERN_INFO "%s: hardware address ", dev->name); - for (i = 0; i < 6; i++) { + for (i = 0; i < 6; i++) dev->dev_addr[i] = inb(dev->base_addr + i); - printk(" %02x", dev->dev_addr[i]); - } - printk("\n"); + + printk(KERN_INFO "%s: hardware address %s\n", + dev->name, print_mac(mac, dev->dev_addr)); dev->open = &elmc_open; dev->stop = &elmc_close; diff --git a/drivers/net/3c527.c b/drivers/net/3c527.c index 5b5f44cdfc1d..b72b89d53ec8 100644 --- a/drivers/net/3c527.c +++ b/drivers/net/3c527.c @@ -336,6 +336,7 @@ static int __init mc32_probe1(struct net_device *dev, int slot) "82586 initialisation failure", "Adapter list configuration error" }; + DECLARE_MAC_BUF(mac); /* Time to play MCA games */ @@ -396,17 +397,17 @@ static int __init mc32_probe1(struct net_device *dev, int slot) * Go PROM browsing */ - printk("%s: Address ", dev->name); - /* Retrieve and print the ethernet address. */ for (i = 0; i < 6; i++) { mca_write_pos(slot, 6, i+12); mca_write_pos(slot, 7, 0); - printk(" %2.2x", dev->dev_addr[i] = mca_read_pos(slot,3)); + dev->dev_addr[i] = mca_read_pos(slot,3); } + printk("%s: Address %s", dev->name, print_mac(mac, dev->dev_addr)); + mca_write_pos(slot, 6, 0); mca_write_pos(slot, 7, 0); diff --git a/drivers/net/3c59x.c b/drivers/net/3c59x.c index ad0f6a729d29..58311199e321 100644 --- a/drivers/net/3c59x.c +++ b/drivers/net/3c59x.c @@ -1014,6 +1014,7 @@ static int __devinit vortex_probe1(struct device *gendev, char *print_name = "3c59x"; struct pci_dev *pdev = NULL; struct eisa_device *edev = NULL; + DECLARE_MAC_BUF(mac); if (!printed_version) { printk (version); @@ -1205,10 +1206,8 @@ static int __devinit vortex_probe1(struct device *gendev, for (i = 0; i < 3; i++) ((u16 *)dev->dev_addr)[i] = htons(eeprom[i + 10]); memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len); - if (print_info) { - for (i = 0; i < 6; i++) - printk("%c%2.2x", i ? ':' : ' ', dev->dev_addr[i]); - } + if (print_info) + printk(" %s", print_mac(mac, dev->dev_addr)); /* Unfortunately an all zero eeprom passes the checksum and this gets found in the wild in failure cases. Crypto is hard 8) */ if (!is_valid_ether_addr(dev->dev_addr)) { diff --git a/drivers/net/8139cp.c b/drivers/net/8139cp.c index 58fad1b2f72e..7edd50cf7776 100644 --- a/drivers/net/8139cp.c +++ b/drivers/net/8139cp.c @@ -1823,6 +1823,7 @@ static int cp_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) void __iomem *regs; resource_size_t pciaddr; unsigned int addr_len, i, pci_using_dac; + DECLARE_MAC_BUF(mac); #ifndef MODULE static int version_printed; @@ -1964,13 +1965,10 @@ static int cp_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) goto err_out_iomap; printk (KERN_INFO "%s: RTL-8139C+ at 0x%lx, " - "%02x:%02x:%02x:%02x:%02x:%02x, " - "IRQ %d\n", + "%s, IRQ %d\n", dev->name, dev->base_addr, - dev->dev_addr[0], dev->dev_addr[1], - dev->dev_addr[2], dev->dev_addr[3], - dev->dev_addr[4], dev->dev_addr[5], + print_mac(mac, dev->dev_addr), dev->irq); pci_set_drvdata(pdev, dev); diff --git a/drivers/net/8139too.c b/drivers/net/8139too.c index 28c1aaf1fe1d..d3088a786e26 100644 --- a/drivers/net/8139too.c +++ b/drivers/net/8139too.c @@ -926,6 +926,7 @@ static int __devinit rtl8139_init_one (struct pci_dev *pdev, int i, addr_len, option; void __iomem *ioaddr; static int board_idx = -1; + DECLARE_MAC_BUF(mac); assert (pdev != NULL); assert (ent != NULL); @@ -1017,14 +1018,11 @@ static int __devinit rtl8139_init_one (struct pci_dev *pdev, pci_set_drvdata (pdev, dev); printk (KERN_INFO "%s: %s at 0x%lx, " - "%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x, " - "IRQ %d\n", + "%s, IRQ %d\n", dev->name, board_info[ent->driver_data].name, dev->base_addr, - dev->dev_addr[0], dev->dev_addr[1], - dev->dev_addr[2], dev->dev_addr[3], - dev->dev_addr[4], dev->dev_addr[5], + print_mac(mac, dev->dev_addr), dev->irq); printk (KERN_DEBUG "%s: Identified 8139 chip type '%s'\n", diff --git a/drivers/net/82596.c b/drivers/net/82596.c index 6b03416731de..bb30d5be7824 100644 --- a/drivers/net/82596.c +++ b/drivers/net/82596.c @@ -1116,15 +1116,12 @@ static int i596_start_xmit(struct sk_buff *skb, struct net_device *dev) static void print_eth(unsigned char *add, char *str) { - int i; + DECLARE_MAC_BUF(mac); + DECLARE_MAC_BUF(mac2); - printk(KERN_DEBUG "i596 0x%p, ", add); - for (i = 0; i < 6; i++) - printk(" %02X", add[i + 6]); - printk(" -->"); - for (i = 0; i < 6; i++) - printk(" %02X", add[i]); - printk(" %02X%02X, %s\n", add[12], add[13], str); + printk(KERN_DEBUG "i596 0x%p, %s --> %s %02X%02X, %s\n", + add, print_mac(mac, add + 6), print_mac(mac2, add), + add[12], add[13], str); } static int io = 0x300; @@ -1539,6 +1536,7 @@ static void set_multicast_list(struct net_device *dev) struct dev_mc_list *dmi; unsigned char *cp; struct mc_cmd *cmd; + DECLARE_MAC_BUF(mac); if (wait_cfg(dev, &lp->mc_cmd.cmd, 1000, "multicast list change request timed out")) return; @@ -1549,8 +1547,8 @@ static void set_multicast_list(struct net_device *dev) for (dmi = dev->mc_list; cnt && dmi != NULL; dmi = dmi->next, cnt--, cp += 6) { memcpy(cp, dmi->dmi_addr, 6); if (i596_debug > 1) - DEB(DEB_MULTI,printk(KERN_INFO "%s: Adding address %02x:%02x:%02x:%02x:%02x:%02x\n", - dev->name, cp[0],cp[1],cp[2],cp[3],cp[4],cp[5])); + DEB(DEB_MULTI,printk(KERN_INFO "%s: Adding address %s\n", + dev->name, print_mac(mac, cp))); } i596_add_cmd(dev, &cmd->cmd); } diff --git a/drivers/net/a2065.c b/drivers/net/a2065.c index 77773ce52eff..18f7f815f66e 100644 --- a/drivers/net/a2065.c +++ b/drivers/net/a2065.c @@ -716,6 +716,7 @@ static int __devinit a2065_init_one(struct zorro_dev *z, unsigned long board, base_addr, mem_start; struct resource *r1, *r2; int err; + DECLARE_MAC_BUF(mac); board = z->resource.start; base_addr = board+A2065_LANCE; @@ -792,9 +793,8 @@ static int __devinit a2065_init_one(struct zorro_dev *z, zorro_set_drvdata(z, dev); printk(KERN_INFO "%s: A2065 at 0x%08lx, Ethernet Address " - "%02x:%02x:%02x:%02x:%02x:%02x\n", dev->name, board, - dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2], - dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]); + "%s\n", dev->name, board, + print_mac(mac, dev->dev_addr)); return 0; } diff --git a/drivers/net/ac3200.c b/drivers/net/ac3200.c index 65b2de56ed22..5136d94923aa 100644 --- a/drivers/net/ac3200.c +++ b/drivers/net/ac3200.c @@ -146,6 +146,7 @@ out: static int __init ac_probe1(int ioaddr, struct net_device *dev) { int i, retval; + DECLARE_MAC_BUF(mac); if (!request_region(ioaddr, AC_IO_EXTENT, DRV_NAME)) return -EBUSY; @@ -167,10 +168,11 @@ static int __init ac_probe1(int ioaddr, struct net_device *dev) inb(ioaddr + AC_ID_PORT + 2), inb(ioaddr + AC_ID_PORT + 3)); #endif - printk("AC3200 in EISA slot %d, node", ioaddr/0x1000); - for(i = 0; i < 6; i++) - printk(" %02x", dev->dev_addr[i] = inb(ioaddr + AC_SA_PROM + i)); + for (i = 0; i < 6; i++) + dev->dev_addr[i] = inb(ioaddr + AC_SA_PROM + i); + printk(KERN_DEBUG "AC3200 in EISA slot %d, node %s", + ioaddr/0x1000, print_mac(mac, dev->dev_addr)); #if 0 /* Check the vendor ID/prefix. Redundant after checking the EISA ID */ if (inb(ioaddr + AC_SA_PROM + 0) != AC_ADDR0 diff --git a/drivers/net/acenic.c b/drivers/net/acenic.c index ca00f41e4d85..2c2ed6dc98bc 100644 --- a/drivers/net/acenic.c +++ b/drivers/net/acenic.c @@ -893,6 +893,7 @@ static int __devinit ace_init(struct net_device *dev) int board_idx, ecode = 0; short i; unsigned char cache_size; + DECLARE_MAC_BUF(mac); ap = netdev_priv(dev); regs = ap->regs; @@ -1012,10 +1013,6 @@ static int __devinit ace_init(struct net_device *dev) writel(mac1, ®s->MacAddrHi); writel(mac2, ®s->MacAddrLo); - printk("MAC: %02x:%02x:%02x:%02x:%02x:%02x\n", - (mac1 >> 8) & 0xff, mac1 & 0xff, (mac2 >> 24) &0xff, - (mac2 >> 16) & 0xff, (mac2 >> 8) & 0xff, mac2 & 0xff); - dev->dev_addr[0] = (mac1 >> 8) & 0xff; dev->dev_addr[1] = mac1 & 0xff; dev->dev_addr[2] = (mac2 >> 24) & 0xff; @@ -1023,6 +1020,8 @@ static int __devinit ace_init(struct net_device *dev) dev->dev_addr[4] = (mac2 >> 8) & 0xff; dev->dev_addr[5] = mac2 & 0xff; + printk("MAC: %s\n", print_mac(mac, dev->dev_addr)); + /* * Looks like this is necessary to deal with on all architectures, * even this %$#%$# N440BX Intel based thing doesn't get it right. diff --git a/drivers/net/amd8111e.c b/drivers/net/amd8111e.c index afb60a5927ae..73f40a45441a 100644 --- a/drivers/net/amd8111e.c +++ b/drivers/net/amd8111e.c @@ -1934,6 +1934,7 @@ static int __devinit amd8111e_probe_one(struct pci_dev *pdev, unsigned long reg_addr,reg_len; struct amd8111e_priv* lp; struct net_device* dev; + DECLARE_MAC_BUF(mac); err = pci_enable_device(pdev); if(err){ @@ -2006,7 +2007,7 @@ static int __devinit amd8111e_probe_one(struct pci_dev *pdev, /* Initializing MAC address */ for(i = 0; i < ETH_ADDR_LEN; i++) - dev->dev_addr[i] =readb(lp->mmio + PADR + i); + dev->dev_addr[i] = readb(lp->mmio + PADR + i); /* Setting user defined parametrs */ lp->ext_phy_option = speed_duplex[card_idx]; @@ -2075,11 +2076,10 @@ static int __devinit amd8111e_probe_one(struct pci_dev *pdev, /* display driver and device information */ chip_version = (readl(lp->mmio + CHIPID) & 0xf0000000)>>28; - printk(KERN_INFO "%s: AMD-8111e Driver Version: %s\n", dev->name,MODULE_VERS); - printk(KERN_INFO "%s: [ Rev %x ] PCI 10/100BaseT Ethernet ", dev->name, chip_version); - for (i = 0; i < 6; i++) - printk("%2.2x%c",dev->dev_addr[i],i == 5 ? ' ' : ':'); - printk( "\n"); + printk(KERN_INFO "%s: AMD-8111e Driver Version: %s\n", + dev->name,MODULE_VERS); + printk(KERN_INFO "%s: [ Rev %x ] PCI 10/100BaseT Ethernet %s\n", + dev->name, chip_version, print_mac(mac, dev->dev_addr)); if (lp->ext_phy_id) printk(KERN_INFO "%s: Found MII PHY ID 0x%08x at address 0x%02x\n", dev->name, lp->ext_phy_id, lp->ext_phy_addr); diff --git a/drivers/net/apne.c b/drivers/net/apne.c index b5a974a964c2..c12cbdf368b1 100644 --- a/drivers/net/apne.c +++ b/drivers/net/apne.c @@ -204,6 +204,7 @@ static int __init apne_probe1(struct net_device *dev, int ioaddr) int neX000, ctron; #endif static unsigned version_printed; + DECLARE_MAC_BUF(mac); if (ei_debug && version_printed++ == 0) printk(version); @@ -316,12 +317,12 @@ static int __init apne_probe1(struct net_device *dev, int ioaddr) i = request_irq(dev->irq, apne_interrupt, IRQF_SHARED, DRV_NAME, dev); if (i) return i; - for(i = 0; i < ETHER_ADDR_LEN; i++) { - printk(" %2.2x", SA_prom[i]); + for(i = 0; i < ETHER_ADDR_LEN; i++) dev->dev_addr[i] = SA_prom[i]; - } - printk("\n%s: %s found.\n", dev->name, name); + printk(" %s\n", print_mac(mac, dev->dev_addr)); + + printk("%s: %s found.\n", dev->name, name); ei_status.name = name; ei_status.tx_start_page = start_page; diff --git a/drivers/net/ariadne.c b/drivers/net/ariadne.c index 2c020a36177e..3fa3bccd1adb 100644 --- a/drivers/net/ariadne.c +++ b/drivers/net/ariadne.c @@ -166,6 +166,7 @@ static int __devinit ariadne_init_one(struct zorro_dev *z, struct net_device *dev; struct ariadne_private *priv; int err; + DECLARE_MAC_BUF(mac); r1 = request_mem_region(base_addr, sizeof(struct Am79C960), "Am79C960"); if (!r1) @@ -216,9 +217,8 @@ static int __devinit ariadne_init_one(struct zorro_dev *z, zorro_set_drvdata(z, dev); printk(KERN_INFO "%s: Ariadne at 0x%08lx, Ethernet Address " - "%02x:%02x:%02x:%02x:%02x:%02x\n", dev->name, board, - dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2], - dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]); + "%s\n", dev->name, board, + print_mac(mac, dev->dev_addr)); return 0; } @@ -614,21 +614,17 @@ static int ariadne_start_xmit(struct sk_buff *skb, struct net_device *dev) /* Fill in a Tx ring entry */ #if 0 - printk(KERN_DEBUG "TX pkt type 0x%04x from ", ((u_short *)skb->data)[6]); - { - int i; - u_char *ptr = &((u_char *)skb->data)[6]; - for (i = 0; i < 6; i++) - printk("%02x", ptr[i]); - } - printk(" to "); - { - int i; - u_char *ptr = (u_char *)skb->data; - for (i = 0; i < 6; i++) - printk("%02x", ptr[i]); - } - printk(" data 0x%08x len %d\n", (int)skb->data, (int)skb->len); +{ + DECLARE_MAC_BUF(mac); + DECLARE_MAC_BUF(mac2); + + printk(KERN_DEBUG "TX pkt type 0x%04x from %s to %s " + " data 0x%08x len %d\n", + ((u_short *)skb->data)[6], + print_mac(mac, ((const u8 *)skb->data)+6), + print_mac(mac, (const u8 *)skb->data), + (int)skb->data, (int)skb->len); +} #endif local_irq_save(flags); @@ -748,22 +744,22 @@ static int ariadne_rx(struct net_device *dev) skb_copy_to_linear_data(skb, (char *)priv->rx_buff[entry], pkt_len); skb->protocol=eth_type_trans(skb,dev); #if 0 +{ + DECLARE_MAC_BUF(mac); + printk(KERN_DEBUG "RX pkt type 0x%04x from ", ((u_short *)skb->data)[6]); { - int i; u_char *ptr = &((u_char *)skb->data)[6]; - for (i = 0; i < 6; i++) - printk("%02x", ptr[i]); + printk("%s", print_mac(mac, ptr)); } printk(" to "); { - int i; u_char *ptr = (u_char *)skb->data; - for (i = 0; i < 6; i++) - printk("%02x", ptr[i]); + printk("%s", print_mac(mac, ptr)); } printk(" data 0x%08x len %d\n", (int)skb->data, (int)skb->len); +} #endif netif_rx(skb); diff --git a/drivers/net/arm/am79c961a.c b/drivers/net/arm/am79c961a.c index 77964556776e..ba6bd03a015f 100644 --- a/drivers/net/arm/am79c961a.c +++ b/drivers/net/arm/am79c961a.c @@ -741,12 +741,10 @@ static int __init am79c961_probe(struct platform_device *pdev) ret = register_netdev(dev); if (ret == 0) { - printk(KERN_INFO "%s: ether address ", dev->name); - - /* Retrive and print the ethernet address. */ - for (i = 0; i < 6; i++) - printk (i == 5 ? "%02x\n" : "%02x:", dev->dev_addr[i]); + DECLARE_MAC_BUF(mac); + printk(KERN_INFO "%s: ether address %s\n", + dev->name, print_mac(mac, dev->dev_addr)); return 0; } diff --git a/drivers/net/arm/at91_ether.c b/drivers/net/arm/at91_ether.c index 619810a01e5b..25b114a4e2b1 100644 --- a/drivers/net/arm/at91_ether.c +++ b/drivers/net/arm/at91_ether.c @@ -485,6 +485,7 @@ static void update_mac_address(struct net_device *dev) static int set_mac_address(struct net_device *dev, void* addr) { struct sockaddr *address = addr; + DECLARE_MAC_BUF(mac); if (!is_valid_ether_addr(address->sa_data)) return -EADDRNOTAVAIL; @@ -492,9 +493,8 @@ static int set_mac_address(struct net_device *dev, void* addr) memcpy(dev->dev_addr, address->sa_data, dev->addr_len); update_mac_address(dev); - printk("%s: Setting MAC address to %02x:%02x:%02x:%02x:%02x:%02x\n", dev->name, - dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2], - dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]); + printk("%s: Setting MAC address to %s\n", dev->name, + print_mac(mac, dev->dev_addr)); return 0; } @@ -979,6 +979,7 @@ static int __init at91ether_setup(unsigned long phy_type, unsigned short phy_add struct at91_private *lp; unsigned int val; int res; + DECLARE_MAC_BUF(mac); dev = alloc_etherdev(sizeof(struct at91_private)); if (!dev) @@ -1081,12 +1082,11 @@ static int __init at91ether_setup(unsigned long phy_type, unsigned short phy_add } /* Display ethernet banner */ - printk(KERN_INFO "%s: AT91 ethernet at 0x%08x int=%d %s%s (%02x:%02x:%02x:%02x:%02x:%02x)\n", - dev->name, (uint) dev->base_addr, dev->irq, - at91_emac_read(AT91_EMAC_CFG) & AT91_EMAC_SPD ? "100-" : "10-", - at91_emac_read(AT91_EMAC_CFG) & AT91_EMAC_FD ? "FullDuplex" : "HalfDuplex", - dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2], - dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]); + printk(KERN_INFO "%s: AT91 ethernet at 0x%08x int=%d %s%s (%s)\n", + dev->name, (uint) dev->base_addr, dev->irq, + at91_emac_read(AT91_EMAC_CFG) & AT91_EMAC_SPD ? "100-" : "10-", + at91_emac_read(AT91_EMAC_CFG) & AT91_EMAC_FD ? "FullDuplex" : "HalfDuplex", + print_mac(mac, dev->dev_addr)); if ((phy_type == MII_DM9161_ID) || (lp->phy_type == MII_DM9161A_ID)) printk(KERN_INFO "%s: Davicom 9161 PHY %s\n", dev->name, (lp->phy_media == PORT_FIBRE) ? "(Fiber)" : "(Copper)"); else if (phy_type == MII_LXT971A_ID) diff --git a/drivers/net/arm/ether1.c b/drivers/net/arm/ether1.c index 6ec8a587c1d2..3bb9e293e2ef 100644 --- a/drivers/net/arm/ether1.c +++ b/drivers/net/arm/ether1.c @@ -996,6 +996,7 @@ ether1_probe(struct expansion_card *ec, const struct ecard_id *id) { struct net_device *dev; int i, ret = 0; + DECLARE_MAC_BUF(mac); ether1_banner(); @@ -1043,12 +1044,9 @@ ether1_probe(struct expansion_card *ec, const struct ecard_id *id) if (ret) goto free; - printk(KERN_INFO "%s: ether1 in slot %d, ", - dev->name, ec->slot_no); + printk(KERN_INFO "%s: ether1 in slot %d, %s\n", + dev->name, ec->slot_no, print_mac(mac, dev->dev_addr)); - for (i = 0; i < 6; i++) - printk ("%2.2x%c", dev->dev_addr[i], i == 5 ? '\n' : ':'); - ecard_set_drvdata(ec, dev); return 0; diff --git a/drivers/net/arm/ether3.c b/drivers/net/arm/ether3.c index 4a914748c0e4..67e96ae85035 100644 --- a/drivers/net/arm/ether3.c +++ b/drivers/net/arm/ether3.c @@ -775,7 +775,8 @@ ether3_probe(struct expansion_card *ec, const struct ecard_id *id) { const struct ether3_data *data = id->data; struct net_device *dev; - int i, bus_type, ret; + int bus_type, ret; + DECLARE_MAC_BUF(mac); ether3_banner(); @@ -858,9 +859,8 @@ ether3_probe(struct expansion_card *ec, const struct ecard_id *id) if (ret) goto free; - printk("%s: %s in slot %d, ", dev->name, data->name, ec->slot_no); - for (i = 0; i < 6; i++) - printk("%2.2x%c", dev->dev_addr[i], i == 5 ? '\n' : ':'); + printk("%s: %s in slot %d, %s\n", + dev->name, data->name, ec->slot_no, print_mac(mac, dev->dev_addr)); ecard_set_drvdata(ec, dev); return 0; diff --git a/drivers/net/arm/etherh.c b/drivers/net/arm/etherh.c index 5d093b3ddcd4..00081d2b9cd5 100644 --- a/drivers/net/arm/etherh.c +++ b/drivers/net/arm/etherh.c @@ -648,6 +648,7 @@ etherh_probe(struct expansion_card *ec, const struct ecard_id *id) struct net_device *dev; struct etherh_priv *eh; int i, ret; + DECLARE_MAC_BUF(mac); etherh_banner(); @@ -745,11 +746,8 @@ etherh_probe(struct expansion_card *ec, const struct ecard_id *id) if (ret) goto free; - printk(KERN_INFO "%s: %s in slot %d, ", - dev->name, data->name, ec->slot_no); - - for (i = 0; i < 6; i++) - printk("%2.2x%c", dev->dev_addr[i], i == 5 ? '\n' : ':'); + printk(KERN_INFO "%s: %s in slot %d, %s\n", + dev->name, data->name, ec->slot_no, print_mac(mac, dev->dev_addr)); ecard_set_drvdata(ec, dev); diff --git a/drivers/net/at1700.c b/drivers/net/at1700.c index a124fdb2bce6..b032c1bf492f 100644 --- a/drivers/net/at1700.c +++ b/drivers/net/at1700.c @@ -265,6 +265,7 @@ static int __init at1700_probe1(struct net_device *dev, int ioaddr) unsigned int i, irq, is_fmv18x = 0, is_at1700 = 0; int slot, ret = -ENODEV; struct net_local *lp = netdev_priv(dev); + DECLARE_MAC_BUF(mac); if (!request_region(ioaddr, AT1700_IO_EXTENT, DRV_NAME)) return -EBUSY; @@ -388,16 +389,15 @@ found: if (is_at1700) { for(i = 0; i < 3; i++) { unsigned short eeprom_val = read_eeprom(ioaddr, 4+i); - printk("%04x", eeprom_val); ((unsigned short *)dev->dev_addr)[i] = ntohs(eeprom_val); } } else { for(i = 0; i < 6; i++) { unsigned char val = inb(ioaddr + SAPROM + i); - printk("%02x", val); dev->dev_addr[i] = val; } } + printk("%s", print_mac(mac, dev->dev_addr)); /* The EEPROM word 12 bit 0x0400 means use regular 100 ohm 10baseT signals, rather than 150 ohm shielded twisted pair compensation. diff --git a/drivers/net/atarilance.c b/drivers/net/atarilance.c index 8bf548e1cb4e..ebf1a3a88e15 100644 --- a/drivers/net/atarilance.c +++ b/drivers/net/atarilance.c @@ -467,6 +467,7 @@ static unsigned long __init lance_probe1( struct net_device *dev, int i; static int did_version; unsigned short save1, save2; + DECLARE_MAC_BUF(mac); PROBE_PRINT(( "Probing for Lance card at mem %#lx io %#lx\n", (long)memaddr, (long)ioaddr )); @@ -595,8 +596,7 @@ static unsigned long __init lance_probe1( struct net_device *dev, i = IO->mem; break; } - for( i = 0; i < 6; ++i ) - printk( "%02x%s", dev->dev_addr[i], (i < 5) ? ":" : "\n" ); + printk("%s\n", print_mac(mac, dev->dev_addr)); if (lp->cardtype == OLD_RIEBL) { printk( "%s: Warning: This is a default ethernet address!\n", dev->name ); @@ -779,6 +779,8 @@ static int lance_start_xmit( struct sk_buff *skb, struct net_device *dev ) int entry, len; struct lance_tx_head *head; unsigned long flags; + DECLARE_MAC_BUF(mac); + DECLARE_MAC_BUF(mac2); DPRINTK( 2, ( "%s: lance_start_xmit() called, csr0 %4.4x.\n", dev->name, DREG )); @@ -801,17 +803,13 @@ static int lance_start_xmit( struct sk_buff *skb, struct net_device *dev ) /* Fill in a Tx ring entry */ if (lance_debug >= 3) { - u_char *p; - int i; - printk( "%s: TX pkt type 0x%04x from ", dev->name, - ((u_short *)skb->data)[6]); - for( p = &((u_char *)skb->data)[6], i = 0; i < 6; i++ ) - printk("%02x%s", *p++, i != 5 ? ":" : "" ); - printk(" to "); - for( p = (u_char *)skb->data, i = 0; i < 6; i++ ) - printk("%02x%s", *p++, i != 5 ? ":" : "" ); - printk(" data at 0x%08x len %d\n", (int)skb->data, - (int)skb->len ); + printk( "%s: TX pkt type 0x%04x from " + "%s to %s" + " data at 0x%08x len %d\n", + dev->name, ((u_short *)skb->data)[6], + print_mac(mac, &skb->data[6]), + print_mac(mac2, skb->data), + (int)skb->data, (int)skb->len ); } /* We're not prepared for the int until the last flags are set/reset. And @@ -1021,19 +1019,18 @@ static int lance_rx( struct net_device *dev ) } if (lance_debug >= 3) { - u_char *data = PKTBUF_ADDR(head), *p; - printk( "%s: RX pkt type 0x%04x from ", dev->name, - ((u_short *)data)[6]); - for( p = &data[6], i = 0; i < 6; i++ ) - printk("%02x%s", *p++, i != 5 ? ":" : "" ); - printk(" to "); - for( p = data, i = 0; i < 6; i++ ) - printk("%02x%s", *p++, i != 5 ? ":" : "" ); - printk(" data %02x %02x %02x %02x %02x %02x %02x %02x " + u_char *data = PKTBUF_ADDR(head); + DECLARE_MAC_BUF(mac); + DECLARE_MAC_BUF(mac2); + + printk(KERN_DEBUG "%s: RX pkt type 0x%04x from %s to %s ", + "data %02x %02x %02x %02x %02x %02x %02x %02x " "len %d\n", + dev->name, ((u_short *)data)[6], + print_mac(mac, &data[6]), print_mac(mac2, data), data[15], data[16], data[17], data[18], data[19], data[20], data[21], data[22], - pkt_len ); + pkt_len); } skb_reserve( skb, 2 ); /* 16 byte align */ diff --git a/drivers/net/atp.c b/drivers/net/atp.c index cec2e3672cd0..62f09e59d9c4 100644 --- a/drivers/net/atp.c +++ b/drivers/net/atp.c @@ -248,6 +248,7 @@ static int __init atp_probe1(long ioaddr) struct net_local *lp; int saved_ctrl_reg, status, i; int res; + DECLARE_MAC_BUF(mac); outb(0xff, ioaddr + PAR_DATA); /* Save the original value of the Control register, in case we guessed @@ -322,10 +323,9 @@ static int __init atp_probe1(long ioaddr) printk(KERN_INFO "%s", version); #endif - printk(KERN_NOTICE "%s: Pocket adapter found at %#3lx, IRQ %d, SAPROM " - "%02X:%02X:%02X:%02X:%02X:%02X.\n", dev->name, dev->base_addr, - dev->irq, dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2], - dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]); + printk(KERN_NOTICE "%s: Pocket adapter found at %#3lx, IRQ %d, " + "SAPROM %s.\n", + dev->name, dev->base_addr, dev->irq, print_mac(mac, dev->dev_addr)); /* Reset the ethernet hardware and activate the printer pass-through. */ write_reg_high(ioaddr, CMR1, CMR1h_RESET | CMR1h_MUX); diff --git a/drivers/net/b44.c b/drivers/net/b44.c index 6d193705a3bc..40842a6aa994 100644 --- a/drivers/net/b44.c +++ b/drivers/net/b44.c @@ -2100,7 +2100,8 @@ static int __devinit b44_init_one(struct pci_dev *pdev, unsigned long b44reg_base, b44reg_len; struct net_device *dev; struct b44 *bp; - int err, i; + int err; + DECLARE_MAC_BUF(mac); if (b44_version_printed++ == 0) printk(KERN_INFO "%s", version); @@ -2229,10 +2230,8 @@ static int __devinit b44_init_one(struct pci_dev *pdev, */ b44_chip_reset(bp); - printk(KERN_INFO "%s: Broadcom 4400 10/100BaseT Ethernet ", dev->name); - for (i = 0; i < 6; i++) - printk("%2.2x%c", dev->dev_addr[i], - i == 5 ? '\n' : ':'); + printk(KERN_INFO "%s: Broadcom 4400 10/100BaseT Ethernet %s\n", + dev->name, print_mac(mac, dev->dev_addr)); return 0; diff --git a/drivers/net/bmac.c b/drivers/net/bmac.c index 2761441f6644..a42bd19646d3 100644 --- a/drivers/net/bmac.c +++ b/drivers/net/bmac.c @@ -1258,6 +1258,7 @@ static int __devinit bmac_probe(struct macio_dev *mdev, const struct of_device_i unsigned char addr[6]; struct net_device *dev; int is_bmac_plus = ((int)match->data) != 0; + DECLARE_MAC_BUF(mac); if (macio_resource_count(mdev) != 3 || macio_irq_count(mdev) != 3) { printk(KERN_ERR "BMAC: can't use, need 3 addrs and 3 intrs\n"); @@ -1367,9 +1368,8 @@ static int __devinit bmac_probe(struct macio_dev *mdev, const struct of_device_i goto err_out_irq2; } - printk(KERN_INFO "%s: BMAC%s at", dev->name, (is_bmac_plus? "+": "")); - for (j = 0; j < 6; ++j) - printk("%c%.2x", (j? ':': ' '), dev->dev_addr[j]); + printk(KERN_INFO "%s: BMAC%s at %s", + dev->name, (is_bmac_plus ? "+" : ""), print_mac(mac, dev->dev_addr)); XXDEBUG((", base_addr=%#0lx", dev->base_addr)); printk("\n"); diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c index 5ee805b3e0e6..ee9aed3aa489 100644 --- a/drivers/net/bnx2.c +++ b/drivers/net/bnx2.c @@ -6821,8 +6821,9 @@ bnx2_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) static int version_printed = 0; struct net_device *dev = NULL; struct bnx2 *bp; - int rc, i; + int rc; char str[40]; + DECLARE_MAC_BUF(mac); if (version_printed++ == 0) printk(KERN_INFO "%s", version); @@ -6890,19 +6891,14 @@ bnx2_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) } printk(KERN_INFO "%s: %s (%c%d) %s found at mem %lx, " - "IRQ %d, ", + "IRQ %d, node addr %s\n", dev->name, bp->name, ((CHIP_ID(bp) & 0xf000) >> 12) + 'A', ((CHIP_ID(bp) & 0x0ff0) >> 4), bnx2_bus_string(bp, str), dev->base_addr, - bp->pdev->irq); - - printk("node addr "); - for (i = 0; i < 6; i++) - printk("%2.2x", dev->dev_addr[i]); - printk("\n"); + bp->pdev->irq, print_mac(mac, dev->dev_addr)); return 0; } diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index ea58144c220e..8f77db2112ce 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -1604,6 +1604,7 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev) struct slave *slave, *oldcurrent; struct sockaddr addr; int mac_addr_differ; + DECLARE_MAC_BUF(mac); /* slave is not a slave or master is not master of this slave */ if (!(slave_dev->flags & IFF_SLAVE) || @@ -1631,19 +1632,13 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev) ETH_ALEN); if (!mac_addr_differ && (bond->slave_cnt > 1)) { printk(KERN_WARNING DRV_NAME - ": %s: Warning: the permanent HWaddr of %s " - "- %02X:%02X:%02X:%02X:%02X:%02X - is " - "still in use by %s. Set the HWaddr of " - "%s to a different address to avoid " - "conflicts.\n", + ": %s: Warning: the permanent HWaddr of %s - " + "%s - is still in use by %s. " + "Set the HWaddr of %s to a different address " + "to avoid conflicts.\n", bond_dev->name, slave_dev->name, - slave->perm_hwaddr[0], - slave->perm_hwaddr[1], - slave->perm_hwaddr[2], - slave->perm_hwaddr[3], - slave->perm_hwaddr[4], - slave->perm_hwaddr[5], + print_mac(mac, slave->perm_hwaddr), bond_dev->name, slave_dev->name); } @@ -3006,6 +3001,7 @@ static void bond_info_show_master(struct seq_file *seq) if (bond->params.mode == BOND_MODE_8023AD) { struct ad_info ad_info; + DECLARE_MAC_BUF(mac); seq_puts(seq, "\n802.3ad info\n"); seq_printf(seq, "LACP rate: %s\n", @@ -3025,13 +3021,8 @@ static void bond_info_show_master(struct seq_file *seq) ad_info.actor_key); seq_printf(seq, "\tPartner Key: %d\n", ad_info.partner_key); - seq_printf(seq, "\tPartner Mac Address: %02x:%02x:%02x:%02x:%02x:%02x\n", - ad_info.partner_system[0], - ad_info.partner_system[1], - ad_info.partner_system[2], - ad_info.partner_system[3], - ad_info.partner_system[4], - ad_info.partner_system[5]); + seq_printf(seq, "\tPartner Mac Address: %s\n", + print_mac(mac, ad_info.partner_system)); } } } @@ -3039,6 +3030,7 @@ static void bond_info_show_master(struct seq_file *seq) static void bond_info_show_slave(struct seq_file *seq, const struct slave *slave) { struct bonding *bond = seq->private; + DECLARE_MAC_BUF(mac); seq_printf(seq, "\nSlave Interface: %s\n", slave->dev->name); seq_printf(seq, "MII Status: %s\n", @@ -3047,10 +3039,8 @@ static void bond_info_show_slave(struct seq_file *seq, const struct slave *slave slave->link_failure_count); seq_printf(seq, - "Permanent HW addr: %02x:%02x:%02x:%02x:%02x:%02x\n", - slave->perm_hwaddr[0], slave->perm_hwaddr[1], - slave->perm_hwaddr[2], slave->perm_hwaddr[3], - slave->perm_hwaddr[4], slave->perm_hwaddr[5]); + "Permanent HW addr: %s\n", + print_mac(mac, slave->perm_hwaddr)); if (bond->params.mode == BOND_MODE_8023AD) { const struct aggregator *agg diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c index a771853219da..f10927639b5c 100644 --- a/drivers/net/bonding/bond_sysfs.c +++ b/drivers/net/bonding/bond_sysfs.c @@ -1361,17 +1361,14 @@ static ssize_t bonding_show_ad_partner_mac(struct device *d, { int count = 0; struct bonding *bond = to_bond(d); + DECLARE_MAC_BUF(mac); if (bond->params.mode == BOND_MODE_8023AD) { struct ad_info ad_info; if (!bond_3ad_get_active_agg_info(bond, &ad_info)) { - count = sprintf(buf,"%02x:%02x:%02x:%02x:%02x:%02x\n", - ad_info.partner_system[0], - ad_info.partner_system[1], - ad_info.partner_system[2], - ad_info.partner_system[3], - ad_info.partner_system[4], - ad_info.partner_system[5]) + 1; + count = sprintf(buf,"%s\n", + print_mac(mac, ad_info.partner_system)) + + 1; } } else diff --git a/drivers/net/cassini.c b/drivers/net/cassini.c index f44f3d2a4b4e..adc2e4d5a69e 100644 --- a/drivers/net/cassini.c +++ b/drivers/net/cassini.c @@ -4877,6 +4877,7 @@ static int __devinit cas_init_one(struct pci_dev *pdev, int i, err, pci_using_dac; u16 pci_cmd; u8 orig_cacheline_size = 0, cas_cacheline_size = 0; + DECLARE_MAC_BUF(mac); if (cas_version_printed++ == 0) printk(KERN_INFO "%s", version); @@ -5084,16 +5085,12 @@ static int __devinit cas_init_one(struct pci_dev *pdev, i = readl(cp->regs + REG_BIM_CFG); printk(KERN_INFO "%s: Sun Cassini%s (%sbit/%sMHz PCI/%s) " - "Ethernet[%d] ", dev->name, + "Ethernet[%d] %s\n", dev->name, (cp->cas_flags & CAS_FLAG_REG_PLUS) ? "+" : "", (i & BIM_CFG_32BIT) ? "32" : "64", (i & BIM_CFG_66MHZ) ? "66" : "33", - (cp->phy_type == CAS_PHY_SERDES) ? "Fi" : "Cu", pdev->irq); - - for (i = 0; i < 6; i++) - printk("%2.2x%c", dev->dev_addr[i], - i == 5 ? ' ' : ':'); - printk("\n"); + (cp->phy_type == CAS_PHY_SERDES) ? "Fi" : "Cu", pdev->irq, + print_mac(mac, dev->dev_addr)); pci_set_drvdata(pdev, dev); cp->hw_running = 1; diff --git a/drivers/net/cris/eth_v10.c b/drivers/net/cris/eth_v10.c index 5bdf5ca85a65..314b2f68f78f 100644 --- a/drivers/net/cris/eth_v10.c +++ b/drivers/net/cris/eth_v10.c @@ -618,12 +618,8 @@ e100_set_mac_address(struct net_device *dev, void *p) /* show it in the log as well */ - printk(KERN_INFO "%s: changed MAC to ", dev->name); - - for (i = 0; i < 5; i++) - printk("%02X:", dev->dev_addr[i]); - - printk("%02X\n", dev->dev_addr[i]); + printk(KERN_INFO "%s: changed MAC to %s\n", + dev->name, print_mac(mac, dev->dev_addr)); spin_unlock(&np->lock); diff --git a/drivers/net/cs89x0.c b/drivers/net/cs89x0.c index 4cf82cf5ac10..571750975137 100644 --- a/drivers/net/cs89x0.c +++ b/drivers/net/cs89x0.c @@ -516,6 +516,7 @@ cs89x0_probe1(struct net_device *dev, int ioaddr, int modular) unsigned rev_type = 0; int eeprom_buff[CHKSUM_LEN]; int retval; + DECLARE_MAC_BUF(mac); /* Initialize the device structure. */ if (!modular) { @@ -840,11 +841,7 @@ cs89x0_probe1(struct net_device *dev, int ioaddr, int modular) } /* print the ethernet address. */ - printk(", MAC"); - for (i = 0; i < ETH_ALEN; i++) - { - printk("%c%02x", i ? ':' : ' ', dev->dev_addr[i]); - } + printk(", MAC %s", print_mac(mac, dev->dev_addr)); dev->open = net_open; dev->stop = net_close; @@ -1806,17 +1803,15 @@ static int set_mac_address(struct net_device *dev, void *p) int i; struct sockaddr *addr = p; - if (netif_running(dev)) return -EBUSY; memcpy(dev->dev_addr, addr->sa_data, dev->addr_len); if (net_debug) { - printk("%s: Setting MAC address to ", dev->name); - for (i = 0; i < dev->addr_len; i++) - printk(" %2.2x", dev->dev_addr[i]); - printk(".\n"); + DECLARE_MAC_BUF(mac); + printk("%s: Setting MAC address to %s.\n", + dev->name, print_mac(mac, dev->dev_addr)); } /* set the Ethernet address */ for (i=0; i < ETH_ALEN/2; i++) diff --git a/drivers/net/de600.c b/drivers/net/de600.c index 421c2ca49711..cb849b091f98 100644 --- a/drivers/net/de600.c +++ b/drivers/net/de600.c @@ -384,6 +384,7 @@ static struct net_device * __init de600_probe(void) int i; struct net_device *dev; int err; + DECLARE_MAC_BUF(mac); dev = alloc_etherdev(0); if (!dev) @@ -438,10 +439,7 @@ static struct net_device * __init de600_probe(void) goto out1; } - printk(", Ethernet Address: %02X", dev->dev_addr[0]); - for (i = 1; i < ETH_ALEN; i++) - printk(":%02X",dev->dev_addr[i]); - printk("\n"); + printk(", Ethernet Address: %s\n", print_mac(mac, dev->dev_addr)); dev->open = de600_open; dev->stop = de600_close; diff --git a/drivers/net/de620.c b/drivers/net/de620.c index 4b93902906ba..3f5190c654cf 100644 --- a/drivers/net/de620.c +++ b/drivers/net/de620.c @@ -807,6 +807,7 @@ struct net_device * __init de620_probe(int unit) struct net_device *dev; int err = -ENOMEM; int i; + DECLARE_MAC_BUF(mac); dev = alloc_etherdev(0); if (!dev) @@ -853,13 +854,14 @@ struct net_device * __init de620_probe(int unit) } /* else, got it! */ - printk(", Ethernet Address: %2.2X", - dev->dev_addr[0] = nic_data.NodeID[0]); + dev->dev_addr[0] = nic_data.NodeID[0]; for (i = 1; i < ETH_ALEN; i++) { - printk(":%2.2X", dev->dev_addr[i] = nic_data.NodeID[i]); + dev->dev_addr[i] = nic_data.NodeID[i]; dev->broadcast[i] = 0xff; } + printk(", Ethernet Address: %s", print_mac(mac, dev->dev_addr)); + printk(" (%dk RAM,", (nic_data.RAM_Size) ? (nic_data.RAM_Size >> 2) : 64); diff --git a/drivers/net/declance.c b/drivers/net/declance.c index 7e7ac3330e60..00e0194bfef0 100644 --- a/drivers/net/declance.c +++ b/drivers/net/declance.c @@ -1027,6 +1027,7 @@ static int __init dec_lance_probe(struct device *bdev, const int type) int i, ret; unsigned long esar_base; unsigned char *esar; + DECLARE_MAC_BUF(mac); if (dec_lance_debug && version_printed++ == 0) printk(version); @@ -1214,21 +1215,20 @@ static int __init dec_lance_probe(struct device *bdev, const int type) */ switch (type) { case ASIC_LANCE: - printk("%s: IOASIC onboard LANCE, addr = ", name); + printk("%s: IOASIC onboard LANCE", name); break; case PMAD_LANCE: - printk("%s: PMAD-AA, addr = ", name); + printk("%s: PMAD-AA", name); break; case PMAX_LANCE: - printk("%s: PMAX onboard LANCE, addr = ", name); + printk("%s: PMAX onboard LANCE", name); break; } - for (i = 0; i < 6; i++) { + for (i = 0; i < 6; i++) dev->dev_addr[i] = esar[i * 4]; - printk("%2.2x%c", dev->dev_addr[i], i == 5 ? ',' : ':'); - } - printk(" irq = %d\n", dev->irq); + printk(", addr = %s, irq = %d\n", + print_mac(mac, dev->dev_addr), dev->irq); dev->open = &lance_open; dev->stop = &lance_close; diff --git a/drivers/net/depca.c b/drivers/net/depca.c index 28fa2bdc8c79..ace39ec0a367 100644 --- a/drivers/net/depca.c +++ b/drivers/net/depca.c @@ -573,6 +573,7 @@ static int __init depca_hw_init (struct net_device *dev, struct device *device) s16 nicsr; u_long ioaddr; u_long mem_start; + DECLARE_MAC_BUF(mac); /* * We are now supposed to enter this function with the @@ -632,14 +633,11 @@ static int __init depca_hw_init (struct net_device *dev, struct device *device) printk(", h/w address "); status = get_hw_addr(dev); + printk("%s", print_mac(mac, dev->dev_addr)); if (status != 0) { printk(" which has an Ethernet PROM CRC error.\n"); return -ENXIO; } - for (i = 0; i < ETH_ALEN - 1; i++) { /* get the ethernet address */ - printk("%2.2x:", dev->dev_addr[i]); - } - printk("%2.2x", dev->dev_addr[i]); /* Set up the maximum amount of network RAM(kB) */ netRAM = ((lp->adapter != DEPCA) ? 64 : 48); @@ -1843,6 +1841,7 @@ static void depca_dbg_open(struct net_device *dev) u_long ioaddr = dev->base_addr; struct depca_init *p = &lp->init_block; int i; + DECLARE_MAC_BUF(mac); if (depca_debug > 1) { /* Do not copy the shadow init block into shared memory */ @@ -1881,11 +1880,7 @@ static void depca_dbg_open(struct net_device *dev) printk("...0x%8.8x\n", readl(&lp->tx_ring[i].base)); printk("Initialisation block at 0x%8.8lx(Phys)\n", lp->mem_start); printk(" mode: 0x%4.4x\n", p->mode); - printk(" physical address: "); - for (i = 0; i < ETH_ALEN - 1; i++) { - printk("%2.2x:", p->phys_addr[i]); - } - printk("%2.2x\n", p->phys_addr[i]); + printk(" physical address: %s\n", print_mac(mac, p->phys_addr)); printk(" multicast hash table: "); for (i = 0; i < (HASH_TABLE_LEN >> 3) - 1; i++) { printk("%2.2x:", p->mcast_table[i]); diff --git a/drivers/net/dgrs.c b/drivers/net/dgrs.c index a9ef79da3dc7..054f2ba5f698 100644 --- a/drivers/net/dgrs.c +++ b/drivers/net/dgrs.c @@ -1139,6 +1139,7 @@ dgrs_probe1(struct net_device *dev) DGRS_PRIV *priv = (DGRS_PRIV *) dev->priv; unsigned long i; int rc; + DECLARE_MAC_BUF(mac); printk("%s: Digi RightSwitch io=%lx mem=%lx irq=%d plx=%lx dma=%lx\n", dev->name, dev->base_addr, dev->mem_start, dev->irq, @@ -1154,11 +1155,9 @@ dgrs_probe1(struct net_device *dev) /* * Get ether address of board */ - printk("%s: Ethernet address", dev->name); memcpy(dev->dev_addr, priv->port->ethaddr, 6); - for (i = 0; i < 6; ++i) - printk("%c%2.2x", i ? ':' : ' ', dev->dev_addr[i]); - printk("\n"); + printk("%s: Ethernet address %s\n", + dev->name, print_mac(mac, dev->dev_addr)); if (dev->dev_addr[0] & 1) { @@ -1214,15 +1213,12 @@ static int __init dgrs_initclone(struct net_device *dev) { DGRS_PRIV *priv = (DGRS_PRIV *) dev->priv; - int i; + DECLARE_MAC_BUF(mac); - printk("%s: Digi RightSwitch port %d ", - dev->name, priv->chan); - for (i = 0; i < 6; ++i) - printk("%c%2.2x", i ? ':' : ' ', dev->dev_addr[i]); - printk("\n"); + printk("%s: Digi RightSwitch port %d %s\n", + dev->name, priv->chan, print_mac(mac, dev->dev_addr)); - return (0); + return 0; } static struct net_device * __init diff --git a/drivers/net/dl2k.c b/drivers/net/dl2k.c index 12486e13b85b..e91b7096838a 100644 --- a/drivers/net/dl2k.c +++ b/drivers/net/dl2k.c @@ -97,6 +97,7 @@ rio_probe1 (struct pci_dev *pdev, const struct pci_device_id *ent) static int version_printed; void *ring_space; dma_addr_t ring_dma; + DECLARE_MAC_BUF(mac); if (!version_printed++) printk ("%s", version); @@ -256,10 +257,8 @@ rio_probe1 (struct pci_dev *pdev, const struct pci_device_id *ent) card_idx++; - printk (KERN_INFO "%s: %s, %02x:%02x:%02x:%02x:%02x:%02x, IRQ %d\n", - dev->name, np->name, - dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2], - dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5], irq); + printk (KERN_INFO "%s: %s, %s, IRQ %d\n", + dev->name, np->name, print_mac(mac, dev->dev_addr), irq); if (tx_coalesce > 1) printk(KERN_INFO "tx_coalesce:\t%d packets\n", tx_coalesce); diff --git a/drivers/net/dm9000.c b/drivers/net/dm9000.c index f691ef61b2d3..27ac010900ab 100644 --- a/drivers/net/dm9000.c +++ b/drivers/net/dm9000.c @@ -595,11 +595,10 @@ dm9000_probe(struct platform_device *pdev) ret = register_netdev(ndev); if (ret == 0) { - printk("%s: dm9000 at %p,%p IRQ %d MAC: ", - ndev->name, db->io_addr, db->io_data, ndev->irq); - for (i = 0; i < 5; i++) - printk("%02x:", ndev->dev_addr[i]); - printk("%02x\n", ndev->dev_addr[5]); + DECLARE_MAC_BUF(mac); + printk("%s: dm9000 at %p,%p IRQ %d MAC: %s\n", + ndev->name, db->io_addr, db->io_data, ndev->irq, + print_mac(mac, ndev->dev_addr)); } return 0; diff --git a/drivers/net/e100.c b/drivers/net/e100.c index 99126564f1a0..720994b1e13a 100644 --- a/drivers/net/e100.c +++ b/drivers/net/e100.c @@ -2548,6 +2548,7 @@ static int __devinit e100_probe(struct pci_dev *pdev, struct net_device *netdev; struct nic *nic; int err; + DECLARE_MAC_BUF(mac); if(!(netdev = alloc_etherdev(sizeof(struct nic)))) { if(((1 << debug) - 1) & NETIF_MSG_PROBE) @@ -2679,11 +2680,9 @@ static int __devinit e100_probe(struct pci_dev *pdev, goto err_out_free; } - DPRINTK(PROBE, INFO, "addr 0x%llx, irq %d, " - "MAC addr %02X:%02X:%02X:%02X:%02X:%02X\n", - (unsigned long long)pci_resource_start(pdev, use_io ? 1 : 0), pdev->irq, - netdev->dev_addr[0], netdev->dev_addr[1], netdev->dev_addr[2], - netdev->dev_addr[3], netdev->dev_addr[4], netdev->dev_addr[5]); + DPRINTK(PROBE, INFO, "addr 0x%llx, irq %d, MAC addr %s\n", + (unsigned long long)pci_resource_start(pdev, use_io ? 1 : 0), + pdev->irq, print_mac(mac, netdev->dev_addr)); return 0; diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c index 7befb706ad55..ad444c9a5d04 100644 --- a/drivers/net/e1000/e1000_main.c +++ b/drivers/net/e1000/e1000_main.c @@ -872,6 +872,8 @@ e1000_probe(struct pci_dev *pdev, int i, err, pci_using_dac; uint16_t eeprom_data = 0; uint16_t eeprom_apme_mask = E1000_EEPROM_APME; + DECLARE_MAC_BUF(mac); + if ((err = pci_enable_device(pdev))) return err; @@ -1132,8 +1134,7 @@ e1000_probe(struct pci_dev *pdev, "32-bit")); } - for (i = 0; i < 6; i++) - printk("%2.2x%c", netdev->dev_addr[i], i == 5 ? '\n' : ':'); + printk("%s\n", print_mac(mac, netdev->dev_addr)); /* reset the hardware with the new settings */ e1000_reset(adapter); diff --git a/drivers/net/eepro.c b/drivers/net/eepro.c index 54811f6f766d..83bda6ccde98 100644 --- a/drivers/net/eepro.c +++ b/drivers/net/eepro.c @@ -690,6 +690,7 @@ static void __init eepro_print_info (struct net_device *dev) struct eepro_local * lp = netdev_priv(dev); int i; const char * ifmap[] = {"AUI", "10Base2", "10BaseT"}; + DECLARE_MAC_BUF(mac); i = inb(dev->base_addr + ID_REG); printk(KERN_DEBUG " id: %#x ",i); @@ -711,10 +712,10 @@ static void __init eepro_print_info (struct net_device *dev) case LAN595: printk("%s: Intel 82595-based lan card at %#x,", dev->name, (unsigned)dev->base_addr); + break; } - for (i=0; i < 6; i++) - printk("%c%02x", i ? ':' : ' ', dev->dev_addr[i]); + printk(" %s", print_mac(mac, dev->dev_addr)); if (net_debug > 3) printk(KERN_DEBUG ", %dK RCV buffer", diff --git a/drivers/net/eepro100.c b/drivers/net/eepro100.c index f8b69ceb2be6..1548a80f917d 100644 --- a/drivers/net/eepro100.c +++ b/drivers/net/eepro100.c @@ -622,6 +622,7 @@ static int __devinit speedo_found1(struct pci_dev *pdev, int size; void *tx_ring_space; dma_addr_t tx_ring_dma; + DECLARE_MAC_BUF(mac); size = TX_RING_SIZE * sizeof(struct TxFD) + sizeof(struct speedo_stats); tx_ring_space = pci_alloc_consistent(pdev, size, &tx_ring_dma); @@ -705,12 +706,8 @@ static int __devinit speedo_found1(struct pci_dev *pdev, else product = pci_name(pdev); - printk(KERN_INFO "%s: %s, ", dev->name, product); - - for (i = 0; i < 5; i++) - printk("%2.2X:", dev->dev_addr[i]); - printk("%2.2X, ", dev->dev_addr[i]); - printk("IRQ %d.\n", pdev->irq); + printk(KERN_INFO "%s: %s, %s, IRQ %d.\n", dev->name, product, + print_mac(mac, dev->dev_addr), pdev->irq); sp = netdev_priv(dev); diff --git a/drivers/net/epic100.c b/drivers/net/epic100.c index 5ac56f20003d..ecdd3fc8d70c 100644 --- a/drivers/net/epic100.c +++ b/drivers/net/epic100.c @@ -317,6 +317,7 @@ static int __devinit epic_init_one (struct pci_dev *pdev, int i, ret, option = 0, duplex = 0; void *ring_space; dma_addr_t ring_dma; + DECLARE_MAC_BUF(mac); /* when built into the kernel, we only print version if device is found */ #ifndef MODULE @@ -493,11 +494,9 @@ static int __devinit epic_init_one (struct pci_dev *pdev, if (ret < 0) goto err_out_unmap_rx; - printk(KERN_INFO "%s: %s at %#lx, IRQ %d, ", - dev->name, pci_id_tbl[chip_idx].name, ioaddr, dev->irq); - for (i = 0; i < 5; i++) - printk("%2.2x:", dev->dev_addr[i]); - printk("%2.2x.\n", dev->dev_addr[i]); + printk(KERN_INFO "%s: %s at %#lx, IRQ %d, %s\n", + dev->name, pci_id_tbl[chip_idx].name, ioaddr, dev->irq, + print_mac(mac, dev->dev_addr)); out: return ret; diff --git a/drivers/net/es3210.c b/drivers/net/es3210.c index 238fa8aff02d..deefa51b8c31 100644 --- a/drivers/net/es3210.c +++ b/drivers/net/es3210.c @@ -179,6 +179,7 @@ static int __init es_probe1(struct net_device *dev, int ioaddr) { int i, retval; unsigned long eisa_id; + DECLARE_MAC_BUF(mac); if (!request_region(ioaddr + ES_SA_PROM, ES_IO_EXTENT, "es3210")) return -ENODEV; @@ -190,7 +191,6 @@ static int __init es_probe1(struct net_device *dev, int ioaddr) inb(ioaddr + ES_CFG4), inb(ioaddr + ES_CFG5), inb(ioaddr + ES_CFG6)); #endif - /* Check the EISA ID of the card. */ eisa_id = inl(ioaddr + ES_ID_PORT); if ((eisa_id != ES_EISA_ID1) && (eisa_id != ES_EISA_ID2)) { @@ -198,21 +198,21 @@ static int __init es_probe1(struct net_device *dev, int ioaddr) goto out; } + for (i = 0; i < ETHER_ADDR_LEN ; i++) + dev->dev_addr[i] = inb(ioaddr + ES_SA_PROM + i); + /* Check the Racal vendor ID as well. */ - if (inb(ioaddr + ES_SA_PROM + 0) != ES_ADDR0 - || inb(ioaddr + ES_SA_PROM + 1) != ES_ADDR1 - || inb(ioaddr + ES_SA_PROM + 2) != ES_ADDR2 ) { - printk("es3210.c: card not found"); - for(i = 0; i < ETHER_ADDR_LEN; i++) - printk(" %02x", inb(ioaddr + ES_SA_PROM + i)); - printk(" (invalid prefix).\n"); + if (dev->dev_addr[0] != ES_ADDR0 || + dev->dev_addr[1] != ES_ADDR1 || + dev->dev_addr[2] != ES_ADDR2) { + printk("es3210.c: card not found %s (invalid_prefix).\n", + print_mac(mac, dev->dev_addr)); retval = -ENODEV; goto out; } - printk("es3210.c: ES3210 rev. %ld at %#x, node", eisa_id>>24, ioaddr); - for(i = 0; i < ETHER_ADDR_LEN; i++) - printk(" %02x", (dev->dev_addr[i] = inb(ioaddr + ES_SA_PROM + i))); + printk("es3210.c: ES3210 rev. %ld at %#x, node %s", + eisa_id>>24, ioaddr, print_mac(mac, dev->dev_addr)); /* Snarf the interrupt now. */ if (dev->irq == 0) { diff --git a/drivers/net/ewrk3.c b/drivers/net/ewrk3.c index 142aa225d89e..593a120e31b2 100644 --- a/drivers/net/ewrk3.c +++ b/drivers/net/ewrk3.c @@ -396,6 +396,7 @@ ewrk3_hw_init(struct net_device *dev, u_long iobase) u_long mem_start, shmem_length; u_char cr, cmr, icr, nicsr, lemac, hard_strapped = 0; u_char eeprom_image[EEPROM_MAX], chksum, eisa_cr = 0; + DECLARE_MAC_BUF(mac); /* ** Stop the EWRK3. Enable the DBR ROM. Disable interrupts and remote boot. @@ -460,10 +461,7 @@ ewrk3_hw_init(struct net_device *dev, u_long iobase) if (lemac != LeMAC2) DevicePresent(iobase); /* need after EWRK3_INIT */ status = get_hw_addr(dev, eeprom_image, lemac); - for (i = 0; i < ETH_ALEN - 1; i++) { /* get the ethernet addr. */ - printk("%2.2x:", dev->dev_addr[i]); - } - printk("%2.2x,\n", dev->dev_addr[i]); + printk("%s\n", print_mac(mac, dev->dev_addr)); if (status) { printk(" which has an EEPROM CRC error.\n"); @@ -628,7 +626,7 @@ static int ewrk3_open(struct net_device *dev) { struct ewrk3_private *lp = netdev_priv(dev); u_long iobase = dev->base_addr; - int i, status = 0; + int status = 0; u_char icr, csr; /* @@ -648,12 +646,10 @@ static int ewrk3_open(struct net_device *dev) ewrk3_init(dev); if (ewrk3_debug > 1) { + DECLARE_MAC_BUF(mac); printk("%s: ewrk3 open with irq %d\n", dev->name, dev->irq); - printk(" physical address: "); - for (i = 0; i < 5; i++) { - printk("%2.2x:", (u_char) dev->dev_addr[i]); - } - printk("%2.2x\n", (u_char) dev->dev_addr[i]); + printk(" physical address: %s\n", + print_mac(mac, dev->dev_addr)); if (lp->shmem_length == 0) { printk(" no shared memory, I/O only mode\n"); } else { diff --git a/drivers/net/fealnx.c b/drivers/net/fealnx.c index 402b071d8d53..43f7647ff246 100644 --- a/drivers/net/fealnx.c +++ b/drivers/net/fealnx.c @@ -486,6 +486,7 @@ static int __devinit fealnx_init_one(struct pci_dev *pdev, #else int bar = 1; #endif + DECLARE_MAC_BUF(mac); /* when built into the kernel, we only print version if device is found */ #ifndef MODULE @@ -664,11 +665,9 @@ static int __devinit fealnx_init_one(struct pci_dev *pdev, if (err) goto err_out_free_tx; - printk(KERN_INFO "%s: %s at %p, ", - dev->name, skel_netdrv_tbl[chip_id].chip_name, ioaddr); - for (i = 0; i < 5; i++) - printk("%2.2x:", dev->dev_addr[i]); - printk("%2.2x, IRQ %d.\n", dev->dev_addr[i], irq); + printk(KERN_INFO "%s: %s at %p, %s, IRQ %d.\n", + dev->name, skel_netdrv_tbl[chip_id].chip_name, ioaddr, + print_mac(mac, dev->dev_addr), irq); return 0; diff --git a/drivers/net/fec.c b/drivers/net/fec.c index 4419c3cee995..2b5782056dda 100644 --- a/drivers/net/fec.c +++ b/drivers/net/fec.c @@ -2635,6 +2635,7 @@ static int __init fec_enet_module_init(void) { struct net_device *dev; int i, j, err; + DECLARE_MAC_BUF(mac); printk("FEC ENET Version 0.2\n"); @@ -2653,10 +2654,8 @@ static int __init fec_enet_module_init(void) return -EIO; } - printk("%s: ethernet ", dev->name); - for (j = 0; (j < 5); j++) - printk("%02x:", dev->dev_addr[j]); - printk("%02x\n", dev->dev_addr[5]); + printk("%s: ethernet %s\n", + dev->name, print_mac(mac, dev->dev_addr)); } return 0; } diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c index be744573b1c2..f7354bc9b009 100644 --- a/drivers/net/forcedeth.c +++ b/drivers/net/forcedeth.c @@ -4991,6 +4991,7 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i u32 powerstate, txreg; u32 phystate_orig = 0, phystate; int phyinitialized = 0; + DECLARE_MAC_BUF(mac); dev = alloc_etherdev(sizeof(struct fe_priv)); err = -ENOMEM; @@ -5205,10 +5206,8 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i * Bad mac address. At least one bios sets the mac address * to 01:23:45:67:89:ab */ - printk(KERN_ERR "%s: Invalid Mac address detected: %02x:%02x:%02x:%02x:%02x:%02x\n", - pci_name(pci_dev), - dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2], - dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]); + printk(KERN_ERR "%s: Invalid Mac address detected: %s\n", + pci_name(pci_dev), print_mac(mac, dev->dev_addr)); printk(KERN_ERR "Please complain to your hardware vendor. Switching to a random MAC.\n"); dev->dev_addr[0] = 0x00; dev->dev_addr[1] = 0x00; @@ -5216,9 +5215,8 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i get_random_bytes(&dev->dev_addr[3], 3); } - dprintk(KERN_DEBUG "%s: MAC Address %02x:%02x:%02x:%02x:%02x:%02x\n", pci_name(pci_dev), - dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2], - dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]); + dprintk(KERN_DEBUG "%s: MAC Address %s\n", + pci_name(pci_dev), print_mac(mac, dev->dev_addr)); /* set mac address */ nv_copy_mac_to_hw(dev); diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c index 5a1a1165b48c..0db5e6fabe73 100644 --- a/drivers/net/gianfar.c +++ b/drivers/net/gianfar.c @@ -170,6 +170,7 @@ static int gfar_probe(struct platform_device *pdev) struct resource *r; int idx; int err = 0; + DECLARE_MAC_BUF(mac); einfo = (struct gianfar_platform_data *) pdev->dev.platform_data; @@ -356,10 +357,8 @@ static int gfar_probe(struct platform_device *pdev) gfar_init_sysfs(dev); /* Print out the device info */ - printk(KERN_INFO DEVICE_NAME, dev->name); - for (idx = 0; idx < 6; idx++) - printk("%2.2x%c", dev->dev_addr[idx], idx == 5 ? ' ' : ':'); - printk("\n"); + printk(KERN_INFO DEVICE_NAME "%s\n", + dev->name, print_mac(mac, dev->dev_addr)); /* Even more device info helps when determining which kernel */ /* provided which set of benchmarks. */ diff --git a/drivers/net/hamachi.c b/drivers/net/hamachi.c index da12b3db023f..015ed3a4057f 100644 --- a/drivers/net/hamachi.c +++ b/drivers/net/hamachi.c @@ -580,6 +580,7 @@ static int __devinit hamachi_init_one (struct pci_dev *pdev, void *ring_space; dma_addr_t ring_dma; int ret = -ENOMEM; + DECLARE_MAC_BUF(mac); /* when built into the kernel, we only print version if device is found */ #ifndef MODULE @@ -741,12 +742,9 @@ static int __devinit hamachi_init_one (struct pci_dev *pdev, goto err_out_unmap_rx; } - printk(KERN_INFO "%s: %s type %x at %p, ", + printk(KERN_INFO "%s: %s type %x at %p, %s, IRQ %d.\n", dev->name, chip_tbl[chip_id].name, readl(ioaddr + ChipRev), - ioaddr); - for (i = 0; i < 5; i++) - printk("%2.2x:", dev->dev_addr[i]); - printk("%2.2x, IRQ %d.\n", dev->dev_addr[i], irq); + ioaddr, print_mac(mac, dev->dev_addr), irq); i = readb(ioaddr + PCIClkMeas); printk(KERN_INFO "%s: %d-bit %d Mhz PCI bus (%d), Virtual Jumpers " "%2.2x, LPA %4.4x.\n", diff --git a/drivers/net/hamradio/bpqether.c b/drivers/net/hamradio/bpqether.c index df09210f7351..c05bc37df356 100644 --- a/drivers/net/hamradio/bpqether.c +++ b/drivers/net/hamradio/bpqether.c @@ -64,7 +64,7 @@ #include #include #include -#include +#include #include #include #include @@ -95,7 +95,6 @@ static char bpq_eth_addr[6]; static int bpq_rcv(struct sk_buff *, struct net_device *, struct packet_type *, struct net_device *); static int bpq_device_event(struct notifier_block *, unsigned long, void *); -static const char *bpq_print_ethaddr(const unsigned char *); static struct packet_type bpq_packet_type = { .type = __constant_htons(ETH_P_BPQ), @@ -383,16 +382,6 @@ static int bpq_close(struct net_device *dev) /* * Proc filesystem */ -static const char * bpq_print_ethaddr(const unsigned char *e) -{ - static char buf[18]; - - sprintf(buf, "%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X", - e[0], e[1], e[2], e[3], e[4], e[5]); - - return buf; -} - static void *bpq_seq_start(struct seq_file *seq, loff_t *pos) { int i = 1; @@ -438,14 +427,16 @@ static int bpq_seq_show(struct seq_file *seq, void *v) "dev ether destination accept from\n"); else { const struct bpqdev *bpqdev = v; + DECLARE_MAC_BUF(mac); seq_printf(seq, "%-5s %-10s %s ", bpqdev->axdev->name, bpqdev->ethdev->name, - bpq_print_ethaddr(bpqdev->dest_addr)); + print_mac(mac, bpqdev->dest_addr)); - seq_printf(seq, "%s\n", - (bpqdev->acpt_addr[0] & 0x01) ? "*" - : bpq_print_ethaddr(bpqdev->acpt_addr)); + if (is_multicast_ether_addr(bpqdev->acpt_addr)) + seq_printf(seq, "*\n"); + else + seq_printf(seq, "%s\n", print_mac(mac, bpqdev->acpt_addr)); } return 0; diff --git a/drivers/net/hp-plus.c b/drivers/net/hp-plus.c index 8d4f810fa288..c2c4f49d7578 100644 --- a/drivers/net/hp-plus.c +++ b/drivers/net/hp-plus.c @@ -166,6 +166,7 @@ static int __init hpp_probe1(struct net_device *dev, int ioaddr) const char name[] = "HP-PC-LAN+"; int mem_start; static unsigned version_printed; + DECLARE_MAC_BUF(mac); if (!request_region(ioaddr, HP_IO_EXTENT, DRV_NAME)) return -EBUSY; @@ -180,7 +181,7 @@ static int __init hpp_probe1(struct net_device *dev, int ioaddr) if (ei_debug && version_printed++ == 0) printk(version); - printk("%s: %s at %#3x,", dev->name, name, ioaddr); + printk("%s: %s at %#3x, ", dev->name, name, ioaddr); /* Retrieve and checksum the station address. */ outw(MAC_Page, ioaddr + HP_PAGING); @@ -189,10 +190,11 @@ static int __init hpp_probe1(struct net_device *dev, int ioaddr) unsigned char inval = inb(ioaddr + 8 + i); dev->dev_addr[i] = inval; checksum += inval; - printk(" %2.2x", inval); } checksum += inb(ioaddr + 14); + printk("%s", print_mac(mac, dev->dev_addr)); + if (checksum != 0xff) { printk(" bad checksum %2.2x.\n", checksum); retval = -ENODEV; diff --git a/drivers/net/hp.c b/drivers/net/hp.c index 1f11126de354..c649a8019beb 100644 --- a/drivers/net/hp.c +++ b/drivers/net/hp.c @@ -127,6 +127,7 @@ static int __init hp_probe1(struct net_device *dev, int ioaddr) int i, retval, board_id, wordmode; const char *name; static unsigned version_printed; + DECLARE_MAC_BUF(mac); if (!request_region(ioaddr, HP_IO_EXTENT, DRV_NAME)) return -EBUSY; @@ -158,7 +159,9 @@ static int __init hp_probe1(struct net_device *dev, int ioaddr) printk("%s: %s (ID %02x) at %#3x,", dev->name, name, board_id, ioaddr); for(i = 0; i < ETHER_ADDR_LEN; i++) - printk(" %2.2x", dev->dev_addr[i] = inb(ioaddr + i)); + dev->dev_addr[i] = inb(ioaddr + i); + + printk(" %s", print_mac(mac, dev->dev_addr)); /* Snarf the interrupt now. Someday this could be moved to open(). */ if (dev->irq < 2) { diff --git a/drivers/net/hp100.c b/drivers/net/hp100.c index 406d6525e222..e4fde17e2841 100644 --- a/drivers/net/hp100.c +++ b/drivers/net/hp100.c @@ -2093,9 +2093,9 @@ static void hp100_set_multicast_list(struct net_device *dev) addrs = dmi->dmi_addr; if ((*addrs & 0x01) == 0x01) { /* multicast address? */ #ifdef HP100_DEBUG - printk("hp100: %s: multicast = %02x:%02x:%02x:%02x:%02x:%02x, ", - dev->name, addrs[0], addrs[1], addrs[2], - addrs[3], addrs[4], addrs[5]); + DECLARE_MAC_BUF(mac); + printk("hp100: %s: multicast = %s, ", + dev->name, print_mac(mac, addrs)); #endif for (j = idx = 0; j < 6; j++) { idx ^= *addrs++ & 0x3f; diff --git a/drivers/net/hydra.c b/drivers/net/hydra.c index 31300a9dd965..b96cf2dcb109 100644 --- a/drivers/net/hydra.c +++ b/drivers/net/hydra.c @@ -103,6 +103,7 @@ static int __devinit hydra_init(struct zorro_dev *z) int start_page, stop_page; int j; int err; + DECLARE_MAC_BUF(mac); static u32 hydra_offsets[16] = { 0x00, 0x02, 0x04, 0x06, 0x08, 0x0a, 0x0c, 0x0e, @@ -162,10 +163,8 @@ static int __devinit hydra_init(struct zorro_dev *z) zorro_set_drvdata(z, dev); printk(KERN_INFO "%s: Hydra at 0x%08lx, address " - "%02x:%02x:%02x:%02x:%02x:%02x (hydra.c " HYDRA_VERSION ")\n", - dev->name, z->resource.start, dev->dev_addr[0], dev->dev_addr[1], - dev->dev_addr[2], dev->dev_addr[3], dev->dev_addr[4], - dev->dev_addr[5]); + "%s (hydra.c " HYDRA_VERSION ")\n", + dev->name, z->resource.start, print_mac(mac, dev->dev_addr)); return 0; } diff --git a/drivers/net/ibm_emac/ibm_emac_core.c b/drivers/net/ibm_emac/ibm_emac_core.c index d7da56b105cb..7d4fa7644e4b 100644 --- a/drivers/net/ibm_emac/ibm_emac_core.c +++ b/drivers/net/ibm_emac/ibm_emac_core.c @@ -353,10 +353,9 @@ static void emac_hash_mc(struct ocp_enet_private *dev) for (dmi = dev->ndev->mc_list; dmi; dmi = dmi->next) { int bit; - DBG2("%d: mc %02x:%02x:%02x:%02x:%02x:%02x" NL, - dev->def->index, - dmi->dmi_addr[0], dmi->dmi_addr[1], dmi->dmi_addr[2], - dmi->dmi_addr[3], dmi->dmi_addr[4], dmi->dmi_addr[5]); + DECLARE_MAC_BUF(mac); + DBG2("%d: mc %s" NL, + dev->def->index, print_mac(mac, dmi->dmi_addr)); bit = 63 - (ether_crc(ETH_ALEN, dmi->dmi_addr) >> 26); gaht[bit >> 4] |= 0x8000 >> (bit & 0x0f); @@ -1940,6 +1939,7 @@ static int __init emac_probe(struct ocp_device *ocpdev) struct ocp_device *maldev; struct ocp_enet_private *dev; int err, i; + DECLARE_MAC_BUF(mac); DBG("%d: probe" NL, ocpdev->def->index); @@ -2188,10 +2188,8 @@ static int __init emac_probe(struct ocp_device *ocpdev) ocp_set_drvdata(ocpdev, dev); - printk("%s: emac%d, MAC %02x:%02x:%02x:%02x:%02x:%02x\n", - ndev->name, dev->def->index, - ndev->dev_addr[0], ndev->dev_addr[1], ndev->dev_addr[2], - ndev->dev_addr[3], ndev->dev_addr[4], ndev->dev_addr[5]); + printk("%s: emac%d, MAC %s\n", + ndev->name, dev->def->index, print_mac(mac, ndev->dev_addr)); if (dev->phy.address >= 0) printk("%s: found %s PHY (0x%02x)\n", ndev->name, diff --git a/drivers/net/ibmlana.c b/drivers/net/ibmlana.c index eebf39acf586..91d83aca6bc7 100644 --- a/drivers/net/ibmlana.c +++ b/drivers/net/ibmlana.c @@ -898,6 +898,7 @@ static int ibmlana_probe(struct net_device *dev) int base = 0, irq = 0, iobase = 0, memlen = 0; ibmlana_priv *priv; ibmlana_medium medium; + DECLARE_MAC_BUF(mac); /* can't work without an MCA bus ;-) */ if (MCA_bus == 0) @@ -981,11 +982,10 @@ static int ibmlana_probe(struct net_device *dev) /* print config */ printk(KERN_INFO "%s: IRQ %d, I/O %#lx, memory %#lx-%#lx, " - "MAC address %02x:%02x:%02x:%02x:%02x:%02x.\n", + "MAC address %s.\n", dev->name, priv->realirq, dev->base_addr, dev->mem_start, dev->mem_end - 1, - dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2], - dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]); + print_mac(mac, dev->dev_addr)); printk(KERN_INFO "%s: %s medium\n", dev->name, MediaNames[priv->medium]); /* reset board */ diff --git a/drivers/net/ibmveth.c b/drivers/net/ibmveth.c index 0636883449fc..228973484ed8 100644 --- a/drivers/net/ibmveth.c +++ b/drivers/net/ibmveth.c @@ -1276,16 +1276,13 @@ static int ibmveth_seq_show(struct seq_file *seq, void *v) struct ibmveth_adapter *adapter = seq->private; char *current_mac = ((char*) &adapter->netdev->dev_addr); char *firmware_mac = ((char*) &adapter->mac_addr) ; + DECLARE_MAC_BUF(mac); seq_printf(seq, "%s %s\n\n", ibmveth_driver_string, ibmveth_driver_version); seq_printf(seq, "Unit Address: 0x%x\n", adapter->vdev->unit_address); - seq_printf(seq, "Current MAC: %02X:%02X:%02X:%02X:%02X:%02X\n", - current_mac[0], current_mac[1], current_mac[2], - current_mac[3], current_mac[4], current_mac[5]); - seq_printf(seq, "Firmware MAC: %02X:%02X:%02X:%02X:%02X:%02X\n", - firmware_mac[0], firmware_mac[1], firmware_mac[2], - firmware_mac[3], firmware_mac[4], firmware_mac[5]); + seq_printf(seq, "Current MAC: %s\n", print_mac(mac, current_mac)); + seq_printf(seq, "Firmware MAC: %s\n", print_mac(mac, firmware_mac)); seq_printf(seq, "\nAdapter Statistics:\n"); seq_printf(seq, " TX: vio_map_single failres: %ld\n", adapter->tx_map_failed); diff --git a/drivers/net/ioc3-eth.c b/drivers/net/ioc3-eth.c index 05d2bc15144e..373f72cdbe8e 100644 --- a/drivers/net/ioc3-eth.c +++ b/drivers/net/ioc3-eth.c @@ -443,18 +443,12 @@ static void ioc3_get_eaddr_nic(struct ioc3_private *ip) */ static void ioc3_get_eaddr(struct ioc3_private *ip) { - int i; - + DECLARE_MAC_BUF(mac); ioc3_get_eaddr_nic(ip); - printk("Ethernet address is "); - for (i = 0; i < 6; i++) { - printk("%02x", priv_netdev(ip)->dev_addr[i]); - if (i < 5) - printk(":"); - } - printk(".\n"); + printk("Ethernet address is %s.\n", + print_mac(mac, priv_netdev(ip)->dev_addr)); } static void __ioc3_set_mac_address(struct net_device *dev) diff --git a/drivers/net/isa-skeleton.c b/drivers/net/isa-skeleton.c index 54178111eec5..d6ff26af37b3 100644 --- a/drivers/net/isa-skeleton.c +++ b/drivers/net/isa-skeleton.c @@ -192,6 +192,7 @@ static int __init netcard_probe1(struct net_device *dev, int ioaddr) static unsigned version_printed; int i; int err = -ENODEV; + DECLARE_MAC_BUF(mac); /* Grab the region so that no one else tries to probe our ioports. */ if (!request_region(ioaddr, NETCARD_IO_EXTENT, cardname)) @@ -217,7 +218,9 @@ static int __init netcard_probe1(struct net_device *dev, int ioaddr) /* Retrieve and print the ethernet address. */ for (i = 0; i < 6; i++) - printk(" %2.2x", dev->dev_addr[i] = inb(ioaddr + i)); + dev->dev_addr[i] = inb(ioaddr + i); + + printk("%s", print_mac(mac, dev->dev_addr)); err = -EAGAIN; #ifdef jumpered_interrupts diff --git a/drivers/net/jazzsonic.c b/drivers/net/jazzsonic.c index 13847a3e43e5..d3825c8ee994 100644 --- a/drivers/net/jazzsonic.c +++ b/drivers/net/jazzsonic.c @@ -209,6 +209,7 @@ static int __init jazz_sonic_probe(struct platform_device *pdev) struct resource *res; int err = 0; int i; + DECLARE_MAC_BUF(mac); res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) @@ -233,13 +234,8 @@ static int __init jazz_sonic_probe(struct platform_device *pdev) if (err) goto out1; - printk("%s: MAC ", dev->name); - for (i = 0; i < 6; i++) { - printk("%2.2x", dev->dev_addr[i]); - if (i < 5) - printk(":"); - } - printk(" IRQ %d\n", dev->irq); + printk("%s: MAC %s IRQ %d\n", + dev->name, print_mac(mac, dev->dev_addr), dev->irq); return 0; diff --git a/drivers/net/lance.c b/drivers/net/lance.c index 7b17212d687e..977ed3401bb3 100644 --- a/drivers/net/lance.c +++ b/drivers/net/lance.c @@ -466,6 +466,7 @@ static int __init lance_probe1(struct net_device *dev, int ioaddr, int irq, int unsigned long flags; int err = -ENOMEM; void __iomem *bios; + DECLARE_MAC_BUF(mac); /* First we look for special cases. Check for HP's on-board ethernet by looking for 'HP' in the BIOS. @@ -522,12 +523,13 @@ static int __init lance_probe1(struct net_device *dev, int ioaddr, int irq, int /* We can't allocate dev->priv from alloc_etherdev() because it must a ISA DMA-able region. */ chipname = chip_table[lance_version].name; - printk("%s: %s at %#3x,", dev->name, chipname, ioaddr); + printk("%s: %s at %#3x, ", dev->name, chipname, ioaddr); /* There is a 16 byte station address PROM at the base address. The first six bytes are the station address. */ for (i = 0; i < 6; i++) - printk(" %2.2x", dev->dev_addr[i] = inb(ioaddr + i)); + dev->dev_addr[i] = inb(ioaddr + i); + printk("%s", print_mac(mac, dev->dev_addr)); dev->base_addr = ioaddr; /* Make certain the data structures used by the LANCE are aligned and DMAble. */ diff --git a/drivers/net/lguest_net.c b/drivers/net/lguest_net.c index 7f34c92bcd86..abce2ee8430a 100644 --- a/drivers/net/lguest_net.c +++ b/drivers/net/lguest_net.c @@ -235,9 +235,9 @@ static int lguestnet_start_xmit(struct sk_buff *skb, struct net_device *dev) struct lguestnet_info *info = netdev_priv(dev); /* Extract the destination ethernet address from the packet. */ const unsigned char *dest = ((struct ethhdr *)skb->data)->h_dest; + DECLARE_MAC_BUF(mac); - pr_debug("%s: xmit %02x:%02x:%02x:%02x:%02x:%02x\n", - dev->name, dest[0],dest[1],dest[2],dest[3],dest[4],dest[5]); + pr_debug("%s: xmit %s\n", dev->name, print_mac(mac, dest)); /* If it's a multicast packet, we broadcast to everyone. That's not * very efficient, but there are very few applications which actually diff --git a/drivers/net/lib82596.c b/drivers/net/lib82596.c index afa4638052a2..ffaa14f2cd01 100644 --- a/drivers/net/lib82596.c +++ b/drivers/net/lib82596.c @@ -1034,15 +1034,12 @@ static int i596_start_xmit(struct sk_buff *skb, struct net_device *dev) static void print_eth(unsigned char *add, char *str) { - int i; + DECLARE_MAC_BUF(mac); + DECLARE_MAC_BUF(mac2); - printk(KERN_DEBUG "i596 0x%p, ", add); - for (i = 0; i < 6; i++) - printk(" %02X", add[i + 6]); - printk(" -->"); - for (i = 0; i < 6; i++) - printk(" %02X", add[i]); - printk(" %02X%02X, %s\n", add[12], add[13], str); + printk(KERN_DEBUG "i596 0x%p, %s --> %s %02X%02X, %s\n", + add, print_mac(mac, add + 6), print_mac(mac2, add), + add[12], add[13], str); } static int __devinit i82596_probe(struct net_device *dev) @@ -1352,6 +1349,7 @@ static void set_multicast_list(struct net_device *dev) struct i596_private *lp = netdev_priv(dev); struct i596_dma *dma = lp->dma; int config = 0, cnt; + DECLARE_MAC_BUF(mac); DEB(DEB_MULTI, printk(KERN_DEBUG @@ -1415,8 +1413,8 @@ static void set_multicast_list(struct net_device *dev) if (i596_debug > 1) DEB(DEB_MULTI, printk(KERN_DEBUG - "%s: Adding address %02x:%02x:%02x:%02x:%02x:%02x\n", - dev->name, cp[0], cp[1], cp[2], cp[3], cp[4], cp[5])); + "%s: Adding address %s\n", + dev->name, print_mac(mac, cp))); } DMA_WBACK_INV(dev, &dma->mc_cmd, sizeof(struct mc_cmd)); i596_add_cmd(dev, &cmd->cmd); diff --git a/drivers/net/lne390.c b/drivers/net/lne390.c index 2dd396983213..b36989097883 100644 --- a/drivers/net/lne390.c +++ b/drivers/net/lne390.c @@ -169,6 +169,7 @@ static int __init lne390_probe1(struct net_device *dev, int ioaddr) { int i, revision, ret; unsigned long eisa_id; + DECLARE_MAC_BUF(mac); if (inb_p(ioaddr + LNE390_ID_PORT) == 0xff) return -ENODEV; @@ -200,10 +201,12 @@ static int __init lne390_probe1(struct net_device *dev, int ioaddr) } #endif - printk("lne390.c: LNE390%X in EISA slot %d, address", 0xa+revision, ioaddr/0x1000); for(i = 0; i < ETHER_ADDR_LEN; i++) - printk(" %02x", (dev->dev_addr[i] = inb(ioaddr + LNE390_SA_PROM + i))); - printk(".\nlne390.c: "); + dev->dev_addr[i] = inb(ioaddr + LNE390_SA_PROM + i); + printk("lne390.c: LNE390%X in EISA slot %d, address %s.\n", + 0xa+revision, ioaddr/0x1000, print_mac(mac, dev->dev_addr)); + + printk("lne390.c: "); /* Snarf the interrupt now. CFG file has them all listed as `edge' with share=NO */ if (dev->irq == 0) { diff --git a/drivers/net/mac89x0.c b/drivers/net/mac89x0.c index f6f3fdfe41db..30854f094965 100644 --- a/drivers/net/mac89x0.c +++ b/drivers/net/mac89x0.c @@ -181,6 +181,7 @@ struct net_device * __init mac89x0_probe(int unit) unsigned long ioaddr; unsigned short sig; int err = -ENODEV; + DECLARE_MAC_BUF(mac); dev = alloc_etherdev(sizeof(struct net_local)); if (!dev) @@ -272,13 +273,11 @@ struct net_device * __init mac89x0_probe(int unit) } dev->irq = SLOT2IRQ(slot); - printk(" IRQ %d ADDR ", dev->irq); - /* print the ethernet address. */ - for (i = 0; i < ETH_ALEN; i++) - printk("%2.2x%s", dev->dev_addr[i], - ((i < ETH_ALEN-1) ? ":" : "")); - printk("\n"); + /* print the IRQ and ethernet address. */ + + printk(" IRQ %d ADDR %s\n", + dev->irq, print_mac(mac, dev->dev_addr)); dev->open = net_open; dev->stop = net_close; diff --git a/drivers/net/macb.c b/drivers/net/macb.c index c6707580c305..047ea7be4850 100644 --- a/drivers/net/macb.c +++ b/drivers/net/macb.c @@ -1071,6 +1071,7 @@ static int __devinit macb_probe(struct platform_device *pdev) unsigned long pclk_hz; u32 config; int err = -ENXIO; + DECLARE_MAC_BUF(mac); regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!regs) { @@ -1190,10 +1191,9 @@ static int __devinit macb_probe(struct platform_device *pdev) platform_set_drvdata(pdev, dev); printk(KERN_INFO "%s: Atmel MACB at 0x%08lx irq %d " - "(%02x:%02x:%02x:%02x:%02x:%02x)\n", + "(%s)\n", dev->name, dev->base_addr, dev->irq, - dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2], - dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]); + print_mac(mac, dev->dev_addr)); phydev = bp->phy_dev; printk(KERN_INFO "%s: attached PHY driver [%s] " diff --git a/drivers/net/mace.c b/drivers/net/mace.c index ee132b1e09b0..95ebe72f320f 100644 --- a/drivers/net/mace.c +++ b/drivers/net/mace.c @@ -101,6 +101,7 @@ static int __devinit mace_probe(struct macio_dev *mdev, const struct of_device_i struct mace_data *mp; const unsigned char *addr; int j, rev, rc = -EBUSY; + DECLARE_MAC_BUF(mac); if (macio_resource_count(mdev) != 3 || macio_irq_count(mdev) != 3) { printk(KERN_ERR "can't use MACE %s: need 3 addrs and 3 irqs\n", @@ -240,11 +241,9 @@ static int __devinit mace_probe(struct macio_dev *mdev, const struct of_device_i goto err_free_rx_irq; } - printk(KERN_INFO "%s: MACE at", dev->name); - for (j = 0; j < 6; ++j) { - printk("%c%.2x", (j? ':': ' '), dev->dev_addr[j]); - } - printk(", chip revision %d.%d\n", mp->chipid >> 8, mp->chipid & 0xff); + printk(KERN_INFO "%s: MACE at %s, chip revision %d.%d\n", + dev->name, print_mac(mac, dev->dev_addr), + mp->chipid >> 8, mp->chipid & 0xff); return 0; diff --git a/drivers/net/macmace.c b/drivers/net/macmace.c index 57f7c1a2c1d7..6589239b79ee 100644 --- a/drivers/net/macmace.c +++ b/drivers/net/macmace.c @@ -194,6 +194,7 @@ static int __devinit mace_probe(struct platform_device *pdev) unsigned char checksum = 0; static int found = 0; int err; + DECLARE_MAC_BUF(mac); if (found || macintosh_config->ether_type != MAC_ETHER_MACE) return -ENODEV; @@ -248,9 +249,8 @@ static int __devinit mace_probe(struct platform_device *pdev) dev->set_multicast_list = mace_set_multicast; dev->set_mac_address = mace_set_address; - printk(KERN_INFO "%s: 68K MACE, hardware address %.2X", dev->name, dev->dev_addr[0]); - for (j = 1 ; j < 6 ; j++) printk(":%.2X", dev->dev_addr[j]); - printk("\n"); + printk(KERN_INFO "%s: 68K MACE, hardware address %s\n", + dev->name, print_mac(mac, dev->dev_addr)); err = register_netdev(dev); if (!err) diff --git a/drivers/net/macsonic.c b/drivers/net/macsonic.c index a55a8399344c..b267161418ea 100644 --- a/drivers/net/macsonic.c +++ b/drivers/net/macsonic.c @@ -223,6 +223,7 @@ int __init mac_onboard_sonic_ethernet_addr(struct net_device* dev) struct sonic_local *lp = netdev_priv(dev); const int prom_addr = ONBOARD_SONIC_PROM_BASE; int i; + DECLARE_MAC_BUF(mac); /* On NuBus boards we can sometimes look in the ROM resources. No such luck for comm-slot/onboard. */ @@ -266,13 +267,8 @@ int __init mac_onboard_sonic_ethernet_addr(struct net_device* dev) dev->dev_addr[1] = val >> 8; dev->dev_addr[0] = val & 0xff; - printk(KERN_INFO "HW Address from CAM 15: "); - for (i = 0; i < 6; i++) { - printk("%2.2x", dev->dev_addr[i]); - if (i < 5) - printk(":"); - } - printk("\n"); + printk(KERN_INFO "HW Address from CAM 15: %s\n", + print_mac(mac, dev->dev_addr)); } else return 0; if (memcmp(dev->dev_addr, "\x08\x00\x07", 3) && @@ -567,7 +563,7 @@ static int __init mac_sonic_probe(struct platform_device *pdev) struct net_device *dev; struct sonic_local *lp; int err; - int i; + DECLARE_MAC_BUF(mac); dev = alloc_etherdev(sizeof(struct sonic_local)); if (!dev) @@ -591,13 +587,8 @@ found: if (err) goto out; - printk("%s: MAC ", dev->name); - for (i = 0; i < 6; i++) { - printk("%2.2x", dev->dev_addr[i]); - if (i < 5) - printk(":"); - } - printk(" IRQ %d\n", dev->irq); + printk("%s: MAC %s IRQ %d\n", + dev->name, print_mac(mac, dev->dev_addr), dev->irq); return 0; diff --git a/drivers/net/meth.c b/drivers/net/meth.c index fe5b6c372072..e25dbab67363 100644 --- a/drivers/net/meth.c +++ b/drivers/net/meth.c @@ -95,11 +95,11 @@ char o2meth_eaddr[8]={0,0,0,0,0,0,0,0}; static inline void load_eaddr(struct net_device *dev) { int i; - DPRINTK("Loading MAC Address: %02x:%02x:%02x:%02x:%02x:%02x\n", - (int)o2meth_eaddr[0]&0xFF,(int)o2meth_eaddr[1]&0xFF,(int)o2meth_eaddr[2]&0xFF, - (int)o2meth_eaddr[3]&0xFF,(int)o2meth_eaddr[4]&0xFF,(int)o2meth_eaddr[5]&0xFF); + DECLARE_MAC_BUF(mac); + for (i = 0; i < 6; i++) dev->dev_addr[i] = o2meth_eaddr[i]; + DPRINTK("Loading MAC Address: %s\n", print_mac(mac, dev->dev_addr)); mace->eth.mac_addr = (*(unsigned long*)o2meth_eaddr) >> 16; } diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c index 34df02cfdbe7..e379165d8375 100644 --- a/drivers/net/mv643xx_eth.c +++ b/drivers/net/mv643xx_eth.c @@ -784,6 +784,7 @@ static int mv643xx_eth_open(struct net_device *dev) unsigned int port_num = mp->port_num; unsigned int size; int err; + DECLARE_MAC_BUF(mac); /* Clear any pending ethernet port interrupts */ mv_write(MV643XX_ETH_INTERRUPT_CAUSE_REG(port_num), 0); @@ -1413,8 +1414,8 @@ static int mv643xx_eth_probe(struct platform_device *pdev) p = dev->dev_addr; printk(KERN_NOTICE - "%s: port %d with MAC address %02x:%02x:%02x:%02x:%02x:%02x\n", - dev->name, port_num, p[0], p[1], p[2], p[3], p[4], p[5]); + "%s: port %d with MAC address %s\n", + dev->name, port_num, print_mac(mac, p)); if (dev->features & NETIF_F_SG) printk(KERN_NOTICE "%s: Scatter Gather Enabled\n", dev->name); diff --git a/drivers/net/mvme147.c b/drivers/net/mvme147.c index 837ad0f2b05d..86c9c06433cb 100644 --- a/drivers/net/mvme147.c +++ b/drivers/net/mvme147.c @@ -67,6 +67,7 @@ struct net_device * __init mvme147lance_probe(int unit) u_long *addr; u_long address; int err; + DECLARE_MAC_BUF(mac); if (!MACH_IS_MVME147 || called) return ERR_PTR(-ENODEV); @@ -101,12 +102,10 @@ struct net_device * __init mvme147lance_probe(int unit) address=address>>8; dev->dev_addr[3]=address&0xff; - printk("%s: MVME147 at 0x%08lx, irq %d, Hardware Address %02x:%02x:%02x:%02x:%02x:%02x\n", - dev->name, dev->base_addr, MVME147_LANCE_IRQ, - dev->dev_addr[0], - dev->dev_addr[1], dev->dev_addr[2], - dev->dev_addr[3], dev->dev_addr[4], - dev->dev_addr[5]); + printk("%s: MVME147 at 0x%08lx, irq %d, " + "Hardware Address %s\n", + dev->name, dev->base_addr, MVME147_LANCE_IRQ, + print_mac(mac, dev->dev_addr)); lp = (struct m147lance_private *)dev->priv; lp->ram = __get_dma_pages(GFP_ATOMIC, 3); /* 16K */ diff --git a/drivers/net/myri10ge/myri10ge.c b/drivers/net/myri10ge/myri10ge.c index 2f8864e70ca9..38b03f538e95 100644 --- a/drivers/net/myri10ge/myri10ge.c +++ b/drivers/net/myri10ge/myri10ge.c @@ -2395,6 +2395,7 @@ static void myri10ge_set_multicast_list(struct net_device *dev) struct dev_mc_list *mc_list; __be32 data[2] = { 0, 0 }; int err; + DECLARE_MAC_BUF(mac); mgp = netdev_priv(dev); /* can be called from atomic contexts, @@ -2442,14 +2443,8 @@ static void myri10ge_set_multicast_list(struct net_device *dev) printk(KERN_ERR "myri10ge: %s: Failed " "MXGEFW_JOIN_MULTICAST_GROUP, error status:" "%d\t", dev->name, err); - printk(KERN_ERR "MAC %02x:%02x:%02x:%02x:%02x:%02x\n", - ((unsigned char *)&mc_list->dmi_addr)[0], - ((unsigned char *)&mc_list->dmi_addr)[1], - ((unsigned char *)&mc_list->dmi_addr)[2], - ((unsigned char *)&mc_list->dmi_addr)[3], - ((unsigned char *)&mc_list->dmi_addr)[4], - ((unsigned char *)&mc_list->dmi_addr)[5] - ); + printk(KERN_ERR "MAC %s\n", + print_mac(mac, mc_list->dmi_addr)); goto abort; } } diff --git a/drivers/net/myri_sbus.c b/drivers/net/myri_sbus.c index 35c4c598c8d2..d68ee51c095f 100644 --- a/drivers/net/myri_sbus.c +++ b/drivers/net/myri_sbus.c @@ -311,12 +311,12 @@ static void myri_is_not_so_happy(struct myri_eth *mp) #ifdef DEBUG_HEADER static void dump_ehdr(struct ethhdr *ehdr) { - printk("ehdr[h_dst(%02x:%02x:%02x:%02x:%02x:%02x)" - "h_source(%02x:%02x:%02x:%02x:%02x:%02x)h_proto(%04x)]\n", - ehdr->h_dest[0], ehdr->h_dest[1], ehdr->h_dest[2], - ehdr->h_dest[3], ehdr->h_dest[4], ehdr->h_dest[4], - ehdr->h_source[0], ehdr->h_source[1], ehdr->h_source[2], - ehdr->h_source[3], ehdr->h_source[4], ehdr->h_source[4], + DECLARE_MAC_BUF(mac); + DECLARE_MAC_BUF(mac2); + printk("ehdr[h_dst(%s)" + "h_source(%s)" + "h_proto(%04x)]\n", + print_mac(mac, ehdr->h_dest), print_mac(mac2, ehdr->h_source), ehdr->h_proto); } @@ -325,13 +325,7 @@ static void dump_ehdr_and_myripad(unsigned char *stuff) struct ethhdr *ehdr = (struct ethhdr *) (stuff + 2); printk("pad[%02x:%02x]", stuff[0], stuff[1]); - printk("ehdr[h_dst(%02x:%02x:%02x:%02x:%02x:%02x)" - "h_source(%02x:%02x:%02x:%02x:%02x:%02x)h_proto(%04x)]\n", - ehdr->h_dest[0], ehdr->h_dest[1], ehdr->h_dest[2], - ehdr->h_dest[3], ehdr->h_dest[4], ehdr->h_dest[4], - ehdr->h_source[0], ehdr->h_source[1], ehdr->h_source[2], - ehdr->h_source[3], ehdr->h_source[4], ehdr->h_source[4], - ehdr->h_proto); + dump_ehdr(ehdr); } #endif @@ -895,6 +889,7 @@ static int __devinit myri_ether_init(struct sbus_dev *sdev) struct myri_eth *mp; unsigned char prop_buf[32]; int i; + DECLARE_MAC_BUF(mac); DET(("myri_ether_init(%p,%d):\n", sdev, num)); dev = alloc_etherdev(sizeof(struct myri_eth)); @@ -1089,12 +1084,8 @@ static int __devinit myri_ether_init(struct sbus_dev *sdev) num++; - printk("%s: MyriCOM MyriNET Ethernet ", dev->name); - - for (i = 0; i < 6; i++) - printk("%2.2x%c", dev->dev_addr[i], - i == 5 ? ' ' : ':'); - printk("\n"); + printk("%s: MyriCOM MyriNET Ethernet %s\n", + dev->name, print_mac(mac, dev->dev_addr)); return 0; diff --git a/drivers/net/natsemi.c b/drivers/net/natsemi.c index 5ee4e8795d23..ea38da6d31ff 100644 --- a/drivers/net/natsemi.c +++ b/drivers/net/natsemi.c @@ -805,6 +805,7 @@ static int __devinit natsemi_probe1 (struct pci_dev *pdev, const int pcibar = 1; /* PCI base address register */ int prev_eedata; u32 tmp; + DECLARE_MAC_BUF(mac); /* when built into the kernel, we only print version if device is found */ #ifndef MODULE @@ -958,12 +959,10 @@ static int __devinit natsemi_probe1 (struct pci_dev *pdev, goto err_create_file; if (netif_msg_drv(np)) { - printk(KERN_INFO "natsemi %s: %s at %#08lx (%s), ", - dev->name, natsemi_pci_info[chip_idx].name, iostart, - pci_name(np->pci_dev)); - for (i = 0; i < ETH_ALEN-1; i++) - printk("%02x:", dev->dev_addr[i]); - printk("%02x, IRQ %d", dev->dev_addr[i], irq); + printk(KERN_INFO "natsemi %s: %s at %#08lx " + "(%s), %s, IRQ %d", + dev->name, natsemi_pci_info[chip_idx].name, iostart, + pci_name(np->pci_dev), print_mac(mac, dev->dev_addr), irq); if (dev->if_port == PORT_TP) printk(", port TP.\n"); else if (np->ignore_phy) diff --git a/drivers/net/ne-h8300.c b/drivers/net/ne-h8300.c index 2b85d1b53344..368f2560856d 100644 --- a/drivers/net/ne-h8300.c +++ b/drivers/net/ne-h8300.c @@ -204,6 +204,7 @@ static int __init ne_probe1(struct net_device *dev, int ioaddr) static unsigned version_printed; struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev); unsigned char bus_width; + DECLARE_MAC_BUF(mac); if (!request_region(ioaddr, NE_IO_EXTENT, DRV_NAME)) return -EBUSY; @@ -296,12 +297,11 @@ static int __init ne_probe1(struct net_device *dev, int ioaddr) dev->base_addr = ioaddr; - for(i = 0; i < ETHER_ADDR_LEN; i++) { - printk(" %2.2x", SA_prom[i]); + for(i = 0; i < ETHER_ADDR_LEN; i++) dev->dev_addr[i] = SA_prom[i]; - } + printk(" %s\n", print_mac(mac, dev->dev_addr)); - printk("\n%s: %s found at %#x, using IRQ %d.\n", + printk("%s: %s found at %#x, using IRQ %d.\n", dev->name, name, ioaddr, dev->irq); ei_status.name = name; diff --git a/drivers/net/ne.c b/drivers/net/ne.c index 27d87985bb63..874d291cbaed 100644 --- a/drivers/net/ne.c +++ b/drivers/net/ne.c @@ -291,6 +291,7 @@ static int __init ne_probe1(struct net_device *dev, unsigned long ioaddr) int neX000, ctron, copam, bad_card; int reg0, ret; static unsigned version_printed; + DECLARE_MAC_BUF(mac); if (!request_region(ioaddr, NE_IO_EXTENT, DRV_NAME)) return -EBUSY; @@ -503,16 +504,14 @@ static int __init ne_probe1(struct net_device *dev, unsigned long ioaddr) for (i = 0 ; i < ETHER_ADDR_LEN ; i++) { dev->dev_addr[i] = SA_prom[i] = inb_p(ioaddr + EN1_PHYS_SHIFT(i)); - printk(" %2.2x", SA_prom[i]); } #else for(i = 0; i < ETHER_ADDR_LEN; i++) { - printk(" %2.2x", SA_prom[i]); dev->dev_addr[i] = SA_prom[i]; } #endif - printk("\n"); + printk("%s\n", print_mac(mac, dev->dev_addr)); ei_status.name = name; ei_status.tx_start_page = start_page; diff --git a/drivers/net/ne2.c b/drivers/net/ne2.c index f73073b1218a..f4cd8c7e81ba 100644 --- a/drivers/net/ne2.c +++ b/drivers/net/ne2.c @@ -302,6 +302,7 @@ out: static int ne2_procinfo(char *buf, int slot, struct net_device *dev) { int len=0; + DECLARE_MAC_BUF(mac); len += sprintf(buf+len, "The NE/2 Ethernet Adapter\n" ); len += sprintf(buf+len, "Driver written by Wim Dumon "); @@ -312,12 +313,7 @@ static int ne2_procinfo(char *buf, int slot, struct net_device *dev) len += sprintf(buf+len, "Based on the original NE2000 drivers\n" ); len += sprintf(buf+len, "Base IO: %#x\n", (unsigned int)dev->base_addr); len += sprintf(buf+len, "IRQ : %d\n", dev->irq); - -#define HW_ADDR(i) dev->dev_addr[i] - len += sprintf(buf+len, "HW addr : %x:%x:%x:%x:%x:%x\n", - HW_ADDR(0), HW_ADDR(1), HW_ADDR(2), - HW_ADDR(3), HW_ADDR(4), HW_ADDR(5) ); -#undef HW_ADDR + len += sprintf(buf+len, "HW addr : %s\n", print_mac(mac, dev->dev_addr)); return len; } @@ -330,6 +326,7 @@ static int __init ne2_probe1(struct net_device *dev, int slot) const char *name = "NE/2"; int start_page, stop_page; static unsigned version_printed; + DECLARE_MAC_BUF(mac); if (ei_debug && version_printed++ == 0) printk(version); @@ -469,12 +466,12 @@ static int __init ne2_probe1(struct net_device *dev, int slot) dev->base_addr = base_addr; - for(i = 0; i < ETHER_ADDR_LEN; i++) { - printk(" %2.2x", SA_prom[i]); + for(i = 0; i < ETHER_ADDR_LEN; i++) dev->dev_addr[i] = SA_prom[i]; - } - printk("\n%s: %s found at %#x, using IRQ %d.\n", + printk(" %s\n", print_mac(mac, dev->dev_addr)); + + printk("%s: %s found at %#x, using IRQ %d.\n", dev->name, name, base_addr, dev->irq); mca_set_adapter_procfn(slot, (MCA_ProcFn) ne2_procinfo, dev); diff --git a/drivers/net/ne2k-pci.c b/drivers/net/ne2k-pci.c index a5879672903e..b569c90da4ba 100644 --- a/drivers/net/ne2k-pci.c +++ b/drivers/net/ne2k-pci.c @@ -212,6 +212,7 @@ static int __devinit ne2k_pci_init_one (struct pci_dev *pdev, static unsigned int fnd_cnt; long ioaddr; int flags = pci_clone_list[chip_idx].flags; + DECLARE_MAC_BUF(mac); /* when built into the kernel, we only print version if device is found */ #ifndef MODULE @@ -365,12 +366,12 @@ static int __devinit ne2k_pci_init_one (struct pci_dev *pdev, if (i) goto err_out_free_netdev; - printk("%s: %s found at %#lx, IRQ %d, ", - dev->name, pci_clone_list[chip_idx].name, ioaddr, dev->irq); - for(i = 0; i < 6; i++) { - printk("%2.2X%s", SA_prom[i], i == 5 ? ".\n": ":"); + for(i = 0; i < 6; i++) dev->dev_addr[i] = SA_prom[i]; - } + printk("%s: %s found at %#lx, IRQ %d, %s.\n", + dev->name, pci_clone_list[chip_idx].name, ioaddr, dev->irq, + print_mac(mac, dev->dev_addr)); + memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len); return 0; diff --git a/drivers/net/ne3210.c b/drivers/net/ne3210.c index b1bf8331e872..425043a88db9 100644 --- a/drivers/net/ne3210.c +++ b/drivers/net/ne3210.c @@ -99,6 +99,7 @@ static int __init ne3210_eisa_probe (struct device *device) int i, retval, port_index; struct eisa_device *edev = to_eisa_device (device); struct net_device *dev; + DECLARE_MAC_BUF(mac); /* Allocate dev->priv and fill in 8390 specific dev fields. */ if (!(dev = alloc_ei_netdev ())) { @@ -127,17 +128,15 @@ static int __init ne3210_eisa_probe (struct device *device) inb(ioaddr + NE3210_CFG1), inb(ioaddr + NE3210_CFG2)); #endif - port_index = inb(ioaddr + NE3210_CFG2) >> 6; - printk("ne3210.c: NE3210 in EISA slot %d, media: %s, addr:", - edev->slot, ifmap[port_index]); for(i = 0; i < ETHER_ADDR_LEN; i++) - printk(" %02x", (dev->dev_addr[i] = inb(ioaddr + NE3210_SA_PROM + i))); - + dev->dev_addr[i] = inb(ioaddr + NE3210_SA_PROM + i); + printk("ne3210.c: NE3210 in EISA slot %d, media: %s, addr: %s.\n", + edev->slot, ifmap[port_index], print_mac(mac, dev->dev_addr)); /* Snarf the interrupt now. CFG file has them all listed as `edge' with share=NO */ dev->irq = irq_map[(inb(ioaddr + NE3210_CFG2) >> 3) & 0x07]; - printk(".\nne3210.c: using IRQ %d, ", dev->irq); + printk("ne3210.c: using IRQ %d, ", dev->irq); retval = request_irq(dev->irq, ei_interrupt, 0, DRV_NAME, dev); if (retval) { diff --git a/drivers/net/netconsole.c b/drivers/net/netconsole.c index 69ef1eb03bea..5ffbb8891647 100644 --- a/drivers/net/netconsole.c +++ b/drivers/net/netconsole.c @@ -306,18 +306,16 @@ static ssize_t show_remote_ip(struct netconsole_target *nt, char *buf) static ssize_t show_local_mac(struct netconsole_target *nt, char *buf) { - return snprintf(buf, PAGE_SIZE, "%02x:%02x:%02x:%02x:%02x:%02x\n", - nt->np.local_mac[0], nt->np.local_mac[1], - nt->np.local_mac[2], nt->np.local_mac[3], - nt->np.local_mac[4], nt->np.local_mac[5]); + DECLARE_MAC_BUF(mac); + return snprintf(buf, PAGE_SIZE, "%s\n", + print_mac(mac, nt->np.local_mac)); } static ssize_t show_remote_mac(struct netconsole_target *nt, char *buf) { - return snprintf(buf, PAGE_SIZE, "%02x:%02x:%02x:%02x:%02x:%02x\n", - nt->np.remote_mac[0], nt->np.remote_mac[1], - nt->np.remote_mac[2], nt->np.remote_mac[3], - nt->np.remote_mac[4], nt->np.remote_mac[5]); + DECLARE_MAC_BUF(mac); + return snprintf(buf, PAGE_SIZE, "%s\n", + print_mac(mac, nt->np.remote_mac)); } /* diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c index 1b165a8c74f3..b9cde65e7f31 100644 --- a/drivers/net/netxen/netxen_nic_main.c +++ b/drivers/net/netxen/netxen_nic_main.c @@ -285,6 +285,7 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) int valid_mac = 0; u32 val; int pci_func_id = PCI_FUNC(pdev->devfn); + DECLARE_MAC_BUF(mac); printk(KERN_INFO "%s \n", netxen_nic_driver_string); @@ -573,15 +574,9 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) memcpy(netdev->perm_addr, netdev->dev_addr, netdev->addr_len); if (!is_valid_ether_addr(netdev->perm_addr)) { - printk(KERN_ERR "%s: Bad MAC address " - "%02x:%02x:%02x:%02x:%02x:%02x.\n", - netxen_nic_driver_name, - netdev->dev_addr[0], - netdev->dev_addr[1], - netdev->dev_addr[2], - netdev->dev_addr[3], - netdev->dev_addr[4], - netdev->dev_addr[5]); + printk(KERN_ERR "%s: Bad MAC address %s.\n", + netxen_nic_driver_name, + print_mac(mac, netdev->dev_addr)); } else { if (adapter->macaddr_set) adapter->macaddr_set(adapter, diff --git a/drivers/net/netxen/netxen_nic_niu.c b/drivers/net/netxen/netxen_nic_niu.c index 05e0577a0e10..5b9e1b300fab 100644 --- a/drivers/net/netxen/netxen_nic_niu.c +++ b/drivers/net/netxen/netxen_nic_niu.c @@ -603,6 +603,7 @@ int netxen_niu_macaddr_set(struct netxen_adapter *adapter, int phy = physical_port[adapter->portnum]; unsigned char mac_addr[6]; int i; + DECLARE_MAC_BUF(mac); for (i = 0; i < 10; i++) { temp[0] = temp[1] = 0; @@ -627,15 +628,10 @@ int netxen_niu_macaddr_set(struct netxen_adapter *adapter, if (i == 10) { printk(KERN_ERR "%s: cannot set Mac addr for %s\n", netxen_nic_driver_name, adapter->netdev->name); - printk(KERN_ERR "MAC address set: " - "%02x:%02x:%02x:%02x:%02x:%02x.\n", - addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]); - - printk(KERN_ERR "MAC address get: " - "%02x:%02x:%02x:%02x:%02x:%02x.\n", - mac_addr[0], - mac_addr[1], - mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]); + printk(KERN_ERR "MAC address set: %s.\n", + print_mac(mac, addr)); + printk(KERN_ERR "MAC address get: %s.\n", + print_mac(mac, mac_addr)); } return 0; } diff --git a/drivers/net/ni5010.c b/drivers/net/ni5010.c index 1dc74a78afa6..14a768fbce2e 100644 --- a/drivers/net/ni5010.c +++ b/drivers/net/ni5010.c @@ -203,6 +203,7 @@ static int __init ni5010_probe1(struct net_device *dev, int ioaddr) unsigned int data = 0; int boguscount = 40; int err = -ENODEV; + DECLARE_MAC_BUF(mac); dev->base_addr = ioaddr; dev->irq = irq; @@ -268,8 +269,9 @@ static int __init ni5010_probe1(struct net_device *dev, int ioaddr) for (i=0; i<6; i++) { outw(i, IE_GP); - printk("%2.2x ", dev->dev_addr[i] = inb(IE_SAPROM)); + dev->dev_addr[i] = inb(IE_SAPROM); } + printk("%s ", print_mac(mac, dev->dev_addr)); PRINTK2((KERN_DEBUG "%s: I/O #4 passed!\n", dev->name)); diff --git a/drivers/net/ns83820.c b/drivers/net/ns83820.c index de495b697294..ea71f6d82661 100644 --- a/drivers/net/ns83820.c +++ b/drivers/net/ns83820.c @@ -1962,6 +1962,7 @@ static int __devinit ns83820_init_one(struct pci_dev *pci_dev, const struct pci_ long addr; int err; int using_dac = 0; + DECLARE_MAC_BUF(mac); /* See if we can set the dma mask early on; failure is fatal. */ if (sizeof(dma_addr_t) == 8 && @@ -2226,13 +2227,11 @@ static int __devinit ns83820_init_one(struct pci_dev *pci_dev, const struct pci_ ndev->features |= NETIF_F_HIGHDMA; } - printk(KERN_INFO "%s: ns83820 v" VERSION ": DP83820 v%u.%u: %02x:%02x:%02x:%02x:%02x:%02x io=0x%08lx irq=%d f=%s\n", + printk(KERN_INFO "%s: ns83820 v" VERSION ": DP83820 v%u.%u: %s io=0x%08lx irq=%d f=%s\n", ndev->name, (unsigned)readl(dev->base + SRR) >> 8, (unsigned)readl(dev->base + SRR) & 0xff, - ndev->dev_addr[0], ndev->dev_addr[1], - ndev->dev_addr[2], ndev->dev_addr[3], - ndev->dev_addr[4], ndev->dev_addr[5], + print_mac(mac, ndev->dev_addr), addr, pci_dev->irq, (ndev->features & NETIF_F_HIGHDMA) ? "h,sg" : "sg" ); diff --git a/drivers/net/pasemi_mac.c b/drivers/net/pasemi_mac.c index f310d94443a0..4d87cd65626f 100644 --- a/drivers/net/pasemi_mac.c +++ b/drivers/net/pasemi_mac.c @@ -1155,6 +1155,7 @@ pasemi_mac_probe(struct pci_dev *pdev, const struct pci_device_id *ent) struct net_device *dev; struct pasemi_mac *mac; int err; + DECLARE_MAC_BUF(mac_buf); err = pci_enable_device(pdev); if (err) @@ -1237,11 +1238,10 @@ pasemi_mac_probe(struct pci_dev *pdev, const struct pci_device_id *ent) goto out; } else printk(KERN_INFO "%s: PA Semi %s: intf %d, txch %d, rxch %d, " - "hw addr %02x:%02x:%02x:%02x:%02x:%02x\n", + "hw addr %s\n", dev->name, mac->type == MAC_TYPE_GMAC ? "GMAC" : "XAUI", mac->dma_if, mac->dma_txch, mac->dma_rxch, - dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2], - dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]); + print_mac(mac_buf, dev->dev_addr)); return err; diff --git a/drivers/net/pci-skeleton.c b/drivers/net/pci-skeleton.c index 7dace63fb6e6..ed402e00e730 100644 --- a/drivers/net/pci-skeleton.c +++ b/drivers/net/pci-skeleton.c @@ -737,6 +737,7 @@ static int __devinit netdrv_init_one (struct pci_dev *pdev, int i, addr_len, option; void *ioaddr = NULL; static int board_idx = -1; + DECLARE_MAC_BUF(mac); /* when built into the kernel, we only print version if device is found */ #ifndef MODULE @@ -796,15 +797,11 @@ static int __devinit netdrv_init_one (struct pci_dev *pdev, tp->phys[0] = 32; - printk (KERN_INFO "%s: %s at 0x%lx, " - "%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x, " - "IRQ %d\n", + printk (KERN_INFO "%s: %s at 0x%lx, %sIRQ %d\n", dev->name, board_info[ent->driver_data].name, dev->base_addr, - dev->dev_addr[0], dev->dev_addr[1], - dev->dev_addr[2], dev->dev_addr[3], - dev->dev_addr[4], dev->dev_addr[5], + print_mac(mac, dev->dev_addr), dev->irq); printk (KERN_DEBUG "%s: Identified 8139 chip type '%s'\n", diff --git a/drivers/net/pcmcia/3c574_cs.c b/drivers/net/pcmcia/3c574_cs.c index 2b395ee21f75..73dcbb7296da 100644 --- a/drivers/net/pcmcia/3c574_cs.c +++ b/drivers/net/pcmcia/3c574_cs.c @@ -343,6 +343,7 @@ static int tc574_config(struct pcmcia_device *link) u16 *phys_addr; char *cardname; union wn3_config config; + DECLARE_MAC_BUF(mac); phys_addr = (u16 *)dev->dev_addr; @@ -458,10 +459,10 @@ static int tc574_config(struct pcmcia_device *link) strcpy(lp->node.dev_name, dev->name); - printk(KERN_INFO "%s: %s at io %#3lx, irq %d, hw_addr ", - dev->name, cardname, dev->base_addr, dev->irq); - for (i = 0; i < 6; i++) - printk("%02X%s", dev->dev_addr[i], ((i<5) ? ":" : ".\n")); + printk(KERN_INFO "%s: %s at io %#3lx, irq %d, " + "hw_addr %s.\n", + dev->name, cardname, dev->base_addr, dev->irq, + print_mac(mac, dev->dev_addr)); printk(" %dK FIFO split %s Rx:Tx, %sMII interface.\n", 8 << config.u.ram_size, ram_split[config.u.ram_split], config.u.autoselect ? "autoselect " : ""); diff --git a/drivers/net/pcmcia/3c589_cs.c b/drivers/net/pcmcia/3c589_cs.c index 2136c80c0581..32076ca6a9e1 100644 --- a/drivers/net/pcmcia/3c589_cs.c +++ b/drivers/net/pcmcia/3c589_cs.c @@ -255,6 +255,7 @@ static int tc589_config(struct pcmcia_device *link) int last_fn, last_ret, i, j, multi = 0, fifo; kio_addr_t ioaddr; char *ram_split[] = {"5:3", "3:1", "1:1", "3:5"}; + DECLARE_MAC_BUF(mac); DEBUG(0, "3c589_config(0x%p)\n", link); @@ -330,11 +331,10 @@ static int tc589_config(struct pcmcia_device *link) strcpy(lp->node.dev_name, dev->name); - printk(KERN_INFO "%s: 3Com 3c%s, io %#3lx, irq %d, hw_addr ", - dev->name, (multi ? "562" : "589"), dev->base_addr, - dev->irq); - for (i = 0; i < 6; i++) - printk("%02X%s", dev->dev_addr[i], ((i<5) ? ":" : "\n")); + printk(KERN_INFO "%s: 3Com 3c%s, io %#3lx, irq %d, " + "hw_addr %s\n", + dev->name, (multi ? "562" : "589"), dev->base_addr, dev->irq, + print_mac(mac, dev->dev_addr)); printk(KERN_INFO " %dK FIFO split %s Rx:Tx, %s xcvr\n", (fifo & 7) ? 32 : 8, ram_split[(fifo >> 16) & 3], if_names[dev->if_port]); diff --git a/drivers/net/pcmcia/axnet_cs.c b/drivers/net/pcmcia/axnet_cs.c index 28eea206766d..de59313d10f5 100644 --- a/drivers/net/pcmcia/axnet_cs.c +++ b/drivers/net/pcmcia/axnet_cs.c @@ -292,6 +292,7 @@ static int axnet_config(struct pcmcia_device *link) cisparse_t parse; int i, j, last_ret, last_fn; u_short buf[64]; + DECLARE_MAC_BUF(mac); DEBUG(0, "axnet_config(0x%p)\n", link); @@ -403,11 +404,11 @@ static int axnet_config(struct pcmcia_device *link) strcpy(info->node.dev_name, dev->name); - printk(KERN_INFO "%s: Asix AX88%d90: io %#3lx, irq %d, hw_addr ", + printk(KERN_INFO "%s: Asix AX88%d90: io %#3lx, irq %d, " + "hw_addr %s\n", dev->name, ((info->flags & IS_AX88790) ? 7 : 1), - dev->base_addr, dev->irq); - for (i = 0; i < 6; i++) - printk("%02X%s", dev->dev_addr[i], ((i<5) ? ":" : "\n")); + dev->base_addr, dev->irq, + print_mac(mac, dev->dev_addr)); if (info->phy_id != -1) { DEBUG(0, " MII transceiver at index %d, status %x.\n", info->phy_id, j); } else { diff --git a/drivers/net/pcmcia/fmvj18x_cs.c b/drivers/net/pcmcia/fmvj18x_cs.c index 7f29e95a0644..62844677c784 100644 --- a/drivers/net/pcmcia/fmvj18x_cs.c +++ b/drivers/net/pcmcia/fmvj18x_cs.c @@ -346,6 +346,7 @@ static int fmvj18x_config(struct pcmcia_device *link) cardtype_t cardtype; char *card_name = "unknown"; u_char *node_id; + DECLARE_MAC_BUF(mac); DEBUG(0, "fmvj18x_config(0x%p)\n", link); @@ -533,11 +534,10 @@ static int fmvj18x_config(struct pcmcia_device *link) strcpy(lp->node.dev_name, dev->name); /* print current configuration */ - printk(KERN_INFO "%s: %s, sram %s, port %#3lx, irq %d, hw_addr ", + printk(KERN_INFO "%s: %s, sram %s, port %#3lx, irq %d, " + "hw_addr %s\n", dev->name, card_name, sram_config == 0 ? "4K TX*2" : "8K TX*2", - dev->base_addr, dev->irq); - for (i = 0; i < 6; i++) - printk("%02X%s", dev->dev_addr[i], ((i<5) ? ":" : "\n")); + dev->base_addr, dev->irq, print_mac(mac, dev->dev_addr)); return 0; diff --git a/drivers/net/pcmcia/nmclan_cs.c b/drivers/net/pcmcia/nmclan_cs.c index 1bb2ffa294de..a355a93b908b 100644 --- a/drivers/net/pcmcia/nmclan_cs.c +++ b/drivers/net/pcmcia/nmclan_cs.c @@ -658,6 +658,7 @@ static int nmclan_config(struct pcmcia_device *link) u_char buf[64]; int i, last_ret, last_fn; kio_addr_t ioaddr; + DECLARE_MAC_BUF(mac); DEBUG(0, "nmclan_config(0x%p)\n", link); @@ -716,10 +717,10 @@ static int nmclan_config(struct pcmcia_device *link) strcpy(lp->node.dev_name, dev->name); - printk(KERN_INFO "%s: nmclan: port %#3lx, irq %d, %s port, hw_addr ", - dev->name, dev->base_addr, dev->irq, if_names[dev->if_port]); - for (i = 0; i < 6; i++) - printk("%02X%s", dev->dev_addr[i], ((i<5) ? ":" : "\n")); + printk(KERN_INFO "%s: nmclan: port %#3lx, irq %d, %s port," + " hw_addr %s\n", + dev->name, dev->base_addr, dev->irq, if_names[dev->if_port], + print_mac(mac, dev->dev_addr)); return 0; cs_failed: diff --git a/drivers/net/pcmcia/pcnet_cs.c b/drivers/net/pcmcia/pcnet_cs.c index 8ce251cd3209..6a647516c380 100644 --- a/drivers/net/pcmcia/pcnet_cs.c +++ b/drivers/net/pcmcia/pcnet_cs.c @@ -38,7 +38,7 @@ #include #include #include -#include <../drivers/net/8390.h> +#include "../8390.h" #include #include @@ -521,6 +521,7 @@ static int pcnet_config(struct pcmcia_device *link) int has_shmem = 0; u_short buf[64]; hw_info_t *hw_info; + DECLARE_MAC_BUF(mac); DEBUG(0, "pcnet_config(0x%p)\n", link); @@ -670,9 +671,7 @@ static int pcnet_config(struct pcmcia_device *link) printk (" mem %#5lx,", dev->mem_start); if (info->flags & HAS_MISC_REG) printk(" %s xcvr,", if_names[dev->if_port]); - printk(" hw_addr "); - for (i = 0; i < 6; i++) - printk("%02X%s", dev->dev_addr[i], ((i<5) ? ":" : "\n")); + printk(" hw_addr %s\n", print_mac(mac, dev->dev_addr)); return 0; cs_failed: diff --git a/drivers/net/pcmcia/smc91c92_cs.c b/drivers/net/pcmcia/smc91c92_cs.c index b25f1985d03e..58d716fd17cf 100644 --- a/drivers/net/pcmcia/smc91c92_cs.c +++ b/drivers/net/pcmcia/smc91c92_cs.c @@ -962,6 +962,7 @@ static int smc91c92_config(struct pcmcia_device *link) int i, j, rev; kio_addr_t ioaddr; u_long mir; + DECLARE_MAC_BUF(mac); DEBUG(0, "smc91c92_config(0x%p)\n", link); @@ -1074,10 +1075,9 @@ static int smc91c92_config(struct pcmcia_device *link) strcpy(smc->node.dev_name, dev->name); printk(KERN_INFO "%s: smc91c%s rev %d: io %#3lx, irq %d, " - "hw_addr ", dev->name, name, (rev & 0x0f), dev->base_addr, - dev->irq); - for (i = 0; i < 6; i++) - printk("%02X%s", dev->dev_addr[i], ((i<5) ? ":" : "\n")); + "hw_addr %s\n", + dev->name, name, (rev & 0x0f), dev->base_addr, dev->irq, + print_mac(mac, dev->dev_addr)); if (rev > 0) { if (mir & 0x3ff) diff --git a/drivers/net/pcmcia/xirc2ps_cs.c b/drivers/net/pcmcia/xirc2ps_cs.c index d5c2d2c8c852..c3b69602e275 100644 --- a/drivers/net/pcmcia/xirc2ps_cs.c +++ b/drivers/net/pcmcia/xirc2ps_cs.c @@ -731,6 +731,7 @@ xirc2ps_config(struct pcmcia_device * link) u_char buf[64]; cistpl_lan_node_id_t *node_id = (cistpl_lan_node_id_t*)parse.funce.data; cistpl_cftable_entry_t *cf = &parse.cftable_entry; + DECLARE_MAC_BUF(mac); local->dingo_ccr = NULL; @@ -1032,11 +1033,9 @@ xirc2ps_config(struct pcmcia_device * link) strcpy(local->node.dev_name, dev->name); /* give some infos about the hardware */ - printk(KERN_INFO "%s: %s: port %#3lx, irq %d, hwaddr", - dev->name, local->manf_str,(u_long)dev->base_addr, (int)dev->irq); - for (i = 0; i < 6; i++) - printk("%c%02X", i?':':' ', dev->dev_addr[i]); - printk("\n"); + printk(KERN_INFO "%s: %s: port %#3lx, irq %d, hwaddr %s\n", + dev->name, local->manf_str,(u_long)dev->base_addr, (int)dev->irq, + print_mac(mac, dev->dev_addr)); return 0; diff --git a/drivers/net/pppoe.c b/drivers/net/pppoe.c index 2f130e06b6dc..ba2eb04aac9f 100644 --- a/drivers/net/pppoe.c +++ b/drivers/net/pppoe.c @@ -955,6 +955,7 @@ static int pppoe_seq_show(struct seq_file *seq, void *v) { struct pppox_sock *po; char *dev_name; + DECLARE_MAC_BUF(mac); if (v == SEQ_START_TOKEN) { seq_puts(seq, "Id Address Device\n"); @@ -964,11 +965,8 @@ static int pppoe_seq_show(struct seq_file *seq, void *v) po = v; dev_name = po->pppoe_pa.dev; - seq_printf(seq, "%08X %02X:%02X:%02X:%02X:%02X:%02X %8s\n", - po->pppoe_pa.sid, - po->pppoe_pa.remote[0], po->pppoe_pa.remote[1], - po->pppoe_pa.remote[2], po->pppoe_pa.remote[3], - po->pppoe_pa.remote[4], po->pppoe_pa.remote[5], dev_name); + seq_printf(seq, "%08X %s %8s\n", + po->pppoe_pa.sid, print_mac(mac, po->pppoe_pa.remote), dev_name); out: return 0; } diff --git a/drivers/net/ps3_gelic_net.c b/drivers/net/ps3_gelic_net.c index f375bbbd6604..0a42bf517465 100644 --- a/drivers/net/ps3_gelic_net.c +++ b/drivers/net/ps3_gelic_net.c @@ -1348,6 +1348,7 @@ static int gelic_net_setup_netdev(struct gelic_net_card *card) unsigned int i; int status; u64 v1, v2; + DECLARE_MAC_BUF(mac); SET_NETDEV_DEV(netdev, &card->dev->core); spin_lock_init(&card->tx_dma_lock); @@ -1373,10 +1374,8 @@ static int gelic_net_setup_netdev(struct gelic_net_card *card) v1 <<= 16; memcpy(addr.sa_data, &v1, ETH_ALEN); memcpy(netdev->dev_addr, addr.sa_data, ETH_ALEN); - dev_info(ctodev(card), "MAC addr %02x:%02x:%02x:%02x:%02x:%02x\n", - netdev->dev_addr[0], netdev->dev_addr[1], - netdev->dev_addr[2], netdev->dev_addr[3], - netdev->dev_addr[4], netdev->dev_addr[5]); + dev_info(ctodev(card), "MAC addr %s\n", + print_mac(mac, netdev->dev_addr)); card->vlan_index = -1; /* no vlan */ for (i = 0; i < GELIC_NET_VLAN_MAX; i++) { diff --git a/drivers/net/qla3xxx.c b/drivers/net/qla3xxx.c index 97c6ed07dd15..ed79aa820df2 100755 --- a/drivers/net/qla3xxx.c +++ b/drivers/net/qla3xxx.c @@ -3557,6 +3557,7 @@ static void ql_display_dev_info(struct net_device *ndev) { struct ql3_adapter *qdev = (struct ql3_adapter *)netdev_priv(ndev); struct pci_dev *pdev = qdev->pdev; + DECLARE_MAC_BUF(mac); printk(KERN_INFO PFX "\n%s Adapter %d RevisionID %d found %s on PCI slot %d.\n", @@ -3582,10 +3583,8 @@ static void ql_display_dev_info(struct net_device *ndev) if (netif_msg_probe(qdev)) printk(KERN_INFO PFX - "%s: MAC address %02x:%02x:%02x:%02x:%02x:%02x\n", - ndev->name, ndev->dev_addr[0], ndev->dev_addr[1], - ndev->dev_addr[2], ndev->dev_addr[3], ndev->dev_addr[4], - ndev->dev_addr[5]); + "%s: MAC address %s\n", + ndev->name, print_mac(mac, ndev->dev_addr)); } static int ql_adapter_down(struct ql3_adapter *qdev, int do_reset) diff --git a/drivers/net/rionet.c b/drivers/net/rionet.c index d43dcf3ed5a9..e7fd08adbbac 100644 --- a/drivers/net/rionet.c +++ b/drivers/net/rionet.c @@ -432,6 +432,7 @@ static int rionet_setup_netdev(struct rio_mport *mport) struct net_device *ndev = NULL; struct rionet_private *rnet; u16 device_id; + DECLARE_MAC_BUF(mac); /* Allocate our net_device structure */ ndev = alloc_etherdev(sizeof(struct rionet_private)); @@ -472,13 +473,12 @@ static int rionet_setup_netdev(struct rio_mport *mport) if (rc != 0) goto out; - printk("%s: %s %s Version %s, MAC %02x:%02x:%02x:%02x:%02x:%02x\n", + printk("%s: %s %s Version %s, MAC %s\n", ndev->name, DRV_NAME, DRV_DESC, DRV_VERSION, - ndev->dev_addr[0], ndev->dev_addr[1], ndev->dev_addr[2], - ndev->dev_addr[3], ndev->dev_addr[4], ndev->dev_addr[5]); + print_mac(mac, ndev->dev_addr)); out: return rc; diff --git a/drivers/net/rrunner.c b/drivers/net/rrunner.c index 03facba05259..19152f54ef2b 100644 --- a/drivers/net/rrunner.c +++ b/drivers/net/rrunner.c @@ -520,7 +520,7 @@ static int __devinit rr_init(struct net_device *dev) struct rr_regs __iomem *regs; struct eeprom *hw = NULL; u32 sram_size, rev; - int i; + DECLARE_MAC_BUF(mac); rrpriv = netdev_priv(dev); regs = rrpriv->regs; @@ -558,11 +558,7 @@ static int __devinit rr_init(struct net_device *dev) *(u32 *)(dev->dev_addr+2) = htonl(rr_read_eeprom_word(rrpriv, &hw->manf.BoardULA[4])); - printk(" MAC: "); - - for (i = 0; i < 5; i++) - printk("%2.2x:", dev->dev_addr[i]); - printk("%2.2x\n", dev->dev_addr[i]); + printk(" MAC: %s\n", print_mac(mac, dev->dev_addr)); sram_size = rr_read_eeprom_word(rrpriv, (void *)8); printk(" SRAM size 0x%06x\n", sram_size); diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c index a285dd734a03..26895de3e264 100644 --- a/drivers/net/s2io.c +++ b/drivers/net/s2io.c @@ -7417,6 +7417,7 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) struct config_param *config; int mode; u8 dev_intr_type = intr_type; + DECLARE_MAC_BUF(mac); if ((ret = s2io_verify_parm(pdev, &dev_intr_type))) return ret; @@ -7720,14 +7721,8 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) sp->product_name, pdev->revision); DBG_PRINT(ERR_DBG, "%s: Driver version %s\n", dev->name, s2io_driver_version); - DBG_PRINT(ERR_DBG, "%s: MAC ADDR: " - "%02x:%02x:%02x:%02x:%02x:%02x", dev->name, - sp->def_mac_addr[0].mac_addr[0], - sp->def_mac_addr[0].mac_addr[1], - sp->def_mac_addr[0].mac_addr[2], - sp->def_mac_addr[0].mac_addr[3], - sp->def_mac_addr[0].mac_addr[4], - sp->def_mac_addr[0].mac_addr[5]); + DBG_PRINT(ERR_DBG, "%s: MAC ADDR: %s\n", + dev->name, print_mac(mac, dev->dev_addr)); DBG_PRINT(ERR_DBG, "SERIAL NUMBER: %s\n", sp->serial_num); if (sp->device_type & XFRAME_II_DEVICE) { mode = s2io_print_pci_mode(sp); diff --git a/drivers/net/sb1250-mac.c b/drivers/net/sb1250-mac.c index 76e7ee9a6cbc..6001ab47fba0 100644 --- a/drivers/net/sb1250-mac.c +++ b/drivers/net/sb1250-mac.c @@ -2407,6 +2407,7 @@ static int sbmac_init(struct net_device *dev, int idx) uint64_t ea_reg; int i; int err; + DECLARE_MAC_BUF(mac); sc = netdev_priv(dev); @@ -2487,10 +2488,8 @@ static int sbmac_init(struct net_device *dev, int idx) * was being displayed) */ printk(KERN_INFO - "%s: SiByte Ethernet at 0x%08lX, address: %02X:%02X:%02X:%02X:%02X:%02X\n", - dev->name, dev->base_addr, - eaddr[0],eaddr[1],eaddr[2],eaddr[3],eaddr[4],eaddr[5]); - + "%s: SiByte Ethernet at 0x%08lX, address: %s\n", + dev->name, dev->base_addr, print_mac(mac, eaddr)); return 0; diff --git a/drivers/net/seeq8005.c b/drivers/net/seeq8005.c index 8ef94028cba5..48c64fb20eec 100644 --- a/drivers/net/seeq8005.c +++ b/drivers/net/seeq8005.c @@ -158,6 +158,7 @@ static int __init seeq8005_probe1(struct net_device *dev, int ioaddr) int old_dmaar; int old_rear; int retval; + DECLARE_MAC_BUF(mac); if (!request_region(ioaddr, SEEQ8005_IO_EXTENT, "seeq8005")) return -ENODEV; @@ -301,7 +302,8 @@ static int __init seeq8005_probe1(struct net_device *dev, int ioaddr) /* Retrieve and print the ethernet address. */ for (i = 0; i < 6; i++) - printk(" %2.2x", dev->dev_addr[i] = SA_prom[i+6]); + dev->dev_addr[i] = SA_prom[i+6]; + printk("%s", print_mac(mac, dev->dev_addr)); if (dev->irq == 0xff) ; /* Do nothing: a user-level program will set it. */ diff --git a/drivers/net/sgiseeq.c b/drivers/net/sgiseeq.c index 5189ef066884..ff4056310356 100644 --- a/drivers/net/sgiseeq.c +++ b/drivers/net/sgiseeq.c @@ -622,6 +622,7 @@ static int __init sgiseeq_probe(struct platform_device *pdev) struct sgiseeq_private *sp; struct net_device *dev; int err, i; + DECLARE_MAC_BUF(mac); dev = alloc_etherdev(sizeof (struct sgiseeq_private)); if (!dev) { @@ -695,9 +696,8 @@ static int __init sgiseeq_probe(struct platform_device *pdev) goto err_out_free_page; } - printk(KERN_INFO "%s: %s ", dev->name, sgiseeqstr); - for (i = 0; i < 6; i++) - printk("%2.2x%c", dev->dev_addr[i], i == 5 ? '\n' : ':'); + printk(KERN_INFO "%s: %s %s\n", + dev->name, sgiseeqstr, print_mac(mac, dev->dev_addr)); return 0; diff --git a/drivers/net/sis190.c b/drivers/net/sis190.c index 808141b46585..720088396bb9 100644 --- a/drivers/net/sis190.c +++ b/drivers/net/sis190.c @@ -1759,6 +1759,7 @@ static int __devinit sis190_init_one(struct pci_dev *pdev, struct net_device *dev; void __iomem *ioaddr; int rc; + DECLARE_MAC_BUF(mac); if (!printed_version) { net_drv(&debug, KERN_INFO SIS190_DRIVER_NAME " loaded.\n"); @@ -1809,12 +1810,9 @@ static int __devinit sis190_init_one(struct pci_dev *pdev, goto err_remove_mii; net_probe(tp, KERN_INFO "%s: %s at %p (IRQ: %d), " - "%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x\n", - pci_name(pdev), sis_chip_info[ent->driver_data].name, - ioaddr, dev->irq, - dev->dev_addr[0], dev->dev_addr[1], - dev->dev_addr[2], dev->dev_addr[3], - dev->dev_addr[4], dev->dev_addr[5]); + "%s\n", + pci_name(pdev), sis_chip_info[ent->driver_data].name, + ioaddr, dev->irq, print_mac(mac, dev->dev_addr)); net_probe(tp, KERN_INFO "%s: %s mode.\n", dev->name, (tp->features & F_HAS_RGMII) ? "RGMII" : "GMII"); diff --git a/drivers/net/sis900.c b/drivers/net/sis900.c index 5da8e671324d..0857d2c88aa0 100644 --- a/drivers/net/sis900.c +++ b/drivers/net/sis900.c @@ -404,6 +404,7 @@ static int __devinit sis900_probe(struct pci_dev *pci_dev, int i, ret; const char *card_name = card_names[pci_id->driver_data]; const char *dev_name = pci_name(pci_dev); + DECLARE_MAC_BUF(mac); /* when built into the kernel, we only print version if device is found */ #ifndef MODULE @@ -533,11 +534,9 @@ static int __devinit sis900_probe(struct pci_dev *pci_dev, goto err_unmap_rx; /* print some information about our NIC */ - printk(KERN_INFO "%s: %s at %#lx, IRQ %d, ", net_dev->name, - card_name, ioaddr, net_dev->irq); - for (i = 0; i < 5; i++) - printk("%2.2x:", (u8)net_dev->dev_addr[i]); - printk("%2.2x.\n", net_dev->dev_addr[i]); + printk(KERN_INFO "%s: %s at %#lx, IRQ %d, %s\n", + net_dev->name, card_name, ioaddr, net_dev->irq, + print_mac(mac, net_dev->dev_addr)); /* Detect Wake on Lan support */ ret = (inl(net_dev->base_addr + CFGPMC) & PMESP) >> 27; diff --git a/drivers/net/skge.c b/drivers/net/skge.c index cac499f84131..ec1acfddf350 100644 --- a/drivers/net/skge.c +++ b/drivers/net/skge.c @@ -3616,12 +3616,11 @@ static struct net_device *skge_devinit(struct skge_hw *hw, int port, static void __devinit skge_show_addr(struct net_device *dev) { const struct skge_port *skge = netdev_priv(dev); + DECLARE_MAC_BUF(mac); if (netif_msg_probe(skge)) - printk(KERN_INFO PFX "%s: addr %02x:%02x:%02x:%02x:%02x:%02x\n", - dev->name, - dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2], - dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]); + printk(KERN_INFO PFX "%s: addr %s\n", + dev->name, print_mac(mac, dev->dev_addr)); } static int __devinit skge_probe(struct pci_dev *pdev, diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index b8c15f881eba..a70bcbcf8a16 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c @@ -3984,12 +3984,11 @@ static __devinit struct net_device *sky2_init_netdev(struct sky2_hw *hw, static void __devinit sky2_show_addr(struct net_device *dev) { const struct sky2_port *sky2 = netdev_priv(dev); + DECLARE_MAC_BUF(mac); if (netif_msg_probe(sky2)) - printk(KERN_INFO PFX "%s: addr %02x:%02x:%02x:%02x:%02x:%02x\n", - dev->name, - dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2], - dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]); + printk(KERN_INFO PFX "%s: addr %s\n", + dev->name, print_mac(mac, dev->dev_addr)); } /* Handle software interrupt used during MSI test */ diff --git a/drivers/net/smc-mca.c b/drivers/net/smc-mca.c index 3b43fa8fd088..d6abb68e6e2f 100644 --- a/drivers/net/smc-mca.c +++ b/drivers/net/smc-mca.c @@ -196,6 +196,7 @@ static int __init ultramca_probe(struct device *gen_dev) int tirq = 0; int base_addr = ultra_io[ultra_found]; int irq = ultra_irq[ultra_found]; + DECLARE_MAC_BUF(mac); if (base_addr || irq) { printk(KERN_INFO "Probing for SMC MCA adapter"); @@ -330,10 +331,11 @@ static int __init ultramca_probe(struct device *gen_dev) reg4 = inb(ioaddr + 4) & 0x7f; outb(reg4, ioaddr + 4); - printk(KERN_INFO "smc_mca[%d]: Parameters: %#3x,", slot + 1, ioaddr); - for (i = 0; i < 6; i++) - printk(" %2.2X", dev->dev_addr[i] = inb(ioaddr + 8 + i)); + dev->dev_addr[i] = inb(ioaddr + 8 + i); + + printk(KERN_INFO "smc_mca[%d]: Parameters: %#3x, %s", + slot + 1, ioaddr, print_mac(mac, dev->dev_addr)); /* Switch from the station address to the alternate register set * and read the useful registers there. diff --git a/drivers/net/smc-ultra.c b/drivers/net/smc-ultra.c index d02bd7bc1bae..00d6cf1af484 100644 --- a/drivers/net/smc-ultra.c +++ b/drivers/net/smc-ultra.c @@ -198,6 +198,7 @@ static int __init ultra_probe1(struct net_device *dev, int ioaddr) unsigned char num_pages, irqreg, addr, piomode; unsigned char idreg = inb(ioaddr + 7); unsigned char reg4 = inb(ioaddr + 4) & 0x7f; + DECLARE_MAC_BUF(mac); if (!request_region(ioaddr, ULTRA_IO_EXTENT, DRV_NAME)) return -EBUSY; @@ -224,10 +225,11 @@ static int __init ultra_probe1(struct net_device *dev, int ioaddr) model_name = (idreg & 0xF0) == 0x20 ? "SMC Ultra" : "SMC EtherEZ"; - printk("%s: %s at %#3x,", dev->name, model_name, ioaddr); - for (i = 0; i < 6; i++) - printk(" %2.2X", dev->dev_addr[i] = inb(ioaddr + 8 + i)); + dev->dev_addr[i] = inb(ioaddr + 8 + i); + + printk("%s: %s at %#3x, %s", dev->name, model_name, + ioaddr, print_mac(mac, dev->dev_addr)); /* Switch from the station address to the alternate register set and read the useful registers there. */ diff --git a/drivers/net/smc-ultra32.c b/drivers/net/smc-ultra32.c index 043a5002029c..a5a91ace28cc 100644 --- a/drivers/net/smc-ultra32.c +++ b/drivers/net/smc-ultra32.c @@ -163,6 +163,7 @@ static int __init ultra32_probe1(struct net_device *dev, int ioaddr) unsigned char idreg; unsigned char reg4; const char *ifmap[] = {"UTP No Link", "", "UTP/AUI", "UTP/BNC"}; + DECLARE_MAC_BUF(mac); if (!request_region(ioaddr, ULTRA32_IO_EXTENT, DRV_NAME)) return -EBUSY; @@ -203,10 +204,11 @@ static int __init ultra32_probe1(struct net_device *dev, int ioaddr) model_name = "SMC Ultra32"; - printk("%s: %s at 0x%X,", dev->name, model_name, ioaddr); - for (i = 0; i < 6; i++) - printk(" %2.2X", dev->dev_addr[i] = inb(ioaddr + 8 + i)); + dev->dev_addr[i] = inb(ioaddr + 8 + i); + + printk("%s: %s at 0x%X, %s", + dev->name, model_name, ioaddr, print_mac(mac, dev->dev_addr)); /* Switch from the station address to the alternate register set and read the useful registers there. */ diff --git a/drivers/net/smc9194.c b/drivers/net/smc9194.c index 5b6748e3ea0e..cb2698de5190 100644 --- a/drivers/net/smc9194.c +++ b/drivers/net/smc9194.c @@ -876,6 +876,8 @@ static int __init smc_probe(struct net_device *dev, int ioaddr) word memory_info_register; word memory_cfg_register; + DECLARE_MAC_BUF(mac); + /* Grab the region so that no one else tries to probe our ioports. */ if (!request_region(ioaddr, SMC_IO_EXTENT, DRV_NAME)) return -EBUSY; @@ -1031,10 +1033,7 @@ static int __init smc_probe(struct net_device *dev, int ioaddr) /* . Print the Ethernet address */ - printk("ADDR: "); - for (i = 0; i < 5; i++) - printk("%2.2x:", dev->dev_addr[i] ); - printk("%2.2x \n", dev->dev_addr[5] ); + printk("ADDR: %s\n", print_mac(mac, dev->dev_addr)); /* set the private data to zero by default */ memset(dev->priv, 0, sizeof(struct smc_local)); diff --git a/drivers/net/smc91x.c b/drivers/net/smc91x.c index fe28d277f21a..24e610e711e8 100644 --- a/drivers/net/smc91x.c +++ b/drivers/net/smc91x.c @@ -1822,9 +1822,10 @@ static int __init smc_probe(struct net_device *dev, void __iomem *ioaddr) { struct smc_local *lp = netdev_priv(dev); static int version_printed = 0; - int i, retval; + int retval; unsigned int val, revision_register; const char *version_string; + DECLARE_MAC_BUF(mac); DBG(2, "%s: %s\n", CARDNAME, __FUNCTION__); @@ -2014,10 +2015,8 @@ static int __init smc_probe(struct net_device *dev, void __iomem *ioaddr) "set using ifconfig\n", dev->name); } else { /* Print the Ethernet address */ - printk("%s: Ethernet addr: ", dev->name); - for (i = 0; i < 5; i++) - printk("%2.2x:", dev->dev_addr[i]); - printk("%2.2x\n", dev->dev_addr[5]); + printk("%s: Ethernet addr: %s\n", + dev->name, print_mac(mac, dev->dev_addr)); } if (lp->phy_type == 0) { diff --git a/drivers/net/starfire.c b/drivers/net/starfire.c index 5785429ca0e2..ea253754763a 100644 --- a/drivers/net/starfire.c +++ b/drivers/net/starfire.c @@ -694,6 +694,7 @@ static int __devinit starfire_init_one(struct pci_dev *pdev, void __iomem *base; int drv_flags, io_size; int boguscnt; + DECLARE_MAC_BUF(mac); /* when built into the kernel, we only print version if device is found */ #ifndef MODULE @@ -863,11 +864,9 @@ static int __devinit starfire_init_one(struct pci_dev *pdev, if (register_netdev(dev)) goto err_out_cleardev; - printk(KERN_INFO "%s: %s at %p, ", - dev->name, netdrv_tbl[chip_idx].name, base); - for (i = 0; i < 5; i++) - printk("%2.2x:", dev->dev_addr[i]); - printk("%2.2x, IRQ %d.\n", dev->dev_addr[i], irq); + printk(KERN_INFO "%s: %s at %p, %s, IRQ %d.\n", + dev->name, netdrv_tbl[chip_idx].name, base, + print_mac(mac, dev->dev_addr), irq); if (drv_flags & CanHaveMII) { int phy, phy_idx = 0; @@ -1472,13 +1471,16 @@ static int __netdev_rx(struct net_device *dev, int *quota) } #ifndef final_version /* Remove after testing. */ /* You will want this info for the initial debug. */ - if (debug > 5) - printk(KERN_DEBUG " Rx data %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:" - "%2.2x %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x %2.2x%2.2x.\n", - skb->data[0], skb->data[1], skb->data[2], skb->data[3], - skb->data[4], skb->data[5], skb->data[6], skb->data[7], - skb->data[8], skb->data[9], skb->data[10], - skb->data[11], skb->data[12], skb->data[13]); + if (debug > 5) { + DECLARE_MAC_BUF(mac); + DECLARE_MAC_BUF(mac2); + + printk(KERN_DEBUG " Rx data %s %s" + " %2.2x%2.2x.\n", + print_mac(mac, &skb->data[0]), + print_mac(mac2, &skb->data[6]), + skb->data[12], skb->data[13]); + } #endif skb->protocol = eth_type_trans(skb, dev); diff --git a/drivers/net/sun3lance.c b/drivers/net/sun3lance.c index f8fbc0492706..f8d46134daca 100644 --- a/drivers/net/sun3lance.c +++ b/drivers/net/sun3lance.c @@ -300,6 +300,7 @@ static int __init lance_probe( struct net_device *dev) static int did_version; volatile unsigned short *ioaddr_probe; unsigned short tmp1, tmp2; + DECLARE_MAC_BUF(mac); #ifdef CONFIG_SUN3 ioaddr = (unsigned long)ioremap(LANCE_OBIO, PAGE_SIZE); @@ -375,8 +376,7 @@ static int __init lance_probe( struct net_device *dev) MEM->init.hwaddr[4] = dev->dev_addr[5]; MEM->init.hwaddr[5] = dev->dev_addr[4]; - for( i = 0; i < 6; ++i ) - printk( "%02x%s", dev->dev_addr[i], (i < 5) ? ":" : "\n" ); + printk("%s\n", print_mac(mac, dev->dev_addr)); MEM->init.mode = 0x0000; MEM->init.filter[0] = 0x00000000; @@ -590,17 +590,12 @@ static int lance_start_xmit( struct sk_buff *skb, struct net_device *dev ) /* Fill in a Tx ring entry */ #if 0 if (lance_debug >= 2) { - u_char *p; - int i; - printk( "%s: TX pkt %d type 0x%04x from ", dev->name, - lp->new_tx, ((u_short *)skb->data)[6]); - for( p = &((u_char *)skb->data)[6], i = 0; i < 6; i++ ) - printk("%02x%s", *p++, i != 5 ? ":" : "" ); - printk(" to "); - for( p = (u_char *)skb->data, i = 0; i < 6; i++ ) - printk("%02x%s", *p++, i != 5 ? ":" : "" ); - printk(" data at 0x%08x len %d\n", (int)skb->data, - (int)skb->len ); + printk( "%s: TX pkt %d type 0x%04x" + " from %s to %s" + " data at 0x%08x len %d\n", + dev->name, lp->new_tx, ((u_short *)skb->data)[6], + DEV_ADDR(&skb->data[6]), DEV_ADDR(skb->data), + (int)skb->data, (int)skb->len ); } #endif /* We're not prepared for the int until the last flags are set/reset. @@ -825,13 +820,14 @@ static int lance_rx( struct net_device *dev ) #if 0 if (lance_debug >= 3) { - u_char *data = PKTBUF_ADDR(head), *p; - printk( "%s: RX pkt %d type 0x%04x from ", dev->name, entry, ((u_short *)data)[6]); - for( p = &data[6], i = 0; i < 6; i++ ) - printk("%02x%s", *p++, i != 5 ? ":" : "" ); - printk(" to "); - for( p = data, i = 0; i < 6; i++ ) - printk("%02x%s", *p++, i != 5 ? ":" : "" ); + u_char *data = PKTBUF_ADDR(head); + DECLARE_MAC_BUF(mac); + DECLARE_MAC_BUF(mac2) + printk("%s: RX pkt %d type 0x%04x" + " from %s to %s", + dev->name, lp->new_tx, ((u_short *)data)[6], + print_mac(mac, &data[6]), print_mac(mac2, data)); + printk(" data %02x %02x %02x %02x %02x %02x %02x %02x " "len %d at %08x\n", data[15], data[16], data[17], data[18], diff --git a/drivers/net/sunbmac.c b/drivers/net/sunbmac.c index 4ba3e4857e90..fe3ac6f9ae89 100644 --- a/drivers/net/sunbmac.c +++ b/drivers/net/sunbmac.c @@ -1082,6 +1082,7 @@ static int __init bigmac_ether_init(struct sbus_dev *qec_sdev) struct bigmac *bp; u8 bsizes, bsizes_more; int i; + DECLARE_MAC_BUF(mac); /* Get a new device struct for this interface. */ dev = alloc_etherdev(sizeof(struct bigmac)); @@ -1226,11 +1227,8 @@ static int __init bigmac_ether_init(struct sbus_dev *qec_sdev) dev_set_drvdata(&bp->bigmac_sdev->ofdev.dev, bp); - printk(KERN_INFO "%s: BigMAC 100baseT Ethernet ", dev->name); - for (i = 0; i < 6; i++) - printk("%2.2x%c", dev->dev_addr[i], - i == 5 ? ' ' : ':'); - printk("\n"); + printk(KERN_INFO "%s: BigMAC 100baseT Ethernet %s\n", + dev->name, print_mac(mac, dev->dev_addr)); return 0; diff --git a/drivers/net/sundance.c b/drivers/net/sundance.c index 3c553dcc2b9d..a37637ec9b77 100644 --- a/drivers/net/sundance.c +++ b/drivers/net/sundance.c @@ -467,7 +467,7 @@ static int __devinit sundance_probe1 (struct pci_dev *pdev, int bar = 1; #endif int phy, phy_idx = 0; - + DECLARE_MAC_BUF(mac); /* when built into the kernel, we only print version if device is found */ #ifndef MODULE @@ -546,11 +546,9 @@ static int __devinit sundance_probe1 (struct pci_dev *pdev, if (i) goto err_out_unmap_rx; - printk(KERN_INFO "%s: %s at %p, ", - dev->name, pci_id_tbl[chip_idx].name, ioaddr); - for (i = 0; i < 5; i++) - printk("%2.2x:", dev->dev_addr[i]); - printk("%2.2x, IRQ %d.\n", dev->dev_addr[i], irq); + printk(KERN_INFO "%s: %s at %p, %s, IRQ %d.\n", + dev->name, pci_id_tbl[chip_idx].name, ioaddr, + print_mac(mac, dev->dev_addr), irq); np->phys[0] = 1; /* Default setting */ np->mii_preamble_required++; diff --git a/drivers/net/sungem.c b/drivers/net/sungem.c index 869ac44c51f3..53b8344a68ef 100644 --- a/drivers/net/sungem.c +++ b/drivers/net/sungem.c @@ -2965,7 +2965,8 @@ static int __devinit gem_init_one(struct pci_dev *pdev, unsigned long gemreg_base, gemreg_len; struct net_device *dev; struct gem *gp; - int i, err, pci_using_dac; + int err, pci_using_dac; + DECLARE_MAC_BUF(mac); if (gem_version_printed++ == 0) printk(KERN_INFO "%s", version); @@ -3149,12 +3150,9 @@ static int __devinit gem_init_one(struct pci_dev *pdev, goto err_out_free_consistent; } - printk(KERN_INFO "%s: Sun GEM (PCI) 10/100/1000BaseT Ethernet ", - dev->name); - for (i = 0; i < 6; i++) - printk("%2.2x%c", dev->dev_addr[i], - i == 5 ? ' ' : ':'); - printk("\n"); + printk(KERN_INFO "%s: Sun GEM (PCI) 10/100/1000BaseT Ethernet " + "%s\n", + dev->name, print_mac(mac, dev->dev_addr)); if (gp->phy_type == phy_mii_mdio0 || gp->phy_type == phy_mii_mdio1) diff --git a/drivers/net/sunhme.c b/drivers/net/sunhme.c index 170580c13127..120c8affe83d 100644 --- a/drivers/net/sunhme.c +++ b/drivers/net/sunhme.c @@ -2664,6 +2664,7 @@ static int __devinit happy_meal_sbus_probe_one(struct sbus_dev *sdev, int is_qfe struct net_device *dev; int i, qfe_slot = -1; int err = -ENODEV; + DECLARE_MAC_BUF(mac); if (is_qfe) { qp = quattro_sbus_find(sdev); @@ -2850,10 +2851,7 @@ static int __devinit happy_meal_sbus_probe_one(struct sbus_dev *sdev, int is_qfe printk(KERN_INFO "%s: HAPPY MEAL (SBUS) 10/100baseT Ethernet ", dev->name); - for (i = 0; i < 6; i++) - printk("%2.2x%c", - dev->dev_addr[i], i == 5 ? ' ' : ':'); - printk("\n"); + printk("%s\n", print_mac(mac, dev->dev_addr)); return 0; @@ -2988,6 +2986,7 @@ static int __devinit happy_meal_pci_probe(struct pci_dev *pdev, int i, qfe_slot = -1; char prom_name[64]; int err; + DECLARE_MAC_BUF(mac); /* Now make sure pci_dev cookie is there. */ #ifdef CONFIG_SPARC @@ -3201,10 +3200,7 @@ static int __devinit happy_meal_pci_probe(struct pci_dev *pdev, printk(KERN_INFO "%s: HAPPY MEAL (PCI/CheerIO) 10/100BaseT Ethernet ", dev->name); - for (i = 0; i < 6; i++) - printk("%2.2x%c", dev->dev_addr[i], i == 5 ? ' ' : ':'); - - printk("\n"); + printk("%s\n", print_mac(mac, dev->dev_addr)); return 0; diff --git a/drivers/net/sunlance.c b/drivers/net/sunlance.c index 7bf5c90b7749..26ade68aeabf 100644 --- a/drivers/net/sunlance.c +++ b/drivers/net/sunlance.c @@ -1321,6 +1321,7 @@ static int __devinit sparc_lance_probe_one(struct sbus_dev *sdev, struct net_device *dev; struct lance_private *lp; int i; + DECLARE_MAC_BUF(mac); dev = alloc_etherdev(sizeof(struct lance_private) + 8); if (!dev) @@ -1478,12 +1479,8 @@ no_link_test: dev_set_drvdata(&sdev->ofdev.dev, lp); - printk(KERN_INFO "%s: LANCE ", dev->name); - - for (i = 0; i < 6; i++) - printk("%2.2x%c", dev->dev_addr[i], - i == 5 ? ' ': ':'); - printk("\n"); + printk(KERN_INFO "%s: LANCE %s\n", + dev->name, print_mac(mac, dev->dev_addr)); return 0; diff --git a/drivers/net/tokenring/abyss.c b/drivers/net/tokenring/abyss.c index 22fad5112406..124cfd4fbcf4 100644 --- a/drivers/net/tokenring/abyss.c +++ b/drivers/net/tokenring/abyss.c @@ -97,8 +97,9 @@ static int __devinit abyss_attach(struct pci_dev *pdev, const struct pci_device_ static int versionprinted; struct net_device *dev; struct net_local *tp; - int i, ret, pci_irq_line; + int ret, pci_irq_line; unsigned long pci_ioaddr; + DECLARE_MAC_BUF(mac); if (versionprinted++ == 0) printk("%s", version); @@ -145,12 +146,9 @@ static int __devinit abyss_attach(struct pci_dev *pdev, const struct pci_device_ } abyss_read_eeprom(dev); - - printk("%s: Ring Station Address: ", dev->name); - printk("%2.2x", dev->dev_addr[0]); - for (i = 1; i < 6; i++) - printk(":%2.2x", dev->dev_addr[i]); - printk("\n"); + + printk("%s: Ring Station Address: %s\n", + dev->name, print_mac(mac, dev->dev_addr)); tp = netdev_priv(dev); tp->setnselout = abyss_setnselout_pins; diff --git a/drivers/net/tokenring/ibmtr.c b/drivers/net/tokenring/ibmtr.c index 65e21eb7e685..e494c63bfbd9 100644 --- a/drivers/net/tokenring/ibmtr.c +++ b/drivers/net/tokenring/ibmtr.c @@ -389,6 +389,7 @@ static int __devinit ibmtr_probe1(struct net_device *dev, int PIOaddr) unsigned long timeout; static int version_printed; #endif + DECLARE_MAC_BUF(mac); /* Query the adapter PIO base port which will return * indication of where MMIO was placed. We also have a @@ -702,9 +703,8 @@ static int __devinit ibmtr_probe1(struct net_device *dev, int PIOaddr) channel_def[cardpresent - 1], adapter_def(ti->adapter_type)); DPRINTK("using irq %d, PIOaddr %hx, %dK shared RAM.\n", irq, PIOaddr, ti->mapped_ram_size / 2); - DPRINTK("Hardware address : %02X:%02X:%02X:%02X:%02X:%02X\n", - dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2], - dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]); + DPRINTK("Hardware address : %s\n", + print_mac(mac, dev->dev_addr)); if (ti->page_mask) DPRINTK("Shared RAM paging enabled. " "Page size: %uK Shared Ram size %dK\n", @@ -1739,18 +1739,20 @@ static void tr_rx(struct net_device *dev) if (!IPv4_p) { void __iomem *trhhdr = rbuf + offsetof(struct rec_buf, data); - + u8 saddr[6]; + u8 daddr[6]; + DECLARE_MAC_BUF(mac); + DECLARE_MAC_BUF(mac2); + int i; + for (i = 0 ; i < 6 ; i++) + saddr[i] = readb(trhhdr + SADDR_OFST + i); + for (i = 0 ; i < 6 ; i++) + daddr[i] = readb(trhhdr + DADDR_OFST + i); DPRINTK("Probably non-IP frame received.\n"); DPRINTK("ssap: %02X dsap: %02X " - "saddr: %02X:%02X:%02X:%02X:%02X:%02X " - "daddr: %02X:%02X:%02X:%02X:%02X:%02X\n", + "saddr: %s daddr: %$s\n", readb(llc + SSAP_OFST), readb(llc + DSAP_OFST), - readb(trhhdr+SADDR_OFST), readb(trhhdr+ SADDR_OFST+1), - readb(trhhdr+SADDR_OFST+2), readb(trhhdr+SADDR_OFST+3), - readb(trhhdr+SADDR_OFST+4), readb(trhhdr+SADDR_OFST+5), - readb(trhhdr+DADDR_OFST), readb(trhhdr+DADDR_OFST + 1), - readb(trhhdr+DADDR_OFST+2), readb(trhhdr+DADDR_OFST+3), - readb(trhhdr+DADDR_OFST+4), readb(trhhdr+DADDR_OFST+5)); + print_mac(mac, saddr), print_mac(mac2, daddr)); } #endif diff --git a/drivers/net/tokenring/lanstreamer.c b/drivers/net/tokenring/lanstreamer.c index f114fb729f54..47d84cd28097 100644 --- a/drivers/net/tokenring/lanstreamer.c +++ b/drivers/net/tokenring/lanstreamer.c @@ -447,6 +447,9 @@ static int streamer_reset(struct net_device *dev) unsigned int uaa_addr; struct sk_buff *skb = NULL; __u16 misr; +#if STREAMER_DEBUG + DECLARE_MAC_BUF(mac); +#endif streamer_priv = netdev_priv(dev); streamer_mmio = streamer_priv->streamer_mmio; @@ -575,11 +578,8 @@ static int streamer_reset(struct net_device *dev) dev->dev_addr[i+1]= addr & 0xff; } #if STREAMER_DEBUG - printk("Adapter address: "); - for (i = 0; i < 6; i++) { - printk("%02x:", dev->dev_addr[i]); - } - printk("\n"); + printk("Adapter address: %s\n", + print_mac(mac, dev->dev_addr)); #endif } return 0; @@ -1539,6 +1539,7 @@ static void streamer_arb_cmd(struct net_device *dev) #if STREAMER_NETWORK_MONITOR struct trh_hdr *mac_hdr; + DECLARE_MAC_BUF(mac); #endif writew(streamer_priv->arb, streamer_mmio + LAPA); @@ -1611,15 +1612,11 @@ static void streamer_arb_cmd(struct net_device *dev) dev->name); mac_hdr = tr_hdr(mac_frame); printk(KERN_WARNING - "%s: MAC Frame Dest. Addr: %02x:%02x:%02x:%02x:%02x:%02x \n", - dev->name, mac_hdr->daddr[0], mac_hdr->daddr[1], - mac_hdr->daddr[2], mac_hdr->daddr[3], - mac_hdr->daddr[4], mac_hdr->daddr[5]); + "%s: MAC Frame Dest. Addr: %s\n", + dev->name, print_mac(mac, mac_hdr->daddr)); printk(KERN_WARNING - "%s: MAC Frame Srce. Addr: %02x:%02x:%02x:%02x:%02x:%02x \n", - dev->name, mac_hdr->saddr[0], mac_hdr->saddr[1], - mac_hdr->saddr[2], mac_hdr->saddr[3], - mac_hdr->saddr[4], mac_hdr->saddr[5]); + "%s: MAC Frame Srce. Addr: %s\n", + dev->name, DEV->ADDR6(mac_hdr->saddr)); #endif netif_rx(mac_frame); @@ -1854,6 +1851,8 @@ static int sprintf_info(char *buffer, struct net_device *dev) struct streamer_parameters_table spt; int size = 0; int i; + DECLARE_MAC_BUF(mac); + DECLARE_MAC_BUF(mac2); writew(streamer_priv->streamer_addr_table_addr, streamer_mmio + LAPA); for (i = 0; i < 14; i += 2) { @@ -1875,37 +1874,30 @@ static int sprintf_info(char *buffer, struct net_device *dev) size = sprintf(buffer, "\n%6s: Adapter Address : Node Address : Functional Addr\n", dev->name); size += sprintf(buffer + size, - "%6s: %02x:%02x:%02x:%02x:%02x:%02x : %02x:%02x:%02x:%02x:%02x:%02x : %02x:%02x:%02x:%02x\n", - dev->name, dev->dev_addr[0], dev->dev_addr[1], - dev->dev_addr[2], dev->dev_addr[3], dev->dev_addr[4], - dev->dev_addr[5], sat.node_addr[0], sat.node_addr[1], - sat.node_addr[2], sat.node_addr[3], sat.node_addr[4], - sat.node_addr[5], sat.func_addr[0], sat.func_addr[1], - sat.func_addr[2], sat.func_addr[3]); + "%6s: %s : %s : %02x:%02x:%02x:%02x\n", + dev->name, print_mac(mac, dev->dev_addr), + print_mac(mac2, sat.node_addr), + sat.func_addr[0], sat.func_addr[1], + sat.func_addr[2], sat.func_addr[3]); size += sprintf(buffer + size, "\n%6s: Token Ring Parameters Table:\n", dev->name); size += sprintf(buffer + size, "%6s: Physical Addr : Up Node Address : Poll Address : AccPri : Auth Src : Att Code :\n", dev->name); size += sprintf(buffer + size, - "%6s: %02x:%02x:%02x:%02x : %02x:%02x:%02x:%02x:%02x:%02x : %02x:%02x:%02x:%02x:%02x:%02x : %04x : %04x : %04x :\n", + "%6s: %02x:%02x:%02x:%02x : %s : %s : %04x : %04x : %04x :\n", dev->name, spt.phys_addr[0], spt.phys_addr[1], spt.phys_addr[2], spt.phys_addr[3], - spt.up_node_addr[0], spt.up_node_addr[1], - spt.up_node_addr[2], spt.up_node_addr[3], - spt.up_node_addr[4], spt.up_node_addr[4], - spt.poll_addr[0], spt.poll_addr[1], spt.poll_addr[2], - spt.poll_addr[3], spt.poll_addr[4], spt.poll_addr[5], + print_mac(mac, spt.up_node_addr), + print_mac(mac2, spt.poll_addr), ntohs(spt.acc_priority), ntohs(spt.auth_source_class), ntohs(spt.att_code)); size += sprintf(buffer + size, "%6s: Source Address : Bcn T : Maj. V : Lan St : Lcl Rg : Mon Err : Frame Correl : \n", dev->name); size += sprintf(buffer + size, - "%6s: %02x:%02x:%02x:%02x:%02x:%02x : %04x : %04x : %04x : %04x : %04x : %04x : \n", - dev->name, spt.source_addr[0], spt.source_addr[1], - spt.source_addr[2], spt.source_addr[3], - spt.source_addr[4], spt.source_addr[5], + "%6s: %s : %04x : %04x : %04x : %04x : %04x : %04x : \n", + dev->name, print_mac(mac, spt.source_addr), ntohs(spt.beacon_type), ntohs(spt.major_vector), ntohs(spt.lan_status), ntohs(spt.local_ring), ntohs(spt.mon_error), ntohs(spt.frame_correl)); @@ -1914,14 +1906,12 @@ static int sprintf_info(char *buffer, struct net_device *dev) dev->name); size += sprintf(buffer + size, - "%6s: : %02x : %02x : %02x:%02x:%02x:%02x:%02x:%02x : %02x:%02x:%02x:%02x : \n", + "%6s: : %02x : %02x : %s : %02x:%02x:%02x:%02x : \n", dev->name, ntohs(spt.beacon_transmit), - ntohs(spt.beacon_receive), spt.beacon_naun[0], - spt.beacon_naun[1], spt.beacon_naun[2], - spt.beacon_naun[3], spt.beacon_naun[4], - spt.beacon_naun[5], spt.beacon_phys[0], - spt.beacon_phys[1], spt.beacon_phys[2], - spt.beacon_phys[3]); + ntohs(spt.beacon_receive), + print_mac(mac, spt.beacon_naun), + spt.beacon_phys[0], spt.beacon_phys[1], + spt.beacon_phys[2], spt.beacon_phys[3]); return size; } #endif diff --git a/drivers/net/tokenring/madgemc.c b/drivers/net/tokenring/madgemc.c index d0ce2ce675d5..5a4151362fc0 100644 --- a/drivers/net/tokenring/madgemc.c +++ b/drivers/net/tokenring/madgemc.c @@ -151,7 +151,8 @@ static int __devinit madgemc_probe(struct device *device) struct net_local *tp; struct card_info *card; struct mca_device *mdev = to_mca_device(device); - int ret = 0, i = 0; + int ret = 0; + DECLARE_MAC_BUF(mac); if (versionprinted++ == 0) printk("%s", version); @@ -322,11 +323,8 @@ static int __devinit madgemc_probe(struct device *device) mca_device_set_name(mdev, (card->cardtype == 0x08)?MADGEMC16_CARDNAME:MADGEMC32_CARDNAME); mca_set_adapter_procfn(mdev->slot, madgemc_mcaproc, dev); - printk("%s: Ring Station Address: ", dev->name); - printk("%2.2x", dev->dev_addr[0]); - for (i = 1; i < 6; i++) - printk(":%2.2x", dev->dev_addr[i]); - printk("\n"); + printk("%s: Ring Station Address: %s\n", + dev->name, print_mac(mac, dev->dev_addr)); if (tmsdev_init(dev, device)) { printk("%s: unable to get memory for dev->priv.\n", @@ -692,11 +690,11 @@ static int madgemc_mcaproc(char *buf, int slot, void *d) struct net_local *tp = netdev_priv(dev); struct card_info *curcard = tp->tmspriv; int len = 0; + DECLARE_MAC_BUF(mac); len += sprintf(buf+len, "-------\n"); if (curcard) { struct net_local *tp = netdev_priv(dev); - int i; len += sprintf(buf+len, "Card Revision: %d\n", curcard->cardrev); len += sprintf(buf+len, "RAM Size: %dkb\n", curcard->ramsize); @@ -716,11 +714,8 @@ static int madgemc_mcaproc(char *buf, int slot, void *d) } len += sprintf(buf+len, " (%s)\n", (curcard->fairness)?"Unfair":"Fair"); - len += sprintf(buf+len, "Ring Station Address: "); - len += sprintf(buf+len, "%2.2x", dev->dev_addr[0]); - for (i = 1; i < 6; i++) - len += sprintf(buf+len, " %2.2x", dev->dev_addr[i]); - len += sprintf(buf+len, "\n"); + len += sprintf(buf+len, "Ring Station Address: %s\n", + print_mac(mac, dev->dev_addr)); } else len += sprintf(buf+len, "Card not configured\n"); diff --git a/drivers/net/tokenring/olympic.c b/drivers/net/tokenring/olympic.c index a149d5e2965c..74c1f0f189f5 100644 --- a/drivers/net/tokenring/olympic.c +++ b/drivers/net/tokenring/olympic.c @@ -418,14 +418,15 @@ static int __devinit olympic_init(struct net_device *dev) writel(uaa_addr,olympic_mmio+LAPA); adapter_addr=olympic_priv->olympic_lap + (uaa_addr & (~0xf800)); + memcpy_fromio(&dev->dev_addr[0], adapter_addr,6); + #if OLYMPIC_DEBUG - printk("adapter address: %02x:%02x:%02x:%02x:%02x:%02x\n", - readb(adapter_addr), readb(adapter_addr+1),readb(adapter_addr+2), - readb(adapter_addr+3),readb(adapter_addr+4),readb(adapter_addr+5)); + { + DECLARE_MAC_BUF(mac); + printk("adapter address: %s\n", print_mac(mac, dev->dev_addr)); + } #endif - memcpy_fromio(&dev->dev_addr[0], adapter_addr,6); - olympic_priv->olympic_addr_table_addr = swab16(readw(init_srb + 12)); olympic_priv->olympic_parms_addr = swab16(readw(init_srb + 14)); @@ -440,6 +441,7 @@ static int olympic_open(struct net_device *dev) unsigned long flags, t; int i, open_finished = 1 ; u8 resp, err; + DECLARE_MAC_BUF(mac); DECLARE_WAITQUEUE(wait,current) ; @@ -567,14 +569,8 @@ static int olympic_open(struct net_device *dev) goto out; case 0x32: - printk(KERN_WARNING "%s: Invalid LAA: %02x:%02x:%02x:%02x:%02x:%02x\n", - dev->name, - olympic_priv->olympic_laa[0], - olympic_priv->olympic_laa[1], - olympic_priv->olympic_laa[2], - olympic_priv->olympic_laa[3], - olympic_priv->olympic_laa[4], - olympic_priv->olympic_laa[5]) ; + printk(KERN_WARNING "%s: Invalid LAA: %s\n", + dev->name, print_mac(mac, olympic_priv->olympic_laa)); goto out; default: @@ -704,30 +700,26 @@ static int olympic_open(struct net_device *dev) #endif if (olympic_priv->olympic_network_monitor) { - u8 __iomem *oat ; - u8 __iomem *opt ; - oat = (olympic_priv->olympic_lap + olympic_priv->olympic_addr_table_addr) ; - opt = (olympic_priv->olympic_lap + olympic_priv->olympic_parms_addr) ; - - printk("%s: Node Address: %02x:%02x:%02x:%02x:%02x:%02x\n",dev->name, - readb(oat+offsetof(struct olympic_adapter_addr_table,node_addr)), - readb(oat+offsetof(struct olympic_adapter_addr_table,node_addr)+1), - readb(oat+offsetof(struct olympic_adapter_addr_table,node_addr)+2), - readb(oat+offsetof(struct olympic_adapter_addr_table,node_addr)+3), - readb(oat+offsetof(struct olympic_adapter_addr_table,node_addr)+4), - readb(oat+offsetof(struct olympic_adapter_addr_table,node_addr)+5)); + u8 __iomem *oat; + u8 __iomem *opt; + int i; + u8 addr[6]; + DECLARE_MAC_BUF(mac); + oat = (olympic_priv->olympic_lap + olympic_priv->olympic_addr_table_addr); + opt = (olympic_priv->olympic_lap + olympic_priv->olympic_parms_addr); + + for (i = 0; i < 6; i++) + addr[i] = readb(oat+offsetof(struct olympic_adapter_addr_table,node_addr)+i); + printk("%s: Node Address: %s\n",dev->name, print_mac(mac, addr)); printk("%s: Functional Address: %02x:%02x:%02x:%02x\n",dev->name, readb(oat+offsetof(struct olympic_adapter_addr_table,func_addr)), readb(oat+offsetof(struct olympic_adapter_addr_table,func_addr)+1), readb(oat+offsetof(struct olympic_adapter_addr_table,func_addr)+2), readb(oat+offsetof(struct olympic_adapter_addr_table,func_addr)+3)); - printk("%s: NAUN Address: %02x:%02x:%02x:%02x:%02x:%02x\n",dev->name, - readb(opt+offsetof(struct olympic_parameters_table, up_node_addr)), - readb(opt+offsetof(struct olympic_parameters_table, up_node_addr)+1), - readb(opt+offsetof(struct olympic_parameters_table, up_node_addr)+2), - readb(opt+offsetof(struct olympic_parameters_table, up_node_addr)+3), - readb(opt+offsetof(struct olympic_parameters_table, up_node_addr)+4), - readb(opt+offsetof(struct olympic_parameters_table, up_node_addr)+5)); + + for (i = 0; i < 6; i++) + addr[i] = readb(opt+offsetof(struct olympic_parameters_table, up_node_addr)+i); + printk("%s: NAUN Address: %s\n",dev->name, print_mac(mac, addr)); } netif_start_queue(dev); @@ -1445,11 +1437,14 @@ static void olympic_arb_cmd(struct net_device *dev) mac_frame->protocol = tr_type_trans(mac_frame, dev); if (olympic_priv->olympic_network_monitor) { - struct trh_hdr *mac_hdr ; - printk(KERN_WARNING "%s: Received MAC Frame, details: \n",dev->name) ; + struct trh_hdr *mac_hdr; + DECLARE_MAC_BUF(mac); + printk(KERN_WARNING "%s: Received MAC Frame, details: \n",dev->name); mac_hdr = tr_hdr(mac_frame); - printk(KERN_WARNING "%s: MAC Frame Dest. Addr: %02x:%02x:%02x:%02x:%02x:%02x \n", dev->name , mac_hdr->daddr[0], mac_hdr->daddr[1], mac_hdr->daddr[2], mac_hdr->daddr[3], mac_hdr->daddr[4], mac_hdr->daddr[5]) ; - printk(KERN_WARNING "%s: MAC Frame Srce. Addr: %02x:%02x:%02x:%02x:%02x:%02x \n", dev->name , mac_hdr->saddr[0], mac_hdr->saddr[1], mac_hdr->saddr[2], mac_hdr->saddr[3], mac_hdr->saddr[4], mac_hdr->saddr[5]) ; + printk(KERN_WARNING "%s: MAC Frame Dest. Addr: %s\n", + dev->name, print_mac(mac, mac_hdr->daddr)); + printk(KERN_WARNING "%s: MAC Frame Srce. Addr: %s\n", + dev->name, print_mac(mac, mac_hdr->saddr)); } netif_rx(mac_frame); dev->last_rx = jiffies; @@ -1644,26 +1639,24 @@ static int olympic_proc_info(char *buffer, char **start, off_t offset, int lengt int len=0; off_t begin=0; off_t pos=0; - + u8 addr[6]; + u8 addr2[6]; + int i; + DECLARE_MAC_BUF(mac); + DECLARE_MAC_BUF(mac2); + size = sprintf(buffer, "IBM Pit/Pit-Phy/Olympic Chipset Token Ring Adapter %s\n",dev->name); size += sprintf(buffer+size, "\n%6s: Adapter Address : Node Address : Functional Addr\n", dev->name); - size += sprintf(buffer+size, "%6s: %02x:%02x:%02x:%02x:%02x:%02x : %02x:%02x:%02x:%02x:%02x:%02x : %02x:%02x:%02x:%02x\n", + for (i = 0 ; i < 6 ; i++) + addr[i] = readb(oat+offsetof(struct olympic_adapter_addr_table,node_addr) + i); + + size += sprintf(buffer+size, "%6s: %s : %s : %02x:%02x:%02x:%02x\n", dev->name, - dev->dev_addr[0], - dev->dev_addr[1], - dev->dev_addr[2], - dev->dev_addr[3], - dev->dev_addr[4], - dev->dev_addr[5], - readb(oat+offsetof(struct olympic_adapter_addr_table,node_addr)), - readb(oat+offsetof(struct olympic_adapter_addr_table,node_addr)+1), - readb(oat+offsetof(struct olympic_adapter_addr_table,node_addr)+2), - readb(oat+offsetof(struct olympic_adapter_addr_table,node_addr)+3), - readb(oat+offsetof(struct olympic_adapter_addr_table,node_addr)+4), - readb(oat+offsetof(struct olympic_adapter_addr_table,node_addr)+5), + print_mac(mac, dev->dev_addr), + print_mac(mac2, addr), readb(oat+offsetof(struct olympic_adapter_addr_table,func_addr)), readb(oat+offsetof(struct olympic_adapter_addr_table,func_addr)+1), readb(oat+offsetof(struct olympic_adapter_addr_table,func_addr)+2), @@ -1673,25 +1666,20 @@ static int olympic_proc_info(char *buffer, char **start, off_t offset, int lengt size += sprintf(buffer+size, "%6s: Physical Addr : Up Node Address : Poll Address : AccPri : Auth Src : Att Code :\n", dev->name) ; - - size += sprintf(buffer+size, "%6s: %02x:%02x:%02x:%02x : %02x:%02x:%02x:%02x:%02x:%02x : %02x:%02x:%02x:%02x:%02x:%02x : %04x : %04x : %04x :\n", + + for (i = 0 ; i < 6 ; i++) + addr[i] = readb(opt+offsetof(struct olympic_parameters_table, up_node_addr) + i); + for (i = 0 ; i < 6 ; i++) + addr2[i] = readb(opt+offsetof(struct olympic_parameters_table, poll_addr) + i); + + size += sprintf(buffer+size, "%6s: %02x:%02x:%02x:%02x : %s : %s : %04x : %04x : %04x :\n", dev->name, readb(opt+offsetof(struct olympic_parameters_table, phys_addr)), readb(opt+offsetof(struct olympic_parameters_table, phys_addr)+1), readb(opt+offsetof(struct olympic_parameters_table, phys_addr)+2), readb(opt+offsetof(struct olympic_parameters_table, phys_addr)+3), - readb(opt+offsetof(struct olympic_parameters_table, up_node_addr)), - readb(opt+offsetof(struct olympic_parameters_table, up_node_addr)+1), - readb(opt+offsetof(struct olympic_parameters_table, up_node_addr)+2), - readb(opt+offsetof(struct olympic_parameters_table, up_node_addr)+3), - readb(opt+offsetof(struct olympic_parameters_table, up_node_addr)+4), - readb(opt+offsetof(struct olympic_parameters_table, up_node_addr)+5), - readb(opt+offsetof(struct olympic_parameters_table, poll_addr)), - readb(opt+offsetof(struct olympic_parameters_table, poll_addr)+1), - readb(opt+offsetof(struct olympic_parameters_table, poll_addr)+2), - readb(opt+offsetof(struct olympic_parameters_table, poll_addr)+3), - readb(opt+offsetof(struct olympic_parameters_table, poll_addr)+4), - readb(opt+offsetof(struct olympic_parameters_table, poll_addr)+5), + print_mac(mac, addr), + print_mac(mac2, addr2), swab16(readw(opt+offsetof(struct olympic_parameters_table, acc_priority))), swab16(readw(opt+offsetof(struct olympic_parameters_table, auth_source_class))), swab16(readw(opt+offsetof(struct olympic_parameters_table, att_code)))); @@ -1699,14 +1687,11 @@ static int olympic_proc_info(char *buffer, char **start, off_t offset, int lengt size += sprintf(buffer+size, "%6s: Source Address : Bcn T : Maj. V : Lan St : Lcl Rg : Mon Err : Frame Correl : \n", dev->name) ; - size += sprintf(buffer+size, "%6s: %02x:%02x:%02x:%02x:%02x:%02x : %04x : %04x : %04x : %04x : %04x : %04x : \n", + for (i = 0 ; i < 6 ; i++) + addr[i] = readb(opt+offsetof(struct olympic_parameters_table, source_addr) + i); + size += sprintf(buffer+size, "%6s: %s : %04x : %04x : %04x : %04x : %04x : %04x : \n", dev->name, - readb(opt+offsetof(struct olympic_parameters_table, source_addr)), - readb(opt+offsetof(struct olympic_parameters_table, source_addr)+1), - readb(opt+offsetof(struct olympic_parameters_table, source_addr)+2), - readb(opt+offsetof(struct olympic_parameters_table, source_addr)+3), - readb(opt+offsetof(struct olympic_parameters_table, source_addr)+4), - readb(opt+offsetof(struct olympic_parameters_table, source_addr)+5), + print_mac(mac, addr), swab16(readw(opt+offsetof(struct olympic_parameters_table, beacon_type))), swab16(readw(opt+offsetof(struct olympic_parameters_table, major_vector))), swab16(readw(opt+offsetof(struct olympic_parameters_table, lan_status))), @@ -1717,16 +1702,13 @@ static int olympic_proc_info(char *buffer, char **start, off_t offset, int lengt size += sprintf(buffer+size, "%6s: Beacon Details : Tx : Rx : NAUN Node Address : NAUN Node Phys : \n", dev->name) ; - size += sprintf(buffer+size, "%6s: : %02x : %02x : %02x:%02x:%02x:%02x:%02x:%02x : %02x:%02x:%02x:%02x : \n", + for (i = 0 ; i < 6 ; i++) + addr[i] = readb(opt+offsetof(struct olympic_parameters_table, beacon_naun) + i); + size += sprintf(buffer+size, "%6s: : %02x : %02x : %s : %02x:%02x:%02x:%02x : \n", dev->name, swab16(readw(opt+offsetof(struct olympic_parameters_table, beacon_transmit))), swab16(readw(opt+offsetof(struct olympic_parameters_table, beacon_receive))), - readb(opt+offsetof(struct olympic_parameters_table, beacon_naun)), - readb(opt+offsetof(struct olympic_parameters_table, beacon_naun)+1), - readb(opt+offsetof(struct olympic_parameters_table, beacon_naun)+2), - readb(opt+offsetof(struct olympic_parameters_table, beacon_naun)+3), - readb(opt+offsetof(struct olympic_parameters_table, beacon_naun)+4), - readb(opt+offsetof(struct olympic_parameters_table, beacon_naun)+5), + print_mac(mac, addr), readb(opt+offsetof(struct olympic_parameters_table, beacon_phys)), readb(opt+offsetof(struct olympic_parameters_table, beacon_phys)+1), readb(opt+offsetof(struct olympic_parameters_table, beacon_phys)+2), diff --git a/drivers/net/tokenring/proteon.c b/drivers/net/tokenring/proteon.c index 85d156dea033..ca6b65919b3d 100644 --- a/drivers/net/tokenring/proteon.c +++ b/drivers/net/tokenring/proteon.c @@ -122,6 +122,7 @@ static int __init setup_card(struct net_device *dev, struct device *pdev) static int versionprinted; const unsigned *port; int j,err = 0; + DECLARE_MAC_BUF(mac); if (!dev) return -ENOMEM; @@ -152,11 +153,8 @@ static int __init setup_card(struct net_device *dev, struct device *pdev) proteon_read_eeprom(dev); - printk(KERN_DEBUG "proteon.c: Ring Station Address: "); - printk("%2.2x", dev->dev_addr[0]); - for (j = 1; j < 6; j++) - printk(":%2.2x", dev->dev_addr[j]); - printk("\n"); + printk(KERN_DEBUG "proteon.c: Ring Station Address: %s\n", + print_mac(mac, dev->dev_addr)); tp = netdev_priv(dev); tp->setnselout = proteon_setnselout_pins; diff --git a/drivers/net/tokenring/skisa.c b/drivers/net/tokenring/skisa.c index ecbddc80a2a5..32e8d5a9f958 100644 --- a/drivers/net/tokenring/skisa.c +++ b/drivers/net/tokenring/skisa.c @@ -139,6 +139,7 @@ static int __init setup_card(struct net_device *dev, struct device *pdev) static int versionprinted; const unsigned *port; int j, err = 0; + DECLARE_MAC_BUF(mac); if (!dev) return -ENOMEM; @@ -169,11 +170,8 @@ static int __init setup_card(struct net_device *dev, struct device *pdev) sk_isa_read_eeprom(dev); - printk(KERN_DEBUG "skisa.c: Ring Station Address: "); - printk("%2.2x", dev->dev_addr[0]); - for (j = 1; j < 6; j++) - printk(":%2.2x", dev->dev_addr[j]); - printk("\n"); + printk(KERN_DEBUG "skisa.c: Ring Station Address: %s\n", + print_mac(mac, dev->dev_addr)); tp = netdev_priv(dev); tp->setnselout = sk_isa_setnselout_pins; diff --git a/drivers/net/tokenring/tmspci.c b/drivers/net/tokenring/tmspci.c index ecdd8511a67b..1c18f782f522 100644 --- a/drivers/net/tokenring/tmspci.c +++ b/drivers/net/tokenring/tmspci.c @@ -96,10 +96,11 @@ static int __devinit tms_pci_attach(struct pci_dev *pdev, const struct pci_devic static int versionprinted; struct net_device *dev; struct net_local *tp; - int i, ret; + int ret; unsigned int pci_irq_line; unsigned long pci_ioaddr; struct card_info *cardinfo = &card_info_table[ent->driver_data]; + DECLARE_MAC_BUF(mac); if (versionprinted++ == 0) printk("%s", version); @@ -136,11 +137,8 @@ static int __devinit tms_pci_attach(struct pci_dev *pdev, const struct pci_devic tms_pci_read_eeprom(dev); - printk("%s: Ring Station Address: ", dev->name); - printk("%2.2x", dev->dev_addr[0]); - for (i = 1; i < 6; i++) - printk(":%2.2x", dev->dev_addr[i]); - printk("\n"); + printk("%s: Ring Station Address: %s\n", + dev->name, print_mac(mac, dev->dev_addr)); ret = tmsdev_init(dev, &pdev->dev); if (ret) { diff --git a/drivers/net/tsi108_eth.c b/drivers/net/tsi108_eth.c index fe3225df0d32..df10af7df7b8 100644 --- a/drivers/net/tsi108_eth.c +++ b/drivers/net/tsi108_eth.c @@ -1540,6 +1540,7 @@ tsi108_init_one(struct platform_device *pdev) struct tsi108_prv_data *data = NULL; hw_info *einfo; int err = 0; + DECLARE_MAC_BUF(mac); einfo = pdev->dev.platform_data; @@ -1628,10 +1629,8 @@ tsi108_init_one(struct platform_device *pdev) goto register_fail; } - printk(KERN_INFO "%s: Tsi108 Gigabit Ethernet, MAC: " - "%02x:%02x:%02x:%02x:%02x:%02x\n", dev->name, - dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2], - dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]); + printk(KERN_INFO "%s: Tsi108 Gigabit Ethernet, MAC: %s\n" + dev->name, print_mac(mac, dev->dev_addr)); #ifdef DEBUG data->msg_enable = DEBUG; dump_eth_one(dev); diff --git a/drivers/net/tulip/de2104x.c b/drivers/net/tulip/de2104x.c index ba3d0e5574a4..f12e33a17363 100644 --- a/drivers/net/tulip/de2104x.c +++ b/drivers/net/tulip/de2104x.c @@ -1929,6 +1929,7 @@ static int __devinit de_init_one (struct pci_dev *pdev, void __iomem *regs; unsigned long pciaddr; static int board_idx = -1; + DECLARE_MAC_BUF(mac); board_idx++; @@ -2042,15 +2043,11 @@ static int __devinit de_init_one (struct pci_dev *pdev, goto err_out_iomap; /* print info about board and interface just registered */ - printk (KERN_INFO "%s: %s at 0x%lx, " - "%02x:%02x:%02x:%02x:%02x:%02x, " - "IRQ %d\n", + printk (KERN_INFO "%s: %s at 0x%lx, %s, IRQ %d\n", dev->name, de->de21040 ? "21040" : "21041", dev->base_addr, - dev->dev_addr[0], dev->dev_addr[1], - dev->dev_addr[2], dev->dev_addr[3], - dev->dev_addr[4], dev->dev_addr[5], + print_mac(mac, dev->dev_addr), dev->irq); pci_set_drvdata(pdev, dev); diff --git a/drivers/net/tulip/de4x5.c b/drivers/net/tulip/de4x5.c index ee4215ca63f0..4633cc6dd412 100644 --- a/drivers/net/tulip/de4x5.c +++ b/drivers/net/tulip/de4x5.c @@ -1088,6 +1088,7 @@ de4x5_hw_init(struct net_device *dev, u_long iobase, struct device *gendev) struct de4x5_private *lp = netdev_priv(dev); struct pci_dev *pdev = NULL; int i, status=0; + DECLARE_MAC_BUF(mac); gendev->driver_data = dev; @@ -1123,12 +1124,8 @@ de4x5_hw_init(struct net_device *dev, u_long iobase, struct device *gendev) dev->base_addr = iobase; printk ("%s: %s at 0x%04lx", gendev->bus_id, name, iobase); - printk(", h/w address "); status = get_hw_addr(dev); - for (i = 0; i < ETH_ALEN - 1; i++) { /* get the ethernet addr. */ - printk("%2.2x:", dev->dev_addr[i]); - } - printk("%2.2x,\n", dev->dev_addr[i]); + printk(", h/w address %s\n", print_mac(mac, dev->dev_addr)); if (status != 0) { printk(" which has an Ethernet PROM CRC error.\n"); @@ -5468,19 +5465,16 @@ static void de4x5_dbg_srom(struct de4x5_srom *p) { int i; + DECLARE_MAC_BUF(mac); if (de4x5_debug & DEBUG_SROM) { printk("Sub-system Vendor ID: %04x\n", *((u_short *)p->sub_vendor_id)); printk("Sub-system ID: %04x\n", *((u_short *)p->sub_system_id)); printk("ID Block CRC: %02x\n", (u_char)(p->id_block_crc)); printk("SROM version: %02x\n", (u_char)(p->version)); - printk("# controllers: %02x\n", (u_char)(p->num_controllers)); + printk("# controllers: %02x\n", (u_char)(p->num_controllers)); - printk("Hardware Address: "); - for (i=0;iieee_addr+i)); - } - printk("%02x\n", (u_char)*(p->ieee_addr+i)); + printk("Hardware Address: %s\n", print_mac(mac, p->ieee_addr)); printk("CRC checksum: %04x\n", (u_short)(p->chksum)); for (i=0; i<64; i++) { printk("%3d %04x\n", i<<1, (u_short)*((u_short *)p+i)); @@ -5494,21 +5488,12 @@ static void de4x5_dbg_rx(struct sk_buff *skb, int len) { int i, j; + DECLARE_MAC_BUF(mac); + DECLARE_MAC_BUF(mac2); if (de4x5_debug & DEBUG_RX) { - printk("R: %02x:%02x:%02x:%02x:%02x:%02x <- %02x:%02x:%02x:%02x:%02x:%02x len/SAP:%02x%02x [%d]\n", - (u_char)skb->data[0], - (u_char)skb->data[1], - (u_char)skb->data[2], - (u_char)skb->data[3], - (u_char)skb->data[4], - (u_char)skb->data[5], - (u_char)skb->data[6], - (u_char)skb->data[7], - (u_char)skb->data[8], - (u_char)skb->data[9], - (u_char)skb->data[10], - (u_char)skb->data[11], + printk("R: %s <- %s len/SAP:%02x%02x [%d]\n", + print_mac(mac, skb->data), print_mac(mac2, &skb->data[6]), (u_char)skb->data[12], (u_char)skb->data[13], len); diff --git a/drivers/net/tulip/dmfe.c b/drivers/net/tulip/dmfe.c index e2596e9ab1d7..ca90566d5bcd 100644 --- a/drivers/net/tulip/dmfe.c +++ b/drivers/net/tulip/dmfe.c @@ -362,6 +362,7 @@ static int __devinit dmfe_init_one (struct pci_dev *pdev, struct net_device *dev; u32 pci_pmr; int i, err; + DECLARE_MAC_BUF(mac); DMFE_DBUG(0, "dmfe_init_one()", 0); @@ -470,13 +471,13 @@ static int __devinit dmfe_init_one (struct pci_dev *pdev, if (err) goto err_out_res; - printk(KERN_INFO "%s: Davicom DM%04lx at pci%s,", - dev->name, - ent->driver_data >> 16, - pci_name(pdev)); - for (i = 0; i < 6; i++) - printk("%c%02x", i ? ':' : ' ', dev->dev_addr[i]); - printk(", irq %d.\n", dev->irq); + printk(KERN_INFO "%s: Davicom DM%04lx at pci%s, " + "%s, irq %d.\n", + dev->name, + ent->driver_data >> 16, + pci_name(pdev), + print_mac(mac, dev->dev_addr), + dev->irq); pci_set_master(pdev); diff --git a/drivers/net/tulip/tulip_core.c b/drivers/net/tulip/tulip_core.c index 66977aaa7176..80fee2292531 100644 --- a/drivers/net/tulip/tulip_core.c +++ b/drivers/net/tulip/tulip_core.c @@ -1051,12 +1051,11 @@ static void set_rx_mode(struct net_device *dev) filterbit &= 0x3f; mc_filter[filterbit >> 5] |= 1 << (filterbit & 31); if (tulip_debug > 2) { - printk(KERN_INFO "%s: Added filter for %2.2x:%2.2x:%2.2x:" - "%2.2x:%2.2x:%2.2x %8.8x bit %d.\n", dev->name, - mclist->dmi_addr[0], mclist->dmi_addr[1], - mclist->dmi_addr[2], mclist->dmi_addr[3], - mclist->dmi_addr[4], mclist->dmi_addr[5], - ether_crc(ETH_ALEN, mclist->dmi_addr), filterbit); + DECLARE_MAC_BUF(mac); + printk(KERN_INFO "%s: Added filter for %s" + " %8.8x bit %d.\n", + dev->name, print_mac(mac, mclist->dmi_addr), + ether_crc(ETH_ALEN, mclist->dmi_addr), filterbit); } } if (mc_filter[0] == tp->mc_filter[0] && @@ -1256,6 +1255,7 @@ static int __devinit tulip_init_one (struct pci_dev *pdev, const char *chip_name = tulip_tbl[chip_idx].chip_name; unsigned int eeprom_missing = 0; unsigned int force_csr0 = 0; + DECLARE_MAC_BUF(mac); #ifndef MODULE static int did_version; /* Already printed version info. */ @@ -1639,8 +1639,7 @@ static int __devinit tulip_init_one (struct pci_dev *pdev, if (eeprom_missing) printk(" EEPROM not present,"); - for (i = 0; i < 6; i++) - printk("%c%2.2X", i ? ':' : ' ', dev->dev_addr[i]); + printk(" %s", print_mac(mac, dev->dev_addr)); printk(", IRQ %d.\n", irq); if (tp->chip_id == PNIC2) diff --git a/drivers/net/tulip/uli526x.c b/drivers/net/tulip/uli526x.c index 2b7257d97c32..a4fd782bcd27 100644 --- a/drivers/net/tulip/uli526x.c +++ b/drivers/net/tulip/uli526x.c @@ -258,6 +258,7 @@ static int __devinit uli526x_init_one (struct pci_dev *pdev, struct uli526x_board_info *db; /* board information structure */ struct net_device *dev; int i, err; + DECLARE_MAC_BUF(mac); ULI526X_DBUG(0, "uli526x_init_one()", 0); @@ -372,11 +373,9 @@ static int __devinit uli526x_init_one (struct pci_dev *pdev, if (err) goto err_out_res; - printk(KERN_INFO "%s: ULi M%04lx at pci%s,",dev->name,ent->driver_data >> 16,pci_name(pdev)); - - for (i = 0; i < 6; i++) - printk("%c%02x", i ? ':' : ' ', dev->dev_addr[i]); - printk(", irq %d.\n", dev->irq); + printk(KERN_INFO "%s: ULi M%04lx at pci%s, %s, irq %d.\n", + dev->name,ent->driver_data >> 16,pci_name(pdev), + print_mac(mac, dev->dev_addr), dev->irq); pci_set_master(pdev); diff --git a/drivers/net/tulip/winbond-840.c b/drivers/net/tulip/winbond-840.c index e00833fadc0b..3c40dd6e1a2f 100644 --- a/drivers/net/tulip/winbond-840.c +++ b/drivers/net/tulip/winbond-840.c @@ -354,6 +354,7 @@ static int __devinit w840_probe1 (struct pci_dev *pdev, int irq; int i, option = find_cnt < MAX_UNITS ? options[find_cnt] : 0; void __iomem *ioaddr; + DECLARE_MAC_BUF(mac); i = pci_enable_device(pdev); if (i) return i; @@ -433,11 +434,9 @@ static int __devinit w840_probe1 (struct pci_dev *pdev, if (i) goto err_out_cleardev; - printk(KERN_INFO "%s: %s at %p, ", - dev->name, pci_id_tbl[chip_idx].name, ioaddr); - for (i = 0; i < 5; i++) - printk("%2.2x:", dev->dev_addr[i]); - printk("%2.2x, IRQ %d.\n", dev->dev_addr[i], irq); + printk(KERN_INFO "%s: %s at %p, %s, IRQ %d.\n", + dev->name, pci_id_tbl[chip_idx].name, ioaddr, + print_mac(mac, dev->dev_addr), irq); if (np->drv_flags & CanHaveMII) { int phy, phy_idx = 0; @@ -1245,16 +1244,16 @@ static int netdev_rx(struct net_device *dev) } #ifndef final_version /* Remove after testing. */ /* You will want this info for the initial debug. */ - if (debug > 5) - printk(KERN_DEBUG " Rx data %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:" - "%2.2x %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x %2.2x%2.2x " - "%d.%d.%d.%d.\n", - skb->data[0], skb->data[1], skb->data[2], skb->data[3], - skb->data[4], skb->data[5], skb->data[6], skb->data[7], - skb->data[8], skb->data[9], skb->data[10], - skb->data[11], skb->data[12], skb->data[13], - skb->data[14], skb->data[15], skb->data[16], - skb->data[17]); + if (debug > 5) { + DECLARE_MAC_BUF(mac); + DECLARE_MAC_BUF(mac2); + + printk(KERN_DEBUG " Rx data %s %s" + " %2.2x%2.2x %d.%d.%d.%d.\n", + print_mac(mac, &skb->data[0]), print_mac(mac2, &skb->data[6]), + skb->data[12], skb->data[13], + skb->data[14], skb->data[15], skb->data[16], skb->data[17]); + } #endif skb->protocol = eth_type_trans(skb, dev); netif_rx(skb); diff --git a/drivers/net/tulip/xircom_cb.c b/drivers/net/tulip/xircom_cb.c index de8c92083e92..70befe33e454 100644 --- a/drivers/net/tulip/xircom_cb.c +++ b/drivers/net/tulip/xircom_cb.c @@ -1074,6 +1074,7 @@ static void read_mac_address(struct xircom_private *card) unsigned char j, tuple, link, data_id, data_count; unsigned long flags; int i; + DECLARE_MAC_BUF(mac); enter("read_mac_address"); @@ -1103,11 +1104,7 @@ static void read_mac_address(struct xircom_private *card) } } spin_unlock_irqrestore(&card->lock, flags); -#ifdef DEBUG - for (i = 0; i < 6; i++) - printk("%c%2.2X", i ? ':' : ' ', card->dev->dev_addr[i]); - printk("\n"); -#endif + pr_debug(" %s\n", print_mac(mac, card->dev->dev_addr)); leave("read_mac_address"); } diff --git a/drivers/net/tun.c b/drivers/net/tun.c index d8b8e68ef70b..1f7644695976 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c @@ -159,16 +159,15 @@ tun_net_mclist(struct net_device *dev) struct tun_struct *tun = netdev_priv(dev); const struct dev_mc_list *mclist; int i; + DECLARE_MAC_BUF(mac); DBG(KERN_DEBUG "%s: tun_net_mclist: mc_count %d\n", dev->name, dev->mc_count); memset(tun->chr_filter, 0, sizeof tun->chr_filter); for (i = 0, mclist = dev->mc_list; i < dev->mc_count && mclist != NULL; i++, mclist = mclist->next) { add_multi(tun->net_filter, mclist->dmi_addr); - DBG(KERN_DEBUG "%s: tun_net_mclist: %x:%x:%x:%x:%x:%x\n", - dev->name, - mclist->dmi_addr[0], mclist->dmi_addr[1], mclist->dmi_addr[2], - mclist->dmi_addr[3], mclist->dmi_addr[4], mclist->dmi_addr[5]); + DBG(KERN_DEBUG "%s: tun_net_mclist: %s\n", + dev->name, print_mac(mac, mclist->dmi_addr)); } } @@ -358,6 +357,7 @@ static ssize_t tun_chr_aio_read(struct kiocb *iocb, const struct iovec *iv, DECLARE_WAITQUEUE(wait, current); struct sk_buff *skb; ssize_t len, ret = 0; + DECLARE_MAC_BUF(mac); if (!tun) return -EBADFD; @@ -412,16 +412,14 @@ static ssize_t tun_chr_aio_read(struct kiocb *iocb, const struct iovec *iv, (addr[0] == 0x33 && addr[1] == 0x33)) && ((tun->if_flags & IFF_ALLMULTI) || (tun->chr_filter[bit_nr >> 5] & (1 << (bit_nr & 31)))))) { - DBG(KERN_DEBUG "%s: tun_chr_readv: accepted: %x:%x:%x:%x:%x:%x\n", - tun->dev->name, addr[0], addr[1], addr[2], - addr[3], addr[4], addr[5]); + DBG(KERN_DEBUG "%s: tun_chr_readv: accepted: %s\n", + tun->dev->name, print_mac(mac, addr)); ret = tun_put_user(tun, skb, (struct iovec *) iv, len); kfree_skb(skb); break; } else { - DBG(KERN_DEBUG "%s: tun_chr_readv: rejected: %x:%x:%x:%x:%x:%x\n", - tun->dev->name, addr[0], addr[1], addr[2], - addr[3], addr[4], addr[5]); + DBG(KERN_DEBUG "%s: tun_chr_readv: rejected: %s\n", + tun->dev->name, print_mac(mac, addr)); kfree_skb(skb); continue; } @@ -564,6 +562,7 @@ static int tun_chr_ioctl(struct inode *inode, struct file *file, struct tun_struct *tun = file->private_data; void __user* argp = (void __user*)arg; struct ifreq ifr; + DECLARE_MAC_BUF(mac); if (cmd == TUNSETIFF || _IOC_TYPE(cmd) == 0x89) if (copy_from_user(&ifr, argp, sizeof ifr)) @@ -692,22 +691,16 @@ static int tun_chr_ioctl(struct inode *inode, struct file *file, /** Add the specified group to the character device's multicast filter * list. */ add_multi(tun->chr_filter, ifr.ifr_hwaddr.sa_data); - DBG(KERN_DEBUG "%s: add multi: %x:%x:%x:%x:%x:%x\n", - tun->dev->name, - (u8)ifr.ifr_hwaddr.sa_data[0], (u8)ifr.ifr_hwaddr.sa_data[1], - (u8)ifr.ifr_hwaddr.sa_data[2], (u8)ifr.ifr_hwaddr.sa_data[3], - (u8)ifr.ifr_hwaddr.sa_data[4], (u8)ifr.ifr_hwaddr.sa_data[5]); + DBG(KERN_DEBUG "%s: add multi: %s\n", + tun->dev->name, print_mac(mac, ifr.ifr_hwaddr.sa_data)); return 0; case SIOCDELMULTI: /** Remove the specified group from the character device's multicast * filter list. */ del_multi(tun->chr_filter, ifr.ifr_hwaddr.sa_data); - DBG(KERN_DEBUG "%s: del multi: %x:%x:%x:%x:%x:%x\n", - tun->dev->name, - (u8)ifr.ifr_hwaddr.sa_data[0], (u8)ifr.ifr_hwaddr.sa_data[1], - (u8)ifr.ifr_hwaddr.sa_data[2], (u8)ifr.ifr_hwaddr.sa_data[3], - (u8)ifr.ifr_hwaddr.sa_data[4], (u8)ifr.ifr_hwaddr.sa_data[5]); + DBG(KERN_DEBUG "%s: del multi: %s\n", + tun->dev->name, print_mac(mac, ifr.ifr_hwaddr.sa_data)); return 0; default: diff --git a/drivers/net/typhoon.c b/drivers/net/typhoon.c index c6d8513ecad6..43894e95fcb3 100644 --- a/drivers/net/typhoon.c +++ b/drivers/net/typhoon.c @@ -2316,8 +2316,8 @@ typhoon_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) dma_addr_t shared_dma; struct cmd_desc xp_cmd; struct resp_desc xp_resp[3]; - int i; int err = 0; + DECLARE_MAC_BUF(mac); if(!did_version++) printk(KERN_INFO "%s", version); @@ -2532,13 +2532,11 @@ typhoon_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) pci_set_drvdata(pdev, dev); - printk(KERN_INFO "%s: %s at %s 0x%llx, ", + printk(KERN_INFO "%s: %s at %s 0x%llx, %s\n", dev->name, typhoon_card_info[card_id].name, use_mmio ? "MMIO" : "IO", - (unsigned long long)pci_resource_start(pdev, use_mmio)); - for(i = 0; i < 5; i++) - printk("%2.2x:", dev->dev_addr[i]); - printk("%2.2x\n", dev->dev_addr[i]); + (unsigned long long)pci_resource_start(pdev, use_mmio), + print_mac(mac, dev->dev_addr)); /* xp_resp still contains the response to the READ_VERSIONS command. * For debugging, let the user know what version he has. diff --git a/drivers/net/usb/pegasus.c b/drivers/net/usb/pegasus.c index 432a2f054468..d1ed68a11e70 100644 --- a/drivers/net/usb/pegasus.c +++ b/drivers/net/usb/pegasus.c @@ -1297,6 +1297,7 @@ static int pegasus_probe(struct usb_interface *intf, pegasus_t *pegasus; int dev_index = id - pegasus_ids; int res = -ENOMEM; + DECLARE_MAC_BUF(mac); usb_get_dev(dev); net = alloc_etherdev(sizeof(struct pegasus)); @@ -1367,12 +1368,10 @@ static int pegasus_probe(struct usb_interface *intf, queue_delayed_work(pegasus_workqueue, &pegasus->carrier_check, CARRIER_CHECK_DELAY); - dev_info(&intf->dev, "%s, %s, %02x:%02x:%02x:%02x:%02x:%02x\n", - net->name, - usb_dev_id[dev_index].name, - net->dev_addr [0], net->dev_addr [1], - net->dev_addr [2], net->dev_addr [3], - net->dev_addr [4], net->dev_addr [5]); + dev_info(&intf->dev, "%s, %s, %s\n", + net->name, + usb_dev_id[dev_index].name, + print_mac(mac, net->dev_addr)); return 0; out3: diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c index 3542ca5fb0fa..acd5f1c0e63a 100644 --- a/drivers/net/usb/usbnet.c +++ b/drivers/net/usb/usbnet.c @@ -1134,6 +1134,7 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod) struct usb_device *xdev; int status; const char *name; + DECLARE_MAC_BUF(mac); name = udev->dev.driver->name; info = (struct driver_info *) prod->driver_info; @@ -1241,14 +1242,11 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod) if (status) goto out3; if (netif_msg_probe (dev)) - devinfo (dev, "register '%s' at usb-%s-%s, %s, " - "%02x:%02x:%02x:%02x:%02x:%02x", + devinfo (dev, "register '%s' at usb-%s-%s, %s, %s", udev->dev.driver->name, xdev->bus->bus_name, xdev->devpath, dev->driver_info->description, - net->dev_addr [0], net->dev_addr [1], - net->dev_addr [2], net->dev_addr [3], - net->dev_addr [4], net->dev_addr [5]); + print_mac(mac, net->dev_addr)); // ok, it's ready to go. usb_set_intfdata (udev, dev); diff --git a/drivers/net/via-rhine.c b/drivers/net/via-rhine.c index d55c4fdff489..9669bce0fd07 100644 --- a/drivers/net/via-rhine.c +++ b/drivers/net/via-rhine.c @@ -638,6 +638,7 @@ static int __devinit rhine_init_one(struct pci_dev *pdev, #else int bar = 0; #endif + DECLARE_MAC_BUF(mac); /* when built into the kernel, we only print version if device is found */ #ifndef MODULE @@ -794,18 +795,14 @@ static int __devinit rhine_init_one(struct pci_dev *pdev, if (rc) goto err_out_unmap; - printk(KERN_INFO "%s: VIA %s at 0x%lx, ", + printk(KERN_INFO "%s: VIA %s at 0x%lx, %s, IRQ %d.\n", dev->name, name, #ifdef USE_MMIO - memaddr + memaddr, #else - (long)ioaddr + (long)ioaddr, #endif - ); - - for (i = 0; i < 5; i++) - printk("%2.2x:", dev->dev_addr[i]); - printk("%2.2x, IRQ %d.\n", dev->dev_addr[i], pdev->irq); + print_mac(mac, dev->dev_addr), pdev->irq); pci_set_drvdata(pdev, dev); diff --git a/drivers/net/wd.c b/drivers/net/wd.c index cef365881ac2..fa14255282af 100644 --- a/drivers/net/wd.c +++ b/drivers/net/wd.c @@ -156,6 +156,7 @@ static int __init wd_probe1(struct net_device *dev, int ioaddr) int word16 = 0; /* 0 = 8 bit, 1 = 16 bit */ const char *model_name; static unsigned version_printed; + DECLARE_MAC_BUF(mac); for (i = 0; i < 8; i++) checksum += inb(ioaddr + 8 + i); @@ -174,9 +175,11 @@ static int __init wd_probe1(struct net_device *dev, int ioaddr) if (ei_debug && version_printed++ == 0) printk(version); - printk("%s: WD80x3 at %#3x,", dev->name, ioaddr); for (i = 0; i < 6; i++) - printk(" %2.2X", dev->dev_addr[i] = inb(ioaddr + 8 + i)); + dev->dev_addr[i] = inb(ioaddr + 8 + i); + + printk("%s: WD80x3 at %#3x, %s", + dev->name, ioaddr, print_mac(mac, dev->dev_addr)); /* The following PureData probe code was contributed by Mike Jagdis . Puredata does software diff --git a/drivers/net/wireless/adm8211.c b/drivers/net/wireless/adm8211.c index eec01fc15282..ac2ea237019d 100644 --- a/drivers/net/wireless/adm8211.c +++ b/drivers/net/wireless/adm8211.c @@ -1787,6 +1787,7 @@ static int __devinit adm8211_probe(struct pci_dev *pdev, int err; u32 reg; u8 perm_addr[ETH_ALEN]; + DECLARE_MAC_BUF(mac); #ifndef MODULE static unsigned int cardidx; @@ -1938,8 +1939,8 @@ static int __devinit adm8211_probe(struct pci_dev *pdev, goto err_free_desc; } - printk(KERN_INFO "%s: hwaddr " MAC_FMT ", Rev 0x%02x\n", - wiphy_name(dev->wiphy), MAC_ARG(dev->wiphy->perm_addr), + printk(KERN_INFO "%s: hwaddr %s, Rev 0x%02x\n", + wiphy_name(dev->wiphy), print_mac(mac, dev->wiphy->perm_addr), priv->revid); return 0; diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c index 7d717c4d9845..95d3cd1c49a7 100644 --- a/drivers/net/wireless/airo.c +++ b/drivers/net/wireless/airo.c @@ -2821,6 +2821,7 @@ static struct net_device *_init_airo_card( unsigned short irq, int port, struct net_device *dev; struct airo_info *ai; int i, rc; + DECLARE_MAC_BUF(mac); /* Create the network device object. */ dev = alloc_netdev(sizeof(*ai), "", ether_setup); @@ -2923,9 +2924,8 @@ static struct net_device *_init_airo_card( unsigned short irq, int port, goto err_out_reg; set_bit(FLAG_REGISTERED,&ai->flags); - airo_print_info(dev->name, "MAC enabled %x:%x:%x:%x:%x:%x", - dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2], - dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5] ); + airo_print_info(dev->name, "MAC enabled %s", + print_mac(mac, dev->dev_addr)); /* Allocate the transmit buffers */ if (probe && !test_bit(FLAG_MPI,&ai->flags)) @@ -2982,6 +2982,7 @@ int reset_airo_card( struct net_device *dev ) { int i; struct airo_info *ai = dev->priv; + DECLARE_MAC_BUF(mac); if (reset_card (dev, 1)) return -1; @@ -2990,9 +2991,8 @@ int reset_airo_card( struct net_device *dev ) airo_print_err(dev->name, "MAC could not be enabled"); return -1; } - airo_print_info(dev->name, "MAC enabled %x:%x:%x:%x:%x:%x", - dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2], - dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]); + airo_print_info(dev->name, "MAC enabled %s", + print_mac(mac, dev->dev_addr)); /* Allocate the transmit buffers if needed */ if (!test_bit(FLAG_MPI,&ai->flags)) for( i = 0; i < MAX_FIDS; i++ ) @@ -5426,6 +5426,7 @@ static int proc_APList_open( struct inode *inode, struct file *file ) { int i; char *ptr; APListRid APList_rid; + DECLARE_MAC_BUF(mac); if ((file->private_data = kzalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL) return -ENOMEM; @@ -5449,13 +5450,8 @@ static int proc_APList_open( struct inode *inode, struct file *file ) { // We end when we find a zero MAC if ( !*(int*)APList_rid.ap[i] && !*(int*)&APList_rid.ap[i][2]) break; - ptr += sprintf(ptr, "%02x:%02x:%02x:%02x:%02x:%02x\n", - (int)APList_rid.ap[i][0], - (int)APList_rid.ap[i][1], - (int)APList_rid.ap[i][2], - (int)APList_rid.ap[i][3], - (int)APList_rid.ap[i][4], - (int)APList_rid.ap[i][5]); + ptr += sprintf(ptr, "%s\n", + print_mac(mac, APList_rid.ap[i])); } if (i==0) ptr += sprintf(ptr, "Not using specific APs\n"); @@ -5474,6 +5470,7 @@ static int proc_BSSList_open( struct inode *inode, struct file *file ) { int rc; /* If doLoseSync is not 1, we won't do a Lose Sync */ int doLoseSync = -1; + DECLARE_MAC_BUF(mac); if ((file->private_data = kzalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL) return -ENOMEM; @@ -5510,13 +5507,8 @@ static int proc_BSSList_open( struct inode *inode, struct file *file ) { we have to add a spin lock... */ rc = readBSSListRid(ai, doLoseSync, &BSSList_rid); while(rc == 0 && BSSList_rid.index != 0xffff) { - ptr += sprintf(ptr, "%02x:%02x:%02x:%02x:%02x:%02x %*s rssi = %d", - (int)BSSList_rid.bssid[0], - (int)BSSList_rid.bssid[1], - (int)BSSList_rid.bssid[2], - (int)BSSList_rid.bssid[3], - (int)BSSList_rid.bssid[4], - (int)BSSList_rid.bssid[5], + ptr += sprintf(ptr, "%s %*s rssi = %d", + print_mac(mac, BSSList_rid.bssid), (int)BSSList_rid.ssidLen, BSSList_rid.ssid, (int)BSSList_rid.dBm); diff --git a/drivers/net/wireless/arlan-main.c b/drivers/net/wireless/arlan-main.c index 3eaaab0ba0cc..dbdfc9e39d20 100644 --- a/drivers/net/wireless/arlan-main.c +++ b/drivers/net/wireless/arlan-main.c @@ -1469,10 +1469,10 @@ static void arlan_rx_interrupt(struct net_device *dev, u_char rxStatus, u_short while (dmi) { if (dmi->dmi_addrlen == 6) { + DECLARE_MAC_BUF(mac); if (arlan_debug & ARLAN_DEBUG_HEADER_DUMP) - printk(KERN_ERR "%s mcl %2x:%2x:%2x:%2x:%2x:%2x \n", dev->name, - dmi->dmi_addr[0], dmi->dmi_addr[1], dmi->dmi_addr[2], - dmi->dmi_addr[3], dmi->dmi_addr[4], dmi->dmi_addr[5]); + printk(KERN_ERR "%s mcl %s\n", + dev->name, print_mac(mac, dmi->dmi_addr)); for (i = 0; i < 6; i++) if (dmi->dmi_addr[i] != hw_dst_addr[i]) break; @@ -1512,17 +1512,18 @@ static void arlan_rx_interrupt(struct net_device *dev, u_char rxStatus, u_short { char immedDestAddress[6]; char immedSrcAddress[6]; + DECLARE_MAC_BUF(mac); + DECLARE_MAC_BUF(mac2); + DECLARE_MAC_BUF(mac3); + DECLARE_MAC_BUF(mac4); memcpy_fromio(immedDestAddress, arlan->immedDestAddress, 6); memcpy_fromio(immedSrcAddress, arlan->immedSrcAddress, 6); - printk(KERN_WARNING "%s t %2x:%2x:%2x:%2x:%2x:%2x f %2x:%2x:%2x:%2x:%2x:%2x imd %2x:%2x:%2x:%2x:%2x:%2x ims %2x:%2x:%2x:%2x:%2x:%2x\n", dev->name, - (unsigned char) skbtmp[0], (unsigned char) skbtmp[1], (unsigned char) skbtmp[2], (unsigned char) skbtmp[3], - (unsigned char) skbtmp[4], (unsigned char) skbtmp[5], (unsigned char) skbtmp[6], (unsigned char) skbtmp[7], - (unsigned char) skbtmp[8], (unsigned char) skbtmp[9], (unsigned char) skbtmp[10], (unsigned char) skbtmp[11], - immedDestAddress[0], immedDestAddress[1], immedDestAddress[2], - immedDestAddress[3], immedDestAddress[4], immedDestAddress[5], - immedSrcAddress[0], immedSrcAddress[1], immedSrcAddress[2], - immedSrcAddress[3], immedSrcAddress[4], immedSrcAddress[5]); + printk(KERN_WARNING "%s t %s f %s imd %s ims %s\n", + dev->name, print_mac(mac, skbtmp), + print_mac(mac2, &skbtmp[6]), + print_mac(mac3, immedDestAddress), + print_mac(mac4, immedSrcAddress)); } skb->protocol = eth_type_trans(skb, dev); IFDEBUG(ARLAN_DEBUG_HEADER_DUMP) diff --git a/drivers/net/wireless/atmel.c b/drivers/net/wireless/atmel.c index 47dbdf95ea6f..059ce3f07dba 100644 --- a/drivers/net/wireless/atmel.c +++ b/drivers/net/wireless/atmel.c @@ -1484,6 +1484,7 @@ struct net_device *init_atmel_card(unsigned short irq, unsigned long port, struct net_device *dev; struct atmel_private *priv; int rc; + DECLARE_MAC_BUF(mac); /* Create the network device object. */ dev = alloc_etherdev(sizeof(*priv)); @@ -1598,10 +1599,8 @@ struct net_device *init_atmel_card(unsigned short irq, unsigned long port, if (!ent) printk(KERN_WARNING "atmel: unable to create /proc entry.\n"); - printk(KERN_INFO "%s: Atmel at76c50x. Version %d.%d. MAC %.2x:%.2x:%.2x:%.2x:%.2x:%.2x\n", - dev->name, DRIVER_MAJOR, DRIVER_MINOR, - dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2], - dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5] ); + printk(KERN_INFO "%s: Atmel at76c50x. Version %d.%d. MAC %s\n", + dev->name, DRIVER_MAJOR, DRIVER_MINOR, print_mac(mac, dev->dev_addr)); return dev; diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index 184ebe3ed738..fd4ef27fcf25 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c @@ -2883,6 +2883,7 @@ static int b43_dev_set_key(struct ieee80211_hw *hw, u8 algorithm; u8 index; int err = -EINVAL; + DECLARE_MAC_BUF(mac); if (modparam_nohwcrypt) return -ENOSPC; /* User disabled HW-crypto */ @@ -2969,9 +2970,9 @@ out_unlock: out: if (!err) { b43dbg(wl, "%s hardware based encryption for keyidx: %d, " - "mac: " MAC_FMT "\n", + "mac: %s\n", cmd == SET_KEY ? "Using" : "Disabling", key->keyidx, - MAC_ARG(addr)); + print_mac(mac, addr)); } return err; } diff --git a/drivers/net/wireless/b43legacy/main.c b/drivers/net/wireless/b43legacy/main.c index ac4831adb574..61b94218094b 100644 --- a/drivers/net/wireless/b43legacy/main.c +++ b/drivers/net/wireless/b43legacy/main.c @@ -2679,6 +2679,7 @@ static int b43legacy_dev_set_key(struct ieee80211_hw *hw, struct b43legacy_wldev *dev = wl->current_dev; unsigned long flags; int err = -EOPNOTSUPP; + DECLARE_MAC_BUF(mac); if (!dev) return -ENODEV; @@ -2691,7 +2692,7 @@ static int b43legacy_dev_set_key(struct ieee80211_hw *hw, spin_unlock_irqrestore(&wl->irq_lock, flags); mutex_unlock(&wl->mutex); b43legacydbg(wl, "Using software based encryption for " - "mac: " MAC_FMT "\n", MAC_ARG(addr)); + "mac: %s\n", print_mac(mac, addr)); return err; } diff --git a/drivers/net/wireless/bcm43xx/bcm43xx.h b/drivers/net/wireless/bcm43xx/bcm43xx.h index 10e07e865426..5fdbf24d2443 100644 --- a/drivers/net/wireless/bcm43xx/bcm43xx.h +++ b/drivers/net/wireless/bcm43xx/bcm43xx.h @@ -994,10 +994,4 @@ int bcm43xx_pci_write_config32(struct bcm43xx_private *bcm, int offset, u32 valu __value; \ }) -/** Helpers to print MAC addresses. */ -#define BCM43xx_MACFMT "%02x:%02x:%02x:%02x:%02x:%02x" -#define BCM43xx_MACARG(x) ((u8*)(x))[0], ((u8*)(x))[1], \ - ((u8*)(x))[2], ((u8*)(x))[3], \ - ((u8*)(x))[4], ((u8*)(x))[5] - #endif /* BCM43xx_H_ */ diff --git a/drivers/net/wireless/hostap/hostap_80211_rx.c b/drivers/net/wireless/hostap/hostap_80211_rx.c index cbedc9ee740a..ef084df3d48e 100644 --- a/drivers/net/wireless/hostap/hostap_80211_rx.c +++ b/drivers/net/wireless/hostap/hostap_80211_rx.c @@ -19,6 +19,7 @@ void hostap_dump_rx_80211(const char *name, struct sk_buff *skb, { struct ieee80211_hdr_4addr *hdr; u16 fc; + DECLARE_MAC_BUF(mac); hdr = (struct ieee80211_hdr_4addr *) skb->data; @@ -44,10 +45,11 @@ void hostap_dump_rx_80211(const char *name, struct sk_buff *skb, printk(" dur=0x%04x seq=0x%04x\n", le16_to_cpu(hdr->duration_id), le16_to_cpu(hdr->seq_ctl)); - printk(KERN_DEBUG " A1=" MACSTR " A2=" MACSTR " A3=" MACSTR, - MAC2STR(hdr->addr1), MAC2STR(hdr->addr2), MAC2STR(hdr->addr3)); + printk(KERN_DEBUG " A1=%s", print_mac(mac, hdr->addr1)); + printk(" A2=%s", print_mac(mac, hdr->addr2)); + printk(" A3=%s", print_mac(mac, hdr->addr3)); if (skb->len >= 30) - printk(" A4=" MACSTR, MAC2STR(hdr->addr4)); + printk(" A4=%s", print_mac(mac, hdr->addr4)); printk("\n"); } @@ -534,6 +536,7 @@ static int hostap_rx_frame_wds(local_info_t *local, struct ieee80211_hdr_4addr *hdr, u16 fc, struct net_device **wds) { + DECLARE_MAC_BUF(mac); /* FIX: is this really supposed to accept WDS frames only in Master * mode? What about Repeater or Managed with WDS frames? */ if ((fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) != @@ -549,10 +552,10 @@ hostap_rx_frame_wds(local_info_t *local, struct ieee80211_hdr_4addr *hdr, hdr->addr1[4] != 0xff || hdr->addr1[5] != 0xff)) { /* RA (or BSSID) is not ours - drop */ PDEBUG(DEBUG_EXTRA, "%s: received WDS frame with " - "not own or broadcast %s=" MACSTR "\n", + "not own or broadcast %s=%s\n", local->dev->name, fc & IEEE80211_FCTL_FROMDS ? "RA" : "BSSID", - MAC2STR(hdr->addr1)); + print_mac(mac, hdr->addr1)); return -1; } @@ -565,8 +568,8 @@ hostap_rx_frame_wds(local_info_t *local, struct ieee80211_hdr_4addr *hdr, /* require that WDS link has been registered with TA or the * frame is from current AP when using 'AP client mode' */ PDEBUG(DEBUG_EXTRA, "%s: received WDS[4 addr] frame " - "from unknown TA=" MACSTR "\n", - local->dev->name, MAC2STR(hdr->addr2)); + "from unknown TA=%s\n", + local->dev->name, print_mac(mac, hdr->addr2)); if (local->ap && local->ap->autom_ap_wds) hostap_wds_link_oper(local, hdr->addr2, WDS_ADD); return -1; @@ -632,6 +635,7 @@ hostap_rx_frame_decrypt(local_info_t *local, struct sk_buff *skb, { struct ieee80211_hdr_4addr *hdr; int res, hdrlen; + DECLARE_MAC_BUF(mac); if (crypt == NULL || crypt->ops->decrypt_mpdu == NULL) return 0; @@ -643,8 +647,8 @@ hostap_rx_frame_decrypt(local_info_t *local, struct sk_buff *skb, strcmp(crypt->ops->name, "TKIP") == 0) { if (net_ratelimit()) { printk(KERN_DEBUG "%s: TKIP countermeasures: dropped " - "received packet from " MACSTR "\n", - local->dev->name, MAC2STR(hdr->addr2)); + "received packet from %s\n", + local->dev->name, print_mac(mac, hdr->addr2)); } return -1; } @@ -653,9 +657,9 @@ hostap_rx_frame_decrypt(local_info_t *local, struct sk_buff *skb, res = crypt->ops->decrypt_mpdu(skb, hdrlen, crypt->priv); atomic_dec(&crypt->refcnt); if (res < 0) { - printk(KERN_DEBUG "%s: decryption failed (SA=" MACSTR + printk(KERN_DEBUG "%s: decryption failed (SA=%s" ") res=%d\n", - local->dev->name, MAC2STR(hdr->addr2), res); + local->dev->name, print_mac(mac, hdr->addr2), res); local->comm_tallies.rx_discards_wep_undecryptable++; return -1; } @@ -671,6 +675,7 @@ hostap_rx_frame_decrypt_msdu(local_info_t *local, struct sk_buff *skb, { struct ieee80211_hdr_4addr *hdr; int res, hdrlen; + DECLARE_MAC_BUF(mac); if (crypt == NULL || crypt->ops->decrypt_msdu == NULL) return 0; @@ -683,8 +688,8 @@ hostap_rx_frame_decrypt_msdu(local_info_t *local, struct sk_buff *skb, atomic_dec(&crypt->refcnt); if (res < 0) { printk(KERN_DEBUG "%s: MSDU decryption/MIC verification failed" - " (SA=" MACSTR " keyidx=%d)\n", - local->dev->name, MAC2STR(hdr->addr2), keyidx); + " (SA=%s keyidx=%d)\n", + local->dev->name, print_mac(mac, hdr->addr2), keyidx); return -1; } @@ -716,6 +721,7 @@ void hostap_80211_rx(struct net_device *dev, struct sk_buff *skb, struct ieee80211_crypt_data *crypt = NULL; void *sta = NULL; int keyidx = 0; + DECLARE_MAC_BUF(mac); iface = netdev_priv(dev); local = iface->local; @@ -792,8 +798,8 @@ void hostap_80211_rx(struct net_device *dev, struct sk_buff *skb, * frames silently instead of filling system log with * these reports. */ printk(KERN_DEBUG "%s: WEP decryption failed (not set)" - " (SA=" MACSTR ")\n", - local->dev->name, MAC2STR(hdr->addr2)); + " (SA=%s)\n", + local->dev->name, print_mac(mac, hdr->addr2)); #endif local->comm_tallies.rx_discards_wep_undecryptable++; goto rx_dropped; @@ -807,8 +813,8 @@ void hostap_80211_rx(struct net_device *dev, struct sk_buff *skb, (keyidx = hostap_rx_frame_decrypt(local, skb, crypt)) < 0) { printk(KERN_DEBUG "%s: failed to decrypt mgmt::auth " - "from " MACSTR "\n", dev->name, - MAC2STR(hdr->addr2)); + "from %s\n", dev->name, + print_mac(mac, hdr->addr2)); /* TODO: could inform hostapd about this so that it * could send auth failure report */ goto rx_dropped; @@ -976,8 +982,8 @@ void hostap_80211_rx(struct net_device *dev, struct sk_buff *skb, "unencrypted EAPOL frame\n", local->dev->name); } else { printk(KERN_DEBUG "%s: encryption configured, but RX " - "frame not encrypted (SA=" MACSTR ")\n", - local->dev->name, MAC2STR(hdr->addr2)); + "frame not encrypted (SA=%s)\n", + local->dev->name, print_mac(mac, hdr->addr2)); goto rx_dropped; } } @@ -986,8 +992,9 @@ void hostap_80211_rx(struct net_device *dev, struct sk_buff *skb, !hostap_is_eapol_frame(local, skb)) { if (net_ratelimit()) { printk(KERN_DEBUG "%s: dropped unencrypted RX data " - "frame from " MACSTR " (drop_unencrypted=1)\n", - dev->name, MAC2STR(hdr->addr2)); + "frame from %s" + " (drop_unencrypted=1)\n", + dev->name, print_mac(mac, hdr->addr2)); } goto rx_dropped; } diff --git a/drivers/net/wireless/hostap/hostap_80211_tx.c b/drivers/net/wireless/hostap/hostap_80211_tx.c index 3df3c60263d4..e7afc3ec3e6d 100644 --- a/drivers/net/wireless/hostap/hostap_80211_tx.c +++ b/drivers/net/wireless/hostap/hostap_80211_tx.c @@ -17,6 +17,7 @@ void hostap_dump_tx_80211(const char *name, struct sk_buff *skb) { struct ieee80211_hdr_4addr *hdr; u16 fc; + DECLARE_MAC_BUF(mac); hdr = (struct ieee80211_hdr_4addr *) skb->data; @@ -40,10 +41,11 @@ void hostap_dump_tx_80211(const char *name, struct sk_buff *skb) printk(" dur=0x%04x seq=0x%04x\n", le16_to_cpu(hdr->duration_id), le16_to_cpu(hdr->seq_ctl)); - printk(KERN_DEBUG " A1=" MACSTR " A2=" MACSTR " A3=" MACSTR, - MAC2STR(hdr->addr1), MAC2STR(hdr->addr2), MAC2STR(hdr->addr3)); + printk(KERN_DEBUG " A1=%s", print_mac(mac, hdr->addr1)); + printk(" A2=%s", print_mac(mac, hdr->addr2)); + printk(" A3=%s", print_mac(mac, hdr->addr3)); if (skb->len >= 30) - printk(" A4=" MACSTR, MAC2STR(hdr->addr4)); + printk(" A4=%s", print_mac(mac, hdr->addr4)); printk("\n"); } @@ -312,6 +314,7 @@ static struct sk_buff * hostap_tx_encrypt(struct sk_buff *skb, struct ieee80211_hdr_4addr *hdr; u16 fc; int prefix_len, postfix_len, hdr_len, res; + DECLARE_MAC_BUF(mac); iface = netdev_priv(skb->dev); local = iface->local; @@ -326,8 +329,8 @@ static struct sk_buff * hostap_tx_encrypt(struct sk_buff *skb, hdr = (struct ieee80211_hdr_4addr *) skb->data; if (net_ratelimit()) { printk(KERN_DEBUG "%s: TKIP countermeasures: dropped " - "TX packet to " MACSTR "\n", - local->dev->name, MAC2STR(hdr->addr1)); + "TX packet to %s\n", + local->dev->name, print_mac(mac, hdr->addr1)); } kfree_skb(skb); return NULL; diff --git a/drivers/net/wireless/hostap/hostap_ap.c b/drivers/net/wireless/hostap/hostap_ap.c index 90900525379c..6bbdb76b32df 100644 --- a/drivers/net/wireless/hostap/hostap_ap.c +++ b/drivers/net/wireless/hostap/hostap_ap.c @@ -94,6 +94,7 @@ static void ap_sta_hash_add(struct ap_data *ap, struct sta_info *sta) static void ap_sta_hash_del(struct ap_data *ap, struct sta_info *sta) { struct sta_info *s; + DECLARE_MAC_BUF(mac); s = ap->sta_hash[STA_HASH(sta->addr)]; if (s == NULL) return; @@ -108,18 +109,20 @@ static void ap_sta_hash_del(struct ap_data *ap, struct sta_info *sta) if (s->hnext != NULL) s->hnext = s->hnext->hnext; else - printk("AP: could not remove STA " MACSTR " from hash table\n", - MAC2STR(sta->addr)); + printk("AP: could not remove STA %s" + " from hash table\n", + print_mac(mac, sta->addr)); } static void ap_free_sta(struct ap_data *ap, struct sta_info *sta) { + DECLARE_MAC_BUF(mac); if (sta->ap && sta->local) hostap_event_expired_sta(sta->local->dev, sta); if (ap->proc != NULL) { char name[20]; - sprintf(name, MACSTR, MAC2STR(sta->addr)); + sprintf(name, "%s", print_mac(mac, sta->addr)); remove_proc_entry(name, ap->proc); } @@ -182,6 +185,7 @@ static void ap_handle_timer(unsigned long data) struct ap_data *ap; unsigned long next_time = 0; int was_assoc; + DECLARE_MAC_BUF(mac); if (sta == NULL || sta->local == NULL || sta->local->ap == NULL) { PDEBUG(DEBUG_AP, "ap_handle_timer() called with NULL data\n"); @@ -238,8 +242,8 @@ static void ap_handle_timer(unsigned long data) if (sta->ap) { if (ap->autom_ap_wds) { PDEBUG(DEBUG_AP, "%s: removing automatic WDS " - "connection to AP " MACSTR "\n", - local->dev->name, MAC2STR(sta->addr)); + "connection to AP %s\n", + local->dev->name, print_mac(mac, sta->addr)); hostap_wds_link_oper(local, sta->addr, WDS_DEL); } } else if (sta->timeout_next == STA_NULLFUNC) { @@ -255,11 +259,11 @@ static void ap_handle_timer(unsigned long data) } else { int deauth = sta->timeout_next == STA_DEAUTH; u16 resp; - PDEBUG(DEBUG_AP, "%s: sending %s info to STA " MACSTR + PDEBUG(DEBUG_AP, "%s: sending %s info to STA %s" "(last=%lu, jiffies=%lu)\n", local->dev->name, deauth ? "deauthentication" : "disassociation", - MAC2STR(sta->addr), sta->last_rx, jiffies); + print_mac(mac, sta->addr), sta->last_rx, jiffies); resp = cpu_to_le16(deauth ? WLAN_REASON_PREV_AUTH_NOT_VALID : WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY); @@ -271,9 +275,10 @@ static void ap_handle_timer(unsigned long data) if (sta->timeout_next == STA_DEAUTH) { if (sta->flags & WLAN_STA_PERM) { - PDEBUG(DEBUG_AP, "%s: STA " MACSTR " would have been " - "removed, but it has 'perm' flag\n", - local->dev->name, MAC2STR(sta->addr)); + PDEBUG(DEBUG_AP, "%s: STA %s" + " would have been removed, " + "but it has 'perm' flag\n", + local->dev->name, print_mac(mac, sta->addr)); } else ap_free_sta(ap, sta); return; @@ -327,6 +332,7 @@ static int ap_control_proc_read(char *page, char **start, off_t off, struct ap_data *ap = (struct ap_data *) data; char *policy_txt; struct mac_entry *entry; + DECLARE_MAC_BUF(mac); if (off != 0) { *eof = 1; @@ -357,7 +363,7 @@ static int ap_control_proc_read(char *page, char **start, off_t off, break; } - p += sprintf(p, MACSTR "\n", MAC2STR(entry->addr)); + p += sprintf(p, "%s\n", print_mac(mac, entry->addr)); } spin_unlock_bh(&ap->mac_restrictions.lock); @@ -514,6 +520,7 @@ static int prism2_ap_proc_read(char *page, char **start, off_t off, struct ap_data *ap = (struct ap_data *) data; struct sta_info *sta; int i; + DECLARE_MAC_BUF(mac); if (off > PROC_LIMIT) { *eof = 1; @@ -526,7 +533,8 @@ static int prism2_ap_proc_read(char *page, char **start, off_t off, if (!sta->ap) continue; - p += sprintf(p, MACSTR " %d %d %d %d '", MAC2STR(sta->addr), + p += sprintf(p, "%s %d %d %d %d '", + print_mac(mac, sta->addr), sta->u.ap.channel, sta->last_rx_signal, sta->last_rx_silence, sta->last_rx_rate); for (i = 0; i < sta->u.ap.ssid_len; i++) @@ -623,6 +631,7 @@ static void hostap_ap_tx_cb_auth(struct sk_buff *skb, int ok, void *data) u16 fc, *pos, auth_alg, auth_transaction, status; struct sta_info *sta = NULL; char *txt = NULL; + DECLARE_MAC_BUF(mac); if (ap->local->hostapd) { dev_kfree_skb(skb); @@ -674,9 +683,9 @@ static void hostap_ap_tx_cb_auth(struct sk_buff *skb, int ok, void *data) if (sta) atomic_dec(&sta->users); if (txt) { - PDEBUG(DEBUG_AP, "%s: " MACSTR " auth_cb - alg=%d trans#=%d " - "status=%d - %s\n", - dev->name, MAC2STR(hdr->addr1), auth_alg, + PDEBUG(DEBUG_AP, "%s: %s auth_cb - alg=%d " + "trans#=%d status=%d - %s\n", + dev->name, print_mac(mac, hdr->addr1), auth_alg, auth_transaction, status, txt); } dev_kfree_skb(skb); @@ -692,6 +701,7 @@ static void hostap_ap_tx_cb_assoc(struct sk_buff *skb, int ok, void *data) u16 fc, *pos, status; struct sta_info *sta = NULL; char *txt = NULL; + DECLARE_MAC_BUF(mac); if (ap->local->hostapd) { dev_kfree_skb(skb); @@ -742,8 +752,8 @@ static void hostap_ap_tx_cb_assoc(struct sk_buff *skb, int ok, void *data) if (sta) atomic_dec(&sta->users); if (txt) { - PDEBUG(DEBUG_AP, "%s: " MACSTR " assoc_cb - %s\n", - dev->name, MAC2STR(hdr->addr1), txt); + PDEBUG(DEBUG_AP, "%s: %s assoc_cb - %s\n", + dev->name, print_mac(mac, hdr->addr1), txt); } dev_kfree_skb(skb); } @@ -755,6 +765,7 @@ static void hostap_ap_tx_cb_poll(struct sk_buff *skb, int ok, void *data) struct ap_data *ap = data; struct ieee80211_hdr_4addr *hdr; struct sta_info *sta; + DECLARE_MAC_BUF(mac); if (skb->len < 24) goto fail; @@ -766,9 +777,9 @@ static void hostap_ap_tx_cb_poll(struct sk_buff *skb, int ok, void *data) sta->flags &= ~WLAN_STA_PENDING_POLL; spin_unlock(&ap->sta_table_lock); } else { - PDEBUG(DEBUG_AP, "%s: STA " MACSTR " did not ACK activity " - "poll frame\n", ap->local->dev->name, - MAC2STR(hdr->addr1)); + PDEBUG(DEBUG_AP, "%s: STA %s" + " did not ACK activity poll frame\n", + ap->local->dev->name, print_mac(mac, hdr->addr1)); } fail: @@ -985,6 +996,7 @@ static int prism2_sta_proc_read(char *page, char **start, off_t off, char *p = page; struct sta_info *sta = (struct sta_info *) data; int i; + DECLARE_MAC_BUF(mac); /* FIX: possible race condition.. the STA data could have just expired, * but proc entry was still here so that the read could have started; @@ -995,11 +1007,11 @@ static int prism2_sta_proc_read(char *page, char **start, off_t off, return 0; } - p += sprintf(p, "%s=" MACSTR "\nusers=%d\naid=%d\n" + p += sprintf(p, "%s=%s\nusers=%d\naid=%d\n" "flags=0x%04x%s%s%s%s%s%s%s\n" "capability=0x%02x\nlisten_interval=%d\nsupported_rates=", sta->ap ? "AP" : "STA", - MAC2STR(sta->addr), atomic_read(&sta->users), sta->aid, + print_mac(mac, sta->addr), atomic_read(&sta->users), sta->aid, sta->flags, sta->flags & WLAN_STA_AUTH ? " AUTH" : "", sta->flags & WLAN_STA_ASSOC ? " ASSOC" : "", @@ -1060,6 +1072,7 @@ static void handle_add_proc_queue(struct work_struct *work) struct sta_info *sta; char name[20]; struct add_sta_proc_data *entry, *prev; + DECLARE_MAC_BUF(mac); entry = ap->add_sta_proc_entries; ap->add_sta_proc_entries = NULL; @@ -1072,7 +1085,7 @@ static void handle_add_proc_queue(struct work_struct *work) spin_unlock_bh(&ap->sta_table_lock); if (sta) { - sprintf(name, MACSTR, MAC2STR(sta->addr)); + sprintf(name, "%s", print_mac(mac, sta->addr)); sta->proc = create_proc_read_entry( name, 0, ap->proc, prism2_sta_proc_read, sta); @@ -1290,6 +1303,7 @@ static void handle_authen(local_info_t *local, struct sk_buff *skb, struct sta_info *sta = NULL; struct ieee80211_crypt_data *crypt; char *txt = ""; + DECLARE_MAC_BUF(mac); len = skb->len - IEEE80211_MGMT_HDR_LEN; @@ -1298,8 +1312,8 @@ static void handle_authen(local_info_t *local, struct sk_buff *skb, if (len < 6) { PDEBUG(DEBUG_AP, "%s: handle_authen - too short payload " - "(len=%d) from " MACSTR "\n", dev->name, len, - MAC2STR(hdr->addr2)); + "(len=%d) from %s\n", dev->name, len, + print_mac(mac, hdr->addr2)); return; } @@ -1364,8 +1378,8 @@ static void handle_authen(local_info_t *local, struct sk_buff *skb, if (time_after(jiffies, sta->u.ap.last_beacon + (10 * sta->listen_interval * HZ) / 1024)) { PDEBUG(DEBUG_AP, "%s: no beacons received for a while," - " assuming AP " MACSTR " is now STA\n", - dev->name, MAC2STR(sta->addr)); + " assuming AP %s is now STA\n", + dev->name, print_mac(mac, sta->addr)); sta->ap = 0; sta->flags = 0; sta->u.sta.challenge = NULL; @@ -1480,9 +1494,9 @@ static void handle_authen(local_info_t *local, struct sk_buff *skb, } if (resp) { - PDEBUG(DEBUG_AP, "%s: " MACSTR " auth (alg=%d trans#=%d " - "stat=%d len=%d fc=%04x) ==> %d (%s)\n", - dev->name, MAC2STR(hdr->addr2), auth_alg, + PDEBUG(DEBUG_AP, "%s: %s auth (alg=%d " + "trans#=%d stat=%d len=%d fc=%04x) ==> %d (%s)\n", + dev->name, print_mac(mac, hdr->addr2), auth_alg, auth_transaction, status_code, len, fc, resp, txt); } } @@ -1502,13 +1516,14 @@ static void handle_assoc(local_info_t *local, struct sk_buff *skb, int send_deauth = 0; char *txt = ""; u8 prev_ap[ETH_ALEN]; + DECLARE_MAC_BUF(mac); left = len = skb->len - IEEE80211_MGMT_HDR_LEN; if (len < (reassoc ? 10 : 4)) { PDEBUG(DEBUG_AP, "%s: handle_assoc - too short payload " - "(len=%d, reassoc=%d) from " MACSTR "\n", - dev->name, len, reassoc, MAC2STR(hdr->addr2)); + "(len=%d, reassoc=%d) from %s\n", + dev->name, len, reassoc, print_mac(mac, hdr->addr2)); return; } @@ -1585,9 +1600,9 @@ static void handle_assoc(local_info_t *local, struct sk_buff *skb, } if (left > 0) { - PDEBUG(DEBUG_AP, "%s: assoc from " MACSTR " with extra" - " data (%d bytes) [", - dev->name, MAC2STR(hdr->addr2), left); + PDEBUG(DEBUG_AP, "%s: assoc from %s" + " with extra data (%d bytes) [", + dev->name, print_mac(mac, hdr->addr2), left); while (left > 0) { PDEBUG2(DEBUG_AP, "<%02x>", *u); u++; left--; @@ -1687,10 +1702,10 @@ static void handle_assoc(local_info_t *local, struct sk_buff *skb, } #if 0 - PDEBUG(DEBUG_AP, "%s: " MACSTR " %sassoc (len=%d prev_ap=" MACSTR - ") => %d(%d) (%s)\n", - dev->name, MAC2STR(hdr->addr2), reassoc ? "re" : "", len, - MAC2STR(prev_ap), resp, send_deauth, txt); + PDEBUG(DEBUG_AP, "%s: %s %sassoc (len=%d " + "prev_ap=%s) => %d(%d) (%s)\n", + dev->name, print_mac(mac, hdr->addr2), reassoc ? "re" : "", len, + print_mac(mac, prev_ap), resp, send_deauth, txt); #endif } @@ -1705,6 +1720,7 @@ static void handle_deauth(local_info_t *local, struct sk_buff *skb, int len; u16 reason_code, *pos; struct sta_info *sta = NULL; + DECLARE_MAC_BUF(mac); len = skb->len - IEEE80211_MGMT_HDR_LEN; @@ -1716,8 +1732,8 @@ static void handle_deauth(local_info_t *local, struct sk_buff *skb, pos = (u16 *) body; reason_code = __le16_to_cpu(*pos); - PDEBUG(DEBUG_AP, "%s: deauthentication: " MACSTR " len=%d, " - "reason_code=%d\n", dev->name, MAC2STR(hdr->addr2), len, + PDEBUG(DEBUG_AP, "%s: deauthentication: %s len=%d, " + "reason_code=%d\n", dev->name, print_mac(mac, hdr->addr2), len, reason_code); spin_lock_bh(&local->ap->sta_table_lock); @@ -1729,9 +1745,9 @@ static void handle_deauth(local_info_t *local, struct sk_buff *skb, } spin_unlock_bh(&local->ap->sta_table_lock); if (sta == NULL) { - printk("%s: deauthentication from " MACSTR ", " + printk("%s: deauthentication from %s, " "reason_code=%d, but STA not authenticated\n", dev->name, - MAC2STR(hdr->addr2), reason_code); + print_mac(mac, hdr->addr2), reason_code); } } @@ -1746,6 +1762,7 @@ static void handle_disassoc(local_info_t *local, struct sk_buff *skb, int len; u16 reason_code, *pos; struct sta_info *sta = NULL; + DECLARE_MAC_BUF(mac); len = skb->len - IEEE80211_MGMT_HDR_LEN; @@ -1757,8 +1774,8 @@ static void handle_disassoc(local_info_t *local, struct sk_buff *skb, pos = (u16 *) body; reason_code = __le16_to_cpu(*pos); - PDEBUG(DEBUG_AP, "%s: disassociation: " MACSTR " len=%d, " - "reason_code=%d\n", dev->name, MAC2STR(hdr->addr2), len, + PDEBUG(DEBUG_AP, "%s: disassociation: %s len=%d, " + "reason_code=%d\n", dev->name, print_mac(mac, hdr->addr2), len, reason_code); spin_lock_bh(&local->ap->sta_table_lock); @@ -1770,9 +1787,9 @@ static void handle_disassoc(local_info_t *local, struct sk_buff *skb, } spin_unlock_bh(&local->ap->sta_table_lock); if (sta == NULL) { - printk("%s: disassociation from " MACSTR ", " + printk("%s: disassociation from %s, " "reason_code=%d, but STA not authenticated\n", - dev->name, MAC2STR(hdr->addr2), reason_code); + dev->name, print_mac(mac, hdr->addr2), reason_code); } } @@ -1862,15 +1879,16 @@ static void handle_pspoll(local_info_t *local, struct sta_info *sta; u16 aid; struct sk_buff *skb; + DECLARE_MAC_BUF(mac); - PDEBUG(DEBUG_PS2, "handle_pspoll: BSSID=" MACSTR ", TA=" MACSTR - " PWRMGT=%d\n", - MAC2STR(hdr->addr1), MAC2STR(hdr->addr2), + PDEBUG(DEBUG_PS2, "handle_pspoll: BSSID=%s" + ", TA=%s PWRMGT=%d\n", + print_mac(mac, hdr->addr1), print_mac(mac, hdr->addr2), !!(le16_to_cpu(hdr->frame_ctl) & IEEE80211_FCTL_PM)); if (memcmp(hdr->addr1, dev->dev_addr, ETH_ALEN)) { - PDEBUG(DEBUG_AP, "handle_pspoll - addr1(BSSID)=" MACSTR - " not own MAC\n", MAC2STR(hdr->addr1)); + PDEBUG(DEBUG_AP, "handle_pspoll - addr1(BSSID)=%s" + " not own MAC\n", print_mac(mac, hdr->addr1)); return; } @@ -1948,6 +1966,7 @@ static void handle_wds_oper_queue(struct work_struct *work) wds_oper_queue); local_info_t *local = ap->local; struct wds_oper_data *entry, *prev; + DECLARE_MAC_BUF(mac); spin_lock_bh(&local->lock); entry = local->ap->wds_oper_entries; @@ -1956,10 +1975,10 @@ static void handle_wds_oper_queue(struct work_struct *work) while (entry) { PDEBUG(DEBUG_AP, "%s: %s automatic WDS connection " - "to AP " MACSTR "\n", + "to AP %s\n", local->dev->name, entry->type == WDS_ADD ? "adding" : "removing", - MAC2STR(entry->addr)); + print_mac(mac, entry->addr)); if (entry->type == WDS_ADD) prism2_wds_add(local, entry->addr, 0); else if (entry->type == WDS_DEL) @@ -2135,6 +2154,7 @@ static void handle_ap_item(local_info_t *local, struct sk_buff *skb, #endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */ u16 fc, type, stype; struct ieee80211_hdr_4addr *hdr; + DECLARE_MAC_BUF(mac); /* FIX: should give skb->len to handler functions and check that the * buffer is long enough */ @@ -2163,8 +2183,8 @@ static void handle_ap_item(local_info_t *local, struct sk_buff *skb, if (memcmp(hdr->addr1, dev->dev_addr, ETH_ALEN)) { PDEBUG(DEBUG_AP, "handle_ap_item - addr1(BSSID)=" - MACSTR " not own MAC\n", - MAC2STR(hdr->addr1)); + "%s not own MAC\n", + print_mac(mac, hdr->addr1)); goto done; } @@ -2200,14 +2220,14 @@ static void handle_ap_item(local_info_t *local, struct sk_buff *skb, } if (memcmp(hdr->addr1, dev->dev_addr, ETH_ALEN)) { - PDEBUG(DEBUG_AP, "handle_ap_item - addr1(DA)=" MACSTR - " not own MAC\n", MAC2STR(hdr->addr1)); + PDEBUG(DEBUG_AP, "handle_ap_item - addr1(DA)=%s" + " not own MAC\n", print_mac(mac, hdr->addr1)); goto done; } if (memcmp(hdr->addr3, dev->dev_addr, ETH_ALEN)) { - PDEBUG(DEBUG_AP, "handle_ap_item - addr3(BSSID)=" MACSTR - " not own MAC\n", MAC2STR(hdr->addr3)); + PDEBUG(DEBUG_AP, "handle_ap_item - addr3(BSSID)=%s" + " not own MAC\n", print_mac(mac, hdr->addr3)); goto done; } @@ -2288,6 +2308,7 @@ static void schedule_packet_send(local_info_t *local, struct sta_info *sta) struct sk_buff *skb; struct ieee80211_hdr_4addr *hdr; struct hostap_80211_rx_status rx_stats; + DECLARE_MAC_BUF(mac); if (skb_queue_empty(&sta->tx_buf)) return; @@ -2308,8 +2329,8 @@ static void schedule_packet_send(local_info_t *local, struct sta_info *sta) memcpy(hdr->addr2, sta->addr, ETH_ALEN); hdr->duration_id = cpu_to_le16(sta->aid | BIT(15) | BIT(14)); - PDEBUG(DEBUG_PS2, "%s: Scheduling buffered packet delivery for " - "STA " MACSTR "\n", local->dev->name, MAC2STR(sta->addr)); + PDEBUG(DEBUG_PS2, "%s: Scheduling buffered packet delivery for STA " + "%s\n", local->dev->name, print_mac(mac, sta->addr)); skb->dev = local->dev; @@ -2636,6 +2657,7 @@ static int ap_update_sta_tx_rate(struct sta_info *sta, struct net_device *dev) int ret = sta->tx_rate; struct hostap_interface *iface; local_info_t *local; + DECLARE_MAC_BUF(mac); iface = netdev_priv(dev); local = iface->local; @@ -2663,9 +2685,9 @@ static int ap_update_sta_tx_rate(struct sta_info *sta, struct net_device *dev) case 3: sta->tx_rate = 110; break; default: sta->tx_rate = 0; break; } - PDEBUG(DEBUG_AP, "%s: STA " MACSTR " TX rate raised to" - " %d\n", dev->name, MAC2STR(sta->addr), - sta->tx_rate); + PDEBUG(DEBUG_AP, "%s: STA %s" + " TX rate raised to %d\n", + dev->name, print_mac(mac, sta->addr), sta->tx_rate); } sta->tx_since_last_failure = 0; } @@ -2683,6 +2705,7 @@ ap_tx_ret hostap_handle_sta_tx(local_info_t *local, struct hostap_tx_data *tx) int set_tim, ret; struct ieee80211_hdr_4addr *hdr; struct hostap_skb_tx_data *meta; + DECLARE_MAC_BUF(mac); meta = (struct hostap_skb_tx_data *) skb->cb; ret = AP_TX_CONTINUE; @@ -2718,7 +2741,8 @@ ap_tx_ret hostap_handle_sta_tx(local_info_t *local, struct hostap_tx_data *tx) * print out any errors here. */ if (net_ratelimit()) { printk(KERN_DEBUG "AP: drop packet to non-associated " - "STA " MACSTR "\n", MAC2STR(hdr->addr1)); + "STA %s\n", + print_mac(mac, hdr->addr1)); } #endif local->ap->tx_drop_nonassoc++; @@ -2756,8 +2780,9 @@ ap_tx_ret hostap_handle_sta_tx(local_info_t *local, struct hostap_tx_data *tx) } if (skb_queue_len(&sta->tx_buf) >= STA_MAX_TX_BUFFER) { - PDEBUG(DEBUG_PS, "%s: No more space in STA (" MACSTR ")'s PS " - "mode buffer\n", local->dev->name, MAC2STR(sta->addr)); + PDEBUG(DEBUG_PS, "%s: No more space in STA (%s" + ")'s PS mode buffer\n", + local->dev->name, print_mac(mac, sta->addr)); /* Make sure that TIM is set for the station (it might not be * after AP wlan hw reset). */ /* FIX: should fix hw reset to restore bits based on STA @@ -2821,6 +2846,7 @@ void hostap_handle_sta_tx_exc(local_info_t *local, struct sk_buff *skb) struct sta_info *sta; struct ieee80211_hdr_4addr *hdr; struct hostap_skb_tx_data *meta; + DECLARE_MAC_BUF(mac); hdr = (struct ieee80211_hdr_4addr *) skb->data; meta = (struct hostap_skb_tx_data *) skb->cb; @@ -2829,9 +2855,9 @@ void hostap_handle_sta_tx_exc(local_info_t *local, struct sk_buff *skb) sta = ap_get_sta(local->ap, hdr->addr1); if (!sta) { spin_unlock(&local->ap->sta_table_lock); - PDEBUG(DEBUG_AP, "%s: Could not find STA " MACSTR " for this " - "TX error (@%lu)\n", - local->dev->name, MAC2STR(hdr->addr1), jiffies); + PDEBUG(DEBUG_AP, "%s: Could not find STA %s" + " for this TX error (@%lu)\n", + local->dev->name, print_mac(mac, hdr->addr1), jiffies); return; } @@ -2858,8 +2884,9 @@ void hostap_handle_sta_tx_exc(local_info_t *local, struct sk_buff *skb) case 3: sta->tx_rate = 110; break; default: sta->tx_rate = 0; break; } - PDEBUG(DEBUG_AP, "%s: STA " MACSTR " TX rate lowered " - "to %d\n", local->dev->name, MAC2STR(sta->addr), + PDEBUG(DEBUG_AP, "%s: STA %s" + " TX rate lowered to %d\n", + local->dev->name, print_mac(mac, sta->addr), sta->tx_rate); } sta->tx_consecutive_exc = 0; @@ -2871,16 +2898,17 @@ void hostap_handle_sta_tx_exc(local_info_t *local, struct sk_buff *skb) static void hostap_update_sta_ps2(local_info_t *local, struct sta_info *sta, int pwrmgt, int type, int stype) { + DECLARE_MAC_BUF(mac); if (pwrmgt && !(sta->flags & WLAN_STA_PS)) { sta->flags |= WLAN_STA_PS; - PDEBUG(DEBUG_PS2, "STA " MACSTR " changed to use PS " + PDEBUG(DEBUG_PS2, "STA %s changed to use PS " "mode (type=0x%02X, stype=0x%02X)\n", - MAC2STR(sta->addr), type >> 2, stype >> 4); + print_mac(mac, sta->addr), type >> 2, stype >> 4); } else if (!pwrmgt && (sta->flags & WLAN_STA_PS)) { sta->flags &= ~WLAN_STA_PS; - PDEBUG(DEBUG_PS2, "STA " MACSTR " changed to not use " + PDEBUG(DEBUG_PS2, "STA %s changed to not use " "PS mode (type=0x%02X, stype=0x%02X)\n", - MAC2STR(sta->addr), type >> 2, stype >> 4); + print_mac(mac, sta->addr), type >> 2, stype >> 4); if (type != IEEE80211_FTYPE_CTL || stype != IEEE80211_STYPE_PSPOLL) schedule_packet_send(local, sta); @@ -2924,6 +2952,7 @@ ap_rx_ret hostap_handle_sta_rx(local_info_t *local, struct net_device *dev, struct sta_info *sta; u16 fc, type, stype; struct ieee80211_hdr_4addr *hdr; + DECLARE_MAC_BUF(mac); if (local->ap == NULL) return AP_RX_CONTINUE; @@ -2954,9 +2983,10 @@ ap_rx_ret hostap_handle_sta_rx(local_info_t *local, struct net_device *dev, #ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT } else { printk(KERN_DEBUG "%s: dropped received packet" - " from non-associated STA " MACSTR + " from non-associated STA " + "%s" " (type=0x%02x, subtype=0x%02x)\n", - dev->name, MAC2STR(hdr->addr2), + dev->name, print_mac(mac, hdr->addr2), type >> 2, stype >> 4); hostap_rx(dev, skb, rx_stats); #endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */ @@ -2991,8 +3021,8 @@ ap_rx_ret hostap_handle_sta_rx(local_info_t *local, struct net_device *dev, * being associated. */ printk(KERN_DEBUG "%s: rejected received nullfunc " "frame without ToDS from not associated STA " - MACSTR "\n", - dev->name, MAC2STR(hdr->addr2)); + "%s\n", + dev->name, print_mac(mac, hdr->addr2)); hostap_rx(dev, skb, rx_stats); #endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */ } @@ -3009,9 +3039,9 @@ ap_rx_ret hostap_handle_sta_rx(local_info_t *local, struct net_device *dev, * If BSSID is own, report the dropping of this frame. */ if (memcmp(hdr->addr3, dev->dev_addr, ETH_ALEN) == 0) { printk(KERN_DEBUG "%s: dropped received packet from " - MACSTR " with no ToDS flag (type=0x%02x, " - "subtype=0x%02x)\n", dev->name, - MAC2STR(hdr->addr2), type >> 2, stype >> 4); + "%s with no ToDS flag " + "(type=0x%02x, subtype=0x%02x)\n", dev->name, + print_mac(mac, hdr->addr2), type >> 2, stype >> 4); hostap_dump_rx_80211(dev->name, skb, rx_stats); } ret = AP_RX_DROP; diff --git a/drivers/net/wireless/hostap/hostap_common.h b/drivers/net/wireless/hostap/hostap_common.h index b31e6a05f23c..ceb7f1e5e9e0 100644 --- a/drivers/net/wireless/hostap/hostap_common.h +++ b/drivers/net/wireless/hostap/hostap_common.h @@ -6,9 +6,6 @@ #define BIT(x) (1 << (x)) -#define MAC2STR(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5] -#define MACSTR "%02x:%02x:%02x:%02x:%02x:%02x" - /* IEEE 802.11 defines */ diff --git a/drivers/net/wireless/hostap/hostap_hw.c b/drivers/net/wireless/hostap/hostap_hw.c index adedb9716542..7fa7ab0a4b23 100644 --- a/drivers/net/wireless/hostap/hostap_hw.c +++ b/drivers/net/wireless/hostap/hostap_hw.c @@ -2335,6 +2335,10 @@ static void prism2_txexc(local_info_t *local) int show_dump, res; char *payload = NULL; struct hfa384x_tx_frame txdesc; + DECLARE_MAC_BUF(mac); + DECLARE_MAC_BUF(mac2); + DECLARE_MAC_BUF(mac3); + DECLARE_MAC_BUF(mac4); show_dump = local->frame_dump & PRISM2_DUMP_TXEXC_HDR; local->stats.tx_errors++; @@ -2400,10 +2404,9 @@ static void prism2_txexc(local_info_t *local) WLAN_FC_GET_STYPE(fc) >> 4, fc & IEEE80211_FCTL_TODS ? " ToDS" : "", fc & IEEE80211_FCTL_FROMDS ? " FromDS" : ""); - PDEBUG(DEBUG_EXTRA, " A1=" MACSTR " A2=" MACSTR " A3=" - MACSTR " A4=" MACSTR "\n", - MAC2STR(txdesc.addr1), MAC2STR(txdesc.addr2), - MAC2STR(txdesc.addr3), MAC2STR(txdesc.addr4)); + PDEBUG(DEBUG_EXTRA, " A1=%s A2=%s A3=%s A4=%s\n", + print_mac(mac, txdesc.addr1), print_mac(mac2, txdesc.addr2), + print_mac(mac3, txdesc.addr3), print_mac(mac4, txdesc.addr4)); } diff --git a/drivers/net/wireless/hostap/hostap_info.c b/drivers/net/wireless/hostap/hostap_info.c index b6a02a02da74..636f4b2382ea 100644 --- a/drivers/net/wireless/hostap/hostap_info.c +++ b/drivers/net/wireless/hostap/hostap_info.c @@ -166,6 +166,7 @@ static void prism2_host_roaming(local_info_t *local) struct hfa384x_hostscan_result *selected, *entry; int i; unsigned long flags; + DECLARE_MAC_BUF(mac); if (local->last_join_time && time_before(jiffies, local->last_join_time + 10 * HZ)) { @@ -198,8 +199,9 @@ static void prism2_host_roaming(local_info_t *local) local->preferred_ap[2] || local->preferred_ap[3] || local->preferred_ap[4] || local->preferred_ap[5]) { /* Try to find preferred AP */ - PDEBUG(DEBUG_EXTRA, "%s: Preferred AP BSSID " MACSTR "\n", - dev->name, MAC2STR(local->preferred_ap)); + PDEBUG(DEBUG_EXTRA, "%s: Preferred AP BSSID " + "%s\n", + dev->name, print_mac(mac, local->preferred_ap)); for (i = 0; i < local->last_scan_results_count; i++) { entry = &local->last_scan_results[i]; if (memcmp(local->preferred_ap, entry->bssid, 6) == 0) @@ -216,8 +218,9 @@ static void prism2_host_roaming(local_info_t *local) req.channel = selected->chid; spin_unlock_irqrestore(&local->lock, flags); - PDEBUG(DEBUG_EXTRA, "%s: JoinRequest: BSSID=" MACSTR " channel=%d\n", - dev->name, MAC2STR(req.bssid), le16_to_cpu(req.channel)); + PDEBUG(DEBUG_EXTRA, "%s: JoinRequest: BSSID=%s" + " channel=%d\n", + dev->name, print_mac(mac, req.bssid), le16_to_cpu(req.channel)); if (local->func->set_rid(dev, HFA384X_RID_JOINREQUEST, &req, sizeof(req))) { printk(KERN_DEBUG "%s: JoinRequest failed\n", dev->name); @@ -409,6 +412,7 @@ static void handle_info_queue_linkstatus(local_info_t *local) int val = local->prev_link_status; int connected; union iwreq_data wrqu; + DECLARE_MAC_BUF(mac); connected = val == HFA384X_LINKSTATUS_CONNECTED || @@ -420,9 +424,10 @@ static void handle_info_queue_linkstatus(local_info_t *local) printk(KERN_DEBUG "%s: could not read CURRENTBSSID after " "LinkStatus event\n", local->dev->name); } else { - PDEBUG(DEBUG_EXTRA, "%s: LinkStatus: BSSID=" MACSTR "\n", + PDEBUG(DEBUG_EXTRA, "%s: LinkStatus: BSSID=" + "%s\n", local->dev->name, - MAC2STR((unsigned char *) local->bssid)); + print_mac(mac, (unsigned char *) local->bssid)); if (local->wds_type & HOSTAP_WDS_AP_CLIENT) hostap_add_sta(local->ap, local->bssid); } diff --git a/drivers/net/wireless/hostap/hostap_ioctl.c b/drivers/net/wireless/hostap/hostap_ioctl.c index 730b3541e325..7036ecff5ec1 100644 --- a/drivers/net/wireless/hostap/hostap_ioctl.c +++ b/drivers/net/wireless/hostap/hostap_ioctl.c @@ -664,6 +664,7 @@ static int hostap_join_ap(struct net_device *dev) unsigned long flags; int i; struct hfa384x_hostscan_result *entry; + DECLARE_MAC_BUF(mac); iface = netdev_priv(dev); local = iface->local; @@ -685,14 +686,14 @@ static int hostap_join_ap(struct net_device *dev) if (local->func->set_rid(dev, HFA384X_RID_JOINREQUEST, &req, sizeof(req))) { - printk(KERN_DEBUG "%s: JoinRequest " MACSTR + printk(KERN_DEBUG "%s: JoinRequest %s" " failed\n", - dev->name, MAC2STR(local->preferred_ap)); + dev->name, print_mac(mac, local->preferred_ap)); return -1; } - printk(KERN_DEBUG "%s: Trying to join BSSID " MACSTR "\n", - dev->name, MAC2STR(local->preferred_ap)); + printk(KERN_DEBUG "%s: Trying to join BSSID %s\n", + dev->name, print_mac(mac, local->preferred_ap)); return 0; } @@ -3697,8 +3698,10 @@ static int prism2_ioctl_set_assoc_ap_addr(local_info_t *local, struct prism2_hostapd_param *param, int param_len) { - printk(KERN_DEBUG "%ssta: associated as client with AP " MACSTR "\n", - local->dev->name, MAC2STR(param->sta_addr)); + DECLARE_MAC_BUF(mac); + printk(KERN_DEBUG "%ssta: associated as client with AP " + "%s\n", + local->dev->name, print_mac(mac, param->sta_addr)); memcpy(local->assoc_ap_addr, param->sta_addr, ETH_ALEN); return 0; } diff --git a/drivers/net/wireless/hostap/hostap_main.c b/drivers/net/wireless/hostap/hostap_main.c index 9a470e80ca24..4cb09d81b404 100644 --- a/drivers/net/wireless/hostap/hostap_main.c +++ b/drivers/net/wireless/hostap/hostap_main.c @@ -530,6 +530,10 @@ int hostap_set_auth_algs(local_info_t *local) void hostap_dump_rx_header(const char *name, const struct hfa384x_rx_frame *rx) { u16 status, fc; + DECLARE_MAC_BUF(mac); + DECLARE_MAC_BUF(mac2); + DECLARE_MAC_BUF(mac3); + DECLARE_MAC_BUF(mac4); status = __le16_to_cpu(rx->status); @@ -548,13 +552,12 @@ void hostap_dump_rx_header(const char *name, const struct hfa384x_rx_frame *rx) fc & IEEE80211_FCTL_TODS ? " [ToDS]" : "", fc & IEEE80211_FCTL_FROMDS ? " [FromDS]" : ""); - printk(KERN_DEBUG " A1=" MACSTR " A2=" MACSTR " A3=" MACSTR " A4=" - MACSTR "\n", - MAC2STR(rx->addr1), MAC2STR(rx->addr2), MAC2STR(rx->addr3), - MAC2STR(rx->addr4)); + printk(KERN_DEBUG " A1=%s A2=%s A3=%s A4=%s\n", + print_mac(mac, rx->addr1), print_mac(mac2, rx->addr2), + print_mac(mac3, rx->addr3), print_mac(mac4, rx->addr4)); - printk(KERN_DEBUG " dst=" MACSTR " src=" MACSTR " len=%d\n", - MAC2STR(rx->dst_addr), MAC2STR(rx->src_addr), + printk(KERN_DEBUG " dst=%s src=%s len=%d\n", + print_mac(mac, rx->dst_addr), print_mac(mac2, rx->src_addr), __be16_to_cpu(rx->len)); } @@ -562,6 +565,10 @@ void hostap_dump_rx_header(const char *name, const struct hfa384x_rx_frame *rx) void hostap_dump_tx_header(const char *name, const struct hfa384x_tx_frame *tx) { u16 fc; + DECLARE_MAC_BUF(mac); + DECLARE_MAC_BUF(mac2); + DECLARE_MAC_BUF(mac3); + DECLARE_MAC_BUF(mac4); printk(KERN_DEBUG "%s: TX status=0x%04x retry_count=%d tx_rate=%d " "tx_control=0x%04x; jiffies=%ld\n", @@ -577,13 +584,12 @@ void hostap_dump_tx_header(const char *name, const struct hfa384x_tx_frame *tx) fc & IEEE80211_FCTL_TODS ? " [ToDS]" : "", fc & IEEE80211_FCTL_FROMDS ? " [FromDS]" : ""); - printk(KERN_DEBUG " A1=" MACSTR " A2=" MACSTR " A3=" MACSTR " A4=" - MACSTR "\n", - MAC2STR(tx->addr1), MAC2STR(tx->addr2), MAC2STR(tx->addr3), - MAC2STR(tx->addr4)); + printk(KERN_DEBUG " A1=%s A2=%s A3=%s A4=%s\n", + print_mac(mac, tx->addr1), print_mac(mac2, tx->addr2), + print_mac(mac3, tx->addr3), print_mac(mac4, tx->addr4)); - printk(KERN_DEBUG " dst=" MACSTR " src=" MACSTR " len=%d\n", - MAC2STR(tx->dst_addr), MAC2STR(tx->src_addr), + printk(KERN_DEBUG " dst=%s src=%s len=%d\n", + print_mac(mac, tx->dst_addr), print_mac(mac2, tx->src_addr), __be16_to_cpu(tx->len)); } diff --git a/drivers/net/wireless/hostap/hostap_proc.c b/drivers/net/wireless/hostap/hostap_proc.c index d1d8ce022e63..b03536008ad9 100644 --- a/drivers/net/wireless/hostap/hostap_proc.c +++ b/drivers/net/wireless/hostap/hostap_proc.c @@ -106,6 +106,7 @@ static int prism2_wds_proc_read(char *page, char **start, off_t off, local_info_t *local = (local_info_t *) data; struct list_head *ptr; struct hostap_interface *iface; + DECLARE_MAC_BUF(mac); if (off > PROC_LIMIT) { *eof = 1; @@ -117,9 +118,9 @@ static int prism2_wds_proc_read(char *page, char **start, off_t off, iface = list_entry(ptr, struct hostap_interface, list); if (iface->type != HOSTAP_INTERFACE_WDS) continue; - p += sprintf(p, "%s\t" MACSTR "\n", + p += sprintf(p, "%s\t%s\n", iface->dev->name, - MAC2STR(iface->u.wds.remote_addr)); + print_mac(mac, iface->u.wds.remote_addr)); if ((p - page) > PROC_LIMIT) { printk(KERN_DEBUG "%s: wds proc did not fit\n", local->dev->name); @@ -147,6 +148,7 @@ static int prism2_bss_list_proc_read(char *page, char **start, off_t off, struct list_head *ptr; struct hostap_bss_info *bss; int i; + DECLARE_MAC_BUF(mac); if (off > PROC_LIMIT) { *eof = 1; @@ -158,8 +160,8 @@ static int prism2_bss_list_proc_read(char *page, char **start, off_t off, spin_lock_bh(&local->lock); list_for_each(ptr, &local->bss_list) { bss = list_entry(ptr, struct hostap_bss_info, list); - p += sprintf(p, MACSTR "\t%lu\t%u\t0x%x\t", - MAC2STR(bss->bssid), bss->last_update, + p += sprintf(p, "%s\t%lu\t%u\t0x%x\t", + print_mac(mac, bss->bssid), bss->last_update, bss->count, bss->capab_info); for (i = 0; i < bss->ssid_len; i++) { p += sprintf(p, "%c", @@ -312,6 +314,7 @@ static int prism2_scan_results_proc_read(char *page, char **start, off_t off, int entry, i, len, total = 0; struct hfa384x_hostscan_result *scanres; u8 *pos; + DECLARE_MAC_BUF(mac); p += sprintf(p, "CHID ANL SL BcnInt Capab Rate BSSID ATIM SupRates " "SSID\n"); @@ -329,14 +332,14 @@ static int prism2_scan_results_proc_read(char *page, char **start, off_t off, if ((p - page) > (PAGE_SIZE - 200)) break; - p += sprintf(p, "%d %d %d %d 0x%02x %d " MACSTR " %d ", + p += sprintf(p, "%d %d %d %d 0x%02x %d %s %d ", le16_to_cpu(scanres->chid), (s16) le16_to_cpu(scanres->anl), (s16) le16_to_cpu(scanres->sl), le16_to_cpu(scanres->beacon_interval), le16_to_cpu(scanres->capability), le16_to_cpu(scanres->rate), - MAC2STR(scanres->bssid), + print_mac(mac, scanres->bssid), le16_to_cpu(scanres->atim)); pos = scanres->sup_rates; diff --git a/drivers/net/wireless/ipw2100.c b/drivers/net/wireless/ipw2100.c index b3c07b93afce..2d46a16c0945 100644 --- a/drivers/net/wireless/ipw2100.c +++ b/drivers/net/wireless/ipw2100.c @@ -1922,6 +1922,7 @@ static void isr_indicate_associated(struct ipw2100_priv *priv, u32 status) u32 chan; char *txratename; u8 bssid[ETH_ALEN]; + DECLARE_MAC_BUF(mac); /* * TBD: BSSID is usually 00:00:00:00:00:00 here and not @@ -1983,9 +1984,9 @@ static void isr_indicate_associated(struct ipw2100_priv *priv, u32 status) } IPW_DEBUG_INFO("%s: Associated with '%s' at %s, channel %d (BSSID=" - MAC_FMT ")\n", + "%s)\n", priv->net_dev->name, escape_essid(essid, essid_len), - txratename, chan, MAC_ARG(bssid)); + txratename, chan, print_mac(mac, bssid)); /* now we copy read ssid into dev */ if (!(priv->config & CFG_STATIC_ESSID)) { @@ -2053,10 +2054,12 @@ static int ipw2100_set_essid(struct ipw2100_priv *priv, char *essid, static void isr_indicate_association_lost(struct ipw2100_priv *priv, u32 status) { + DECLARE_MAC_BUF(mac); + IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE | IPW_DL_ASSOC, - "disassociated: '%s' " MAC_FMT " \n", + "disassociated: '%s' %s \n", escape_essid(priv->essid, priv->essid_len), - MAC_ARG(priv->bssid)); + print_mac(mac, priv->bssid)); priv->status &= ~(STATUS_ASSOCIATED | STATUS_ASSOCIATING); @@ -4049,6 +4052,7 @@ static ssize_t show_bssinfo(struct device *d, struct device_attribute *attr, char *out = buf; int length; int ret; + DECLARE_MAC_BUF(mac); if (priv->status & STATUS_RF_KILL_MASK) return 0; @@ -4076,9 +4080,7 @@ static ssize_t show_bssinfo(struct device *d, struct device_attribute *attr, __LINE__); out += sprintf(out, "ESSID: %s\n", essid); - out += sprintf(out, "BSSID: %02x:%02x:%02x:%02x:%02x:%02x\n", - bssid[0], bssid[1], bssid[2], - bssid[3], bssid[4], bssid[5]); + out += sprintf(out, "BSSID: %s\n", print_mac(mac, bssid)); out += sprintf(out, "Channel: %d\n", chan); return out - buf; @@ -4652,19 +4654,20 @@ static void ipw2100_rx_free(struct ipw2100_priv *priv) static int ipw2100_read_mac_address(struct ipw2100_priv *priv) { u32 length = ETH_ALEN; - u8 mac[ETH_ALEN]; + u8 addr[ETH_ALEN]; + DECLARE_MAC_BUF(mac); int err; - err = ipw2100_get_ordinal(priv, IPW_ORD_STAT_ADAPTER_MAC, mac, &length); + err = ipw2100_get_ordinal(priv, IPW_ORD_STAT_ADAPTER_MAC, addr, &length); if (err) { IPW_DEBUG_INFO("MAC address read failed\n"); return -EIO; } - IPW_DEBUG_INFO("card MAC is %02X:%02X:%02X:%02X:%02X:%02X\n", - mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); - memcpy(priv->net_dev->dev_addr, mac, ETH_ALEN); + memcpy(priv->net_dev->dev_addr, addr, ETH_ALEN); + IPW_DEBUG_INFO("card MAC is %s\n", + print_mac(mac, priv->net_dev->dev_addr)); return 0; } @@ -5043,10 +5046,10 @@ static int ipw2100_set_mandatory_bssid(struct ipw2100_priv *priv, u8 * bssid, int err; #ifdef CONFIG_IPW2100_DEBUG + DECLARE_MAC_BUF(mac); if (bssid != NULL) - IPW_DEBUG_HC("MANDATORY_BSSID: %02X:%02X:%02X:%02X:%02X:%02X\n", - bssid[0], bssid[1], bssid[2], bssid[3], bssid[4], - bssid[5]); + IPW_DEBUG_HC("MANDATORY_BSSID: %s\n", + print_mac(mac, bssid)); else IPW_DEBUG_HC("MANDATORY_BSSID: \n"); #endif @@ -6892,6 +6895,7 @@ static int ipw2100_wx_set_wap(struct net_device *dev, static const unsigned char off[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + DECLARE_MAC_BUF(mac); // sanity checks if (wrqu->ap_addr.sa_family != ARPHRD_ETHER) @@ -6917,13 +6921,8 @@ static int ipw2100_wx_set_wap(struct net_device *dev, err = ipw2100_set_mandatory_bssid(priv, wrqu->ap_addr.sa_data, 0); - IPW_DEBUG_WX("SET BSSID -> %02X:%02X:%02X:%02X:%02X:%02X\n", - wrqu->ap_addr.sa_data[0] & 0xff, - wrqu->ap_addr.sa_data[1] & 0xff, - wrqu->ap_addr.sa_data[2] & 0xff, - wrqu->ap_addr.sa_data[3] & 0xff, - wrqu->ap_addr.sa_data[4] & 0xff, - wrqu->ap_addr.sa_data[5] & 0xff); + IPW_DEBUG_WX("SET BSSID -> %s\n", + print_mac(mac, wrqu->ap_addr.sa_data)); done: mutex_unlock(&priv->action_mutex); @@ -6939,6 +6938,7 @@ static int ipw2100_wx_get_wap(struct net_device *dev, */ struct ipw2100_priv *priv = ieee80211_priv(dev); + DECLARE_MAC_BUF(mac); /* If we are associated, trying to associate, or have a statically * configured BSSID then return that; otherwise return ANY */ @@ -6948,8 +6948,8 @@ static int ipw2100_wx_get_wap(struct net_device *dev, } else memset(wrqu->ap_addr.sa_data, 0, ETH_ALEN); - IPW_DEBUG_WX("Getting WAP BSSID: " MAC_FMT "\n", - MAC_ARG(wrqu->ap_addr.sa_data)); + IPW_DEBUG_WX("Getting WAP BSSID: %s\n", + print_mac(mac, wrqu->ap_addr.sa_data)); return 0; } diff --git a/drivers/net/wireless/ipw2200.c b/drivers/net/wireless/ipw2200.c index afad8bb7e334..2119a79dcc86 100644 --- a/drivers/net/wireless/ipw2200.c +++ b/drivers/net/wireless/ipw2200.c @@ -2247,8 +2247,8 @@ static int ipw_send_adapter_address(struct ipw_priv *priv, u8 * mac) return -1; } - IPW_DEBUG_INFO("%s: Setting MAC to " MAC_FMT "\n", - priv->net_dev->name, MAC_ARG(mac)); + IPW_DEBUG_INFO("%s: Setting MAC to %s\n", + priv->net_dev->name, print_mac(mac, mac)); return ipw_send_cmd_pdu(priv, IPW_CMD_ADAPTER_ADDRESS, ETH_ALEN, mac); } @@ -3796,6 +3796,7 @@ static u8 ipw_add_station(struct ipw_priv *priv, u8 * bssid) { struct ipw_station_entry entry; int i; + DECLARE_MAC_BUF(mac); for (i = 0; i < priv->num_stations; i++) { if (!memcmp(priv->stations[i], bssid, ETH_ALEN)) { @@ -3812,7 +3813,7 @@ static u8 ipw_add_station(struct ipw_priv *priv, u8 * bssid) if (i == MAX_STATIONS) return IPW_INVALID_STATION; - IPW_DEBUG_SCAN("Adding AdHoc station: " MAC_FMT "\n", MAC_ARG(bssid)); + IPW_DEBUG_SCAN("Adding AdHoc station: %s\n", print_mac(mac, bssid)); entry.reserved = 0; entry.support_mode = 0; @@ -3839,6 +3840,7 @@ static u8 ipw_find_station(struct ipw_priv *priv, u8 * bssid) static void ipw_send_disassociate(struct ipw_priv *priv, int quiet) { int err; + DECLARE_MAC_BUF(mac); if (priv->status & STATUS_ASSOCIATING) { IPW_DEBUG_ASSOC("Disassociating while associating.\n"); @@ -3851,9 +3853,9 @@ static void ipw_send_disassociate(struct ipw_priv *priv, int quiet) return; } - IPW_DEBUG_ASSOC("Disassocation attempt from " MAC_FMT " " + IPW_DEBUG_ASSOC("Disassocation attempt from %s " "on channel %d.\n", - MAC_ARG(priv->assoc_request.bssid), + print_mac(mac, priv->assoc_request.bssid), priv->assoc_request.channel); priv->status &= ~(STATUS_ASSOCIATING | STATUS_ASSOCIATED); @@ -4348,6 +4350,7 @@ static void ipw_handle_missed_beacon(struct ipw_priv *priv, static void ipw_rx_notification(struct ipw_priv *priv, struct ipw_rx_notification *notif) { + DECLARE_MAC_BUF(mac); notif->size = le16_to_cpu(notif->size); IPW_DEBUG_NOTIF("type = %i (%d bytes)\n", notif->subtype, notif->size); @@ -4360,11 +4363,11 @@ static void ipw_rx_notification(struct ipw_priv *priv, case CMAS_ASSOCIATED:{ IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE | IPW_DL_ASSOC, - "associated: '%s' " MAC_FMT + "associated: '%s' %s" " \n", escape_essid(priv->essid, priv->essid_len), - MAC_ARG(priv->bssid)); + print_mac(mac, priv->bssid)); switch (priv->ieee->iw_mode) { case IW_MODE_INFRA: @@ -4444,13 +4447,13 @@ static void ipw_rx_notification(struct ipw_priv *priv, IPW_DL_STATE | IPW_DL_ASSOC, "deauthenticated: '%s' " - MAC_FMT + "%s" ": (0x%04X) - %s \n", escape_essid(priv-> essid, priv-> essid_len), - MAC_ARG(priv->bssid), + print_mac(mac, priv->bssid), ntohs(auth->status), ipw_get_status_code (ntohs @@ -4467,11 +4470,11 @@ static void ipw_rx_notification(struct ipw_priv *priv, IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE | IPW_DL_ASSOC, - "authenticated: '%s' " MAC_FMT + "authenticated: '%s' %s" "\n", escape_essid(priv->essid, priv->essid_len), - MAC_ARG(priv->bssid)); + print_mac(mac, priv->bssid)); break; } @@ -4496,11 +4499,11 @@ static void ipw_rx_notification(struct ipw_priv *priv, IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE | IPW_DL_ASSOC, - "disassociated: '%s' " MAC_FMT + "disassociated: '%s' %s" " \n", escape_essid(priv->essid, priv->essid_len), - MAC_ARG(priv->bssid)); + print_mac(mac, priv->bssid)); priv->status &= ~(STATUS_DISASSOCIATING | @@ -4535,10 +4538,10 @@ static void ipw_rx_notification(struct ipw_priv *priv, switch (auth->state) { case CMAS_AUTHENTICATED: IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE, - "authenticated: '%s' " MAC_FMT " \n", + "authenticated: '%s' %s \n", escape_essid(priv->essid, priv->essid_len), - MAC_ARG(priv->bssid)); + print_mac(mac, priv->bssid)); priv->status |= STATUS_AUTH; break; @@ -4554,10 +4557,10 @@ static void ipw_rx_notification(struct ipw_priv *priv, } IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE | IPW_DL_ASSOC, - "deauthenticated: '%s' " MAC_FMT "\n", + "deauthenticated: '%s' %s\n", escape_essid(priv->essid, priv->essid_len), - MAC_ARG(priv->bssid)); + print_mac(mac, priv->bssid)); priv->status &= ~(STATUS_ASSOCIATING | STATUS_AUTH | @@ -5383,25 +5386,27 @@ static int ipw_find_adhoc_network(struct ipw_priv *priv, int roaming) { struct ipw_supported_rates rates; + DECLARE_MAC_BUF(mac); + DECLARE_MAC_BUF(mac2); /* Verify that this network's capability is compatible with the * current mode (AdHoc or Infrastructure) */ if ((priv->ieee->iw_mode == IW_MODE_ADHOC && !(network->capability & WLAN_CAPABILITY_IBSS))) { - IPW_DEBUG_MERGE("Network '%s (" MAC_FMT ")' excluded due to " + IPW_DEBUG_MERGE("Network '%s (%s)' excluded due to " "capability mismatch.\n", escape_essid(network->ssid, network->ssid_len), - MAC_ARG(network->bssid)); + print_mac(mac, network->bssid)); return 0; } /* If we do not have an ESSID for this AP, we can not associate with * it */ if (network->flags & NETWORK_EMPTY_ESSID) { - IPW_DEBUG_MERGE("Network '%s (" MAC_FMT ")' excluded " + IPW_DEBUG_MERGE("Network '%s (%s)' excluded " "because of hidden ESSID.\n", escape_essid(network->ssid, network->ssid_len), - MAC_ARG(network->bssid)); + print_mac(mac, network->bssid)); return 0; } @@ -5411,11 +5416,11 @@ static int ipw_find_adhoc_network(struct ipw_priv *priv, if ((network->ssid_len != match->network->ssid_len) || memcmp(network->ssid, match->network->ssid, network->ssid_len)) { - IPW_DEBUG_MERGE("Netowrk '%s (" MAC_FMT ")' excluded " + IPW_DEBUG_MERGE("Network '%s (%s)' excluded " "because of non-network ESSID.\n", escape_essid(network->ssid, network->ssid_len), - MAC_ARG(network->bssid)); + print_mac(mac, network->bssid)); return 0; } } else { @@ -5430,9 +5435,9 @@ static int ipw_find_adhoc_network(struct ipw_priv *priv, strncpy(escaped, escape_essid(network->ssid, network->ssid_len), sizeof(escaped)); - IPW_DEBUG_MERGE("Network '%s (" MAC_FMT ")' excluded " + IPW_DEBUG_MERGE("Network '%s (%s)' excluded " "because of ESSID mismatch: '%s'.\n", - escaped, MAC_ARG(network->bssid), + escaped, print_mac(mac, network->bssid), escape_essid(priv->essid, priv->essid_len)); return 0; @@ -5459,10 +5464,10 @@ static int ipw_find_adhoc_network(struct ipw_priv *priv, /* Now go through and see if the requested network is valid... */ if (priv->ieee->scan_age != 0 && time_after(jiffies, network->last_scanned + priv->ieee->scan_age)) { - IPW_DEBUG_MERGE("Network '%s (" MAC_FMT ")' excluded " + IPW_DEBUG_MERGE("Network '%s (%s)' excluded " "because of age: %ums.\n", escape_essid(network->ssid, network->ssid_len), - MAC_ARG(network->bssid), + print_mac(mac, network->bssid), jiffies_to_msecs(jiffies - network->last_scanned)); return 0; @@ -5470,10 +5475,10 @@ static int ipw_find_adhoc_network(struct ipw_priv *priv, if ((priv->config & CFG_STATIC_CHANNEL) && (network->channel != priv->channel)) { - IPW_DEBUG_MERGE("Network '%s (" MAC_FMT ")' excluded " + IPW_DEBUG_MERGE("Network '%s (%s)' excluded " "because of channel mismatch: %d != %d.\n", escape_essid(network->ssid, network->ssid_len), - MAC_ARG(network->bssid), + print_mac(mac, network->bssid), network->channel, priv->channel); return 0; } @@ -5481,10 +5486,10 @@ static int ipw_find_adhoc_network(struct ipw_priv *priv, /* Verify privacy compatability */ if (((priv->capability & CAP_PRIVACY_ON) ? 1 : 0) != ((network->capability & WLAN_CAPABILITY_PRIVACY) ? 1 : 0)) { - IPW_DEBUG_MERGE("Network '%s (" MAC_FMT ")' excluded " + IPW_DEBUG_MERGE("Network '%s (%s)' excluded " "because of privacy mismatch: %s != %s.\n", escape_essid(network->ssid, network->ssid_len), - MAC_ARG(network->bssid), + print_mac(mac, network->bssid), priv-> capability & CAP_PRIVACY_ON ? "on" : "off", network-> @@ -5494,40 +5499,41 @@ static int ipw_find_adhoc_network(struct ipw_priv *priv, } if (!memcmp(network->bssid, priv->bssid, ETH_ALEN)) { - IPW_DEBUG_MERGE("Network '%s (" MAC_FMT ")' excluded " - "because of the same BSSID match: " MAC_FMT + IPW_DEBUG_MERGE("Network '%s (%s)' excluded " + "because of the same BSSID match: %s" ".\n", escape_essid(network->ssid, network->ssid_len), - MAC_ARG(network->bssid), MAC_ARG(priv->bssid)); + print_mac(mac, network->bssid), + print_mac(mac2, priv->bssid)); return 0; } /* Filter out any incompatible freq / mode combinations */ if (!ieee80211_is_valid_mode(priv->ieee, network->mode)) { - IPW_DEBUG_MERGE("Network '%s (" MAC_FMT ")' excluded " + IPW_DEBUG_MERGE("Network '%s (%s)' excluded " "because of invalid frequency/mode " "combination.\n", escape_essid(network->ssid, network->ssid_len), - MAC_ARG(network->bssid)); + print_mac(mac, network->bssid)); return 0; } /* Ensure that the rates supported by the driver are compatible with * this AP, including verification of basic rates (mandatory) */ if (!ipw_compatible_rates(priv, network, &rates)) { - IPW_DEBUG_MERGE("Network '%s (" MAC_FMT ")' excluded " + IPW_DEBUG_MERGE("Network '%s (%s)' excluded " "because configured rate mask excludes " "AP mandatory rate.\n", escape_essid(network->ssid, network->ssid_len), - MAC_ARG(network->bssid)); + print_mac(mac, network->bssid)); return 0; } if (rates.num_rates == 0) { - IPW_DEBUG_MERGE("Network '%s (" MAC_FMT ")' excluded " + IPW_DEBUG_MERGE("Network '%s (%s)' excluded " "because of no compatible rates.\n", escape_essid(network->ssid, network->ssid_len), - MAC_ARG(network->bssid)); + print_mac(mac, network->bssid)); return 0; } @@ -5538,9 +5544,9 @@ static int ipw_find_adhoc_network(struct ipw_priv *priv, /* Set up 'new' AP to this network */ ipw_copy_rates(&match->rates, &rates); match->network = network; - IPW_DEBUG_MERGE("Network '%s (" MAC_FMT ")' is a viable match.\n", + IPW_DEBUG_MERGE("Network '%s (%s)' is a viable match.\n", escape_essid(network->ssid, network->ssid_len), - MAC_ARG(network->bssid)); + print_mac(mac, network->bssid)); return 1; } @@ -5594,6 +5600,7 @@ static int ipw_best_network(struct ipw_priv *priv, struct ieee80211_network *network, int roaming) { struct ipw_supported_rates rates; + DECLARE_MAC_BUF(mac); /* Verify that this network's capability is compatible with the * current mode (AdHoc or Infrastructure) */ @@ -5601,20 +5608,20 @@ static int ipw_best_network(struct ipw_priv *priv, !(network->capability & WLAN_CAPABILITY_ESS)) || (priv->ieee->iw_mode == IW_MODE_ADHOC && !(network->capability & WLAN_CAPABILITY_IBSS))) { - IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded due to " + IPW_DEBUG_ASSOC("Network '%s (%s)' excluded due to " "capability mismatch.\n", escape_essid(network->ssid, network->ssid_len), - MAC_ARG(network->bssid)); + print_mac(mac, network->bssid)); return 0; } /* If we do not have an ESSID for this AP, we can not associate with * it */ if (network->flags & NETWORK_EMPTY_ESSID) { - IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded " + IPW_DEBUG_ASSOC("Network '%s (%s)' excluded " "because of hidden ESSID.\n", escape_essid(network->ssid, network->ssid_len), - MAC_ARG(network->bssid)); + print_mac(mac, network->bssid)); return 0; } @@ -5624,11 +5631,11 @@ static int ipw_best_network(struct ipw_priv *priv, if ((network->ssid_len != match->network->ssid_len) || memcmp(network->ssid, match->network->ssid, network->ssid_len)) { - IPW_DEBUG_ASSOC("Netowrk '%s (" MAC_FMT ")' excluded " + IPW_DEBUG_ASSOC("Network '%s (%s)' excluded " "because of non-network ESSID.\n", escape_essid(network->ssid, network->ssid_len), - MAC_ARG(network->bssid)); + print_mac(mac, network->bssid)); return 0; } } else { @@ -5642,9 +5649,9 @@ static int ipw_best_network(struct ipw_priv *priv, strncpy(escaped, escape_essid(network->ssid, network->ssid_len), sizeof(escaped)); - IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded " + IPW_DEBUG_ASSOC("Network '%s (%s)' excluded " "because of ESSID mismatch: '%s'.\n", - escaped, MAC_ARG(network->bssid), + escaped, print_mac(mac, network->bssid), escape_essid(priv->essid, priv->essid_len)); return 0; @@ -5658,12 +5665,12 @@ static int ipw_best_network(struct ipw_priv *priv, strncpy(escaped, escape_essid(network->ssid, network->ssid_len), sizeof(escaped)); - IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded because " - "'%s (" MAC_FMT ")' has a stronger signal.\n", - escaped, MAC_ARG(network->bssid), + IPW_DEBUG_ASSOC("Network '%s (%s)' excluded because " + "'%s (%s)' has a stronger signal.\n", + escaped, print_mac(mac, network->bssid), escape_essid(match->network->ssid, match->network->ssid_len), - MAC_ARG(match->network->bssid)); + print_mac(mac, match->network->bssid)); return 0; } @@ -5671,11 +5678,11 @@ static int ipw_best_network(struct ipw_priv *priv, * last 3 seconds, do not try and associate again... */ if (network->last_associate && time_after(network->last_associate + (HZ * 3UL), jiffies)) { - IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded " + IPW_DEBUG_ASSOC("Network '%s (%s)' excluded " "because of storming (%ums since last " "assoc attempt).\n", escape_essid(network->ssid, network->ssid_len), - MAC_ARG(network->bssid), + print_mac(mac, network->bssid), jiffies_to_msecs(jiffies - network->last_associate)); return 0; @@ -5684,10 +5691,10 @@ static int ipw_best_network(struct ipw_priv *priv, /* Now go through and see if the requested network is valid... */ if (priv->ieee->scan_age != 0 && time_after(jiffies, network->last_scanned + priv->ieee->scan_age)) { - IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded " + IPW_DEBUG_ASSOC("Network '%s (%s)' excluded " "because of age: %ums.\n", escape_essid(network->ssid, network->ssid_len), - MAC_ARG(network->bssid), + print_mac(mac, network->bssid), jiffies_to_msecs(jiffies - network->last_scanned)); return 0; @@ -5695,10 +5702,10 @@ static int ipw_best_network(struct ipw_priv *priv, if ((priv->config & CFG_STATIC_CHANNEL) && (network->channel != priv->channel)) { - IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded " + IPW_DEBUG_ASSOC("Network '%s (%s)' excluded " "because of channel mismatch: %d != %d.\n", escape_essid(network->ssid, network->ssid_len), - MAC_ARG(network->bssid), + print_mac(mac, network->bssid), network->channel, priv->channel); return 0; } @@ -5706,10 +5713,10 @@ static int ipw_best_network(struct ipw_priv *priv, /* Verify privacy compatability */ if (((priv->capability & CAP_PRIVACY_ON) ? 1 : 0) != ((network->capability & WLAN_CAPABILITY_PRIVACY) ? 1 : 0)) { - IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded " + IPW_DEBUG_ASSOC("Network '%s (%s)' excluded " "because of privacy mismatch: %s != %s.\n", escape_essid(network->ssid, network->ssid_len), - MAC_ARG(network->bssid), + print_mac(mac, network->bssid), priv->capability & CAP_PRIVACY_ON ? "on" : "off", network->capability & @@ -5719,48 +5726,48 @@ static int ipw_best_network(struct ipw_priv *priv, if ((priv->config & CFG_STATIC_BSSID) && memcmp(network->bssid, priv->bssid, ETH_ALEN)) { - IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded " - "because of BSSID mismatch: " MAC_FMT ".\n", + IPW_DEBUG_ASSOC("Network '%s (%s)' excluded " + "because of BSSID mismatch: %s.\n", escape_essid(network->ssid, network->ssid_len), - MAC_ARG(network->bssid), MAC_ARG(priv->bssid)); + print_mac(mac, network->bssid), print_mac(mac, priv->bssid)); return 0; } /* Filter out any incompatible freq / mode combinations */ if (!ieee80211_is_valid_mode(priv->ieee, network->mode)) { - IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded " + IPW_DEBUG_ASSOC("Network '%s (%s)' excluded " "because of invalid frequency/mode " "combination.\n", escape_essid(network->ssid, network->ssid_len), - MAC_ARG(network->bssid)); + print_mac(mac, network->bssid)); return 0; } /* Filter out invalid channel in current GEO */ if (!ieee80211_is_valid_channel(priv->ieee, network->channel)) { - IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded " + IPW_DEBUG_ASSOC("Network '%s (%s)' excluded " "because of invalid channel in current GEO\n", escape_essid(network->ssid, network->ssid_len), - MAC_ARG(network->bssid)); + print_mac(mac, network->bssid)); return 0; } /* Ensure that the rates supported by the driver are compatible with * this AP, including verification of basic rates (mandatory) */ if (!ipw_compatible_rates(priv, network, &rates)) { - IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded " + IPW_DEBUG_ASSOC("Network '%s (%s)' excluded " "because configured rate mask excludes " "AP mandatory rate.\n", escape_essid(network->ssid, network->ssid_len), - MAC_ARG(network->bssid)); + print_mac(mac, network->bssid)); return 0; } if (rates.num_rates == 0) { - IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded " + IPW_DEBUG_ASSOC("Network '%s (%s)' excluded " "because of no compatible rates.\n", escape_essid(network->ssid, network->ssid_len), - MAC_ARG(network->bssid)); + print_mac(mac, network->bssid)); return 0; } @@ -5772,9 +5779,9 @@ static int ipw_best_network(struct ipw_priv *priv, ipw_copy_rates(&match->rates, &rates); match->network = network; - IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' is a viable match.\n", + IPW_DEBUG_ASSOC("Network '%s (%s)' is a viable match.\n", escape_essid(network->ssid, network->ssid_len), - MAC_ARG(network->bssid)); + print_mac(mac, network->bssid)); return 1; } @@ -6016,6 +6023,7 @@ static void ipw_bg_adhoc_check(struct work_struct *work) static void ipw_debug_config(struct ipw_priv *priv) { + DECLARE_MAC_BUF(mac); IPW_DEBUG_INFO("Scan completed, no valid APs matched " "[CFG 0x%08X]\n", priv->config); if (priv->config & CFG_STATIC_CHANNEL) @@ -6028,8 +6036,8 @@ static void ipw_debug_config(struct ipw_priv *priv) else IPW_DEBUG_INFO("ESSID unlocked.\n"); if (priv->config & CFG_STATIC_BSSID) - IPW_DEBUG_INFO("BSSID locked to " MAC_FMT "\n", - MAC_ARG(priv->bssid)); + IPW_DEBUG_INFO("BSSID locked to %s\n", + print_mac(mac, priv->bssid)); else IPW_DEBUG_INFO("BSSID unlocked.\n"); if (priv->capability & CAP_PRIVACY_ON) @@ -7221,6 +7229,7 @@ static int ipw_associate_network(struct ipw_priv *priv, struct ipw_supported_rates *rates, int roaming) { int err; + DECLARE_MAC_BUF(mac); if (priv->config & CFG_FIXED_RATE) ipw_set_fixed_rate(priv, network->mode); @@ -7388,9 +7397,9 @@ static int ipw_associate_network(struct ipw_priv *priv, return err; } - IPW_DEBUG(IPW_DL_STATE, "associating: '%s' " MAC_FMT " \n", + IPW_DEBUG(IPW_DL_STATE, "associating: '%s' %s \n", escape_essid(priv->essid, priv->essid_len), - MAC_ARG(priv->bssid)); + print_mac(mac, priv->bssid)); return 0; } @@ -8202,6 +8211,9 @@ static void ipw_rx(struct ipw_priv *priv) struct ieee80211_hdr_4addr *header; u32 r, w, i; u8 network_packet; + DECLARE_MAC_BUF(mac); + DECLARE_MAC_BUF(mac2); + DECLARE_MAC_BUF(mac3); r = ipw_read32(priv, IPW_RX_READ_INDEX); w = ipw_read32(priv, IPW_RX_WRITE_INDEX); @@ -8328,14 +8340,17 @@ static void ipw_rx(struct ipw_priv *priv) header))) { IPW_DEBUG_DROP("Dropping: " - MAC_FMT ", " - MAC_FMT ", " - MAC_FMT "\n", - MAC_ARG(header-> + "%s, " + "%s, " + "%s\n", + print_mac(mac, + header-> addr1), - MAC_ARG(header-> + print_mac(mac2, + header-> addr2), - MAC_ARG(header-> + print_mac(mac3, + header-> addr3)); break; } @@ -8867,6 +8882,7 @@ static int ipw_wx_set_wap(struct net_device *dev, union iwreq_data *wrqu, char *extra) { struct ipw_priv *priv = ieee80211_priv(dev); + DECLARE_MAC_BUF(mac); static const unsigned char any[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff @@ -8897,8 +8913,8 @@ static int ipw_wx_set_wap(struct net_device *dev, return 0; } - IPW_DEBUG_WX("Setting mandatory BSSID to " MAC_FMT "\n", - MAC_ARG(wrqu->ap_addr.sa_data)); + IPW_DEBUG_WX("Setting mandatory BSSID to %s\n", + print_mac(mac, wrqu->ap_addr.sa_data)); memcpy(priv->bssid, wrqu->ap_addr.sa_data, ETH_ALEN); @@ -8916,6 +8932,8 @@ static int ipw_wx_get_wap(struct net_device *dev, union iwreq_data *wrqu, char *extra) { struct ipw_priv *priv = ieee80211_priv(dev); + DECLARE_MAC_BUF(mac); + /* If we are associated, trying to associate, or have a statically * configured BSSID then return that; otherwise return ANY */ mutex_lock(&priv->mutex); @@ -8926,8 +8944,8 @@ static int ipw_wx_get_wap(struct net_device *dev, } else memset(wrqu->ap_addr.sa_data, 0, ETH_ALEN); - IPW_DEBUG_WX("Getting WAP BSSID: " MAC_FMT "\n", - MAC_ARG(wrqu->ap_addr.sa_data)); + IPW_DEBUG_WX("Getting WAP BSSID: %s\n", + print_mac(mac, wrqu->ap_addr.sa_data)); mutex_unlock(&priv->mutex); return 0; } @@ -10133,6 +10151,7 @@ static int ipw_tx_skb(struct ipw_priv *priv, struct ieee80211_txb *txb, u8 id, hdr_len, unicast; u16 remaining_bytes; int fc; + DECLARE_MAC_BUF(mac); hdr_len = ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_ctl)); switch (priv->ieee->iw_mode) { @@ -10143,8 +10162,8 @@ static int ipw_tx_skb(struct ipw_priv *priv, struct ieee80211_txb *txb, id = ipw_add_station(priv, hdr->addr1); if (id == IPW_INVALID_STATION) { IPW_WARNING("Attempt to send data to " - "invalid cell: " MAC_FMT "\n", - MAC_ARG(hdr->addr1)); + "invalid cell: %s\n", + print_mac(mac, hdr->addr1)); goto drop; } } @@ -10460,13 +10479,15 @@ static int ipw_net_set_mac_address(struct net_device *dev, void *p) { struct ipw_priv *priv = ieee80211_priv(dev); struct sockaddr *addr = p; + DECLARE_MAC_BUF(mac); + if (!is_valid_ether_addr(addr->sa_data)) return -EADDRNOTAVAIL; mutex_lock(&priv->mutex); priv->config |= CFG_CUSTOM_MAC; memcpy(priv->mac_addr, addr->sa_data, ETH_ALEN); - printk(KERN_INFO "%s: Setting MAC to " MAC_FMT "\n", - priv->net_dev->name, MAC_ARG(priv->mac_addr)); + printk(KERN_INFO "%s: Setting MAC to %s\n", + priv->net_dev->name, print_mac(mac, priv->mac_addr)); queue_work(priv->workqueue, &priv->adapter_restart); mutex_unlock(&priv->mutex); return 0; diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-rs.c b/drivers/net/wireless/iwlwifi/iwl-3945-rs.c index a4f4c8798a83..b0d28ae0b324 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945-rs.c +++ b/drivers/net/wireless/iwlwifi/iwl-3945-rs.c @@ -646,6 +646,7 @@ static struct ieee80211_rate *rs_get_rate(void *priv_rate, struct sta_info *sta; u16 fc, rate_mask; struct iwl_priv *priv = (struct iwl_priv *)priv_rate; + DECLARE_MAC_BUF(mac); IWL_DEBUG_RATE("enter\n"); @@ -681,8 +682,8 @@ static struct ieee80211_rate *rs_get_rate(void *priv_rate, u8 sta_id = iwl_hw_find_station(priv, hdr->addr1); if (sta_id == IWL_INVALID_STATION) { - IWL_DEBUG_RATE("LQ: ADD station " MAC_FMT "\n", - MAC_ARG(hdr->addr1)); + IWL_DEBUG_RATE("LQ: ADD station %s\n", + print_mac(mac, hdr->addr1)); sta_id = iwl_add_station(priv, hdr->addr1, 0, CMD_ASYNC); } diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c index 26f03a0b878d..55f7d89aad8d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945.c +++ b/drivers/net/wireless/iwlwifi/iwl-3945.c @@ -457,13 +457,16 @@ static void iwl3945_rx_reply_rx(struct iwl_priv *priv, } case IEEE80211_STYPE_PROBE_REQ:{ + DECLARE_MAC_BUF(mac1); + DECLARE_MAC_BUF(mac2); + DECLARE_MAC_BUF(mac3); if (priv->iw_mode == IEEE80211_IF_TYPE_IBSS) IWL_DEBUG_DROP - ("Dropping (non network): " MAC_FMT - ", " MAC_FMT ", " MAC_FMT "\n", - MAC_ARG(header->addr1), - MAC_ARG(header->addr2), - MAC_ARG(header->addr3)); + ("Dropping (non network): %s" + ", %s, %s\n", + print_mac(mac1, header->addr1), + print_mac(mac2, header->addr2), + print_mac(mac3, header->addr3)); return; } } @@ -474,18 +477,22 @@ static void iwl3945_rx_reply_rx(struct iwl_priv *priv, case IEEE80211_FTYPE_CTL: break; - case IEEE80211_FTYPE_DATA: + case IEEE80211_FTYPE_DATA: { + DECLARE_MAC_BUF(mac1); + DECLARE_MAC_BUF(mac2); + DECLARE_MAC_BUF(mac3); + if (unlikely(is_duplicate_packet(priv, header))) - IWL_DEBUG_DROP("Dropping (dup): " MAC_FMT ", " - MAC_FMT ", " MAC_FMT "\n", - MAC_ARG(header->addr1), - MAC_ARG(header->addr2), - MAC_ARG(header->addr3)); + IWL_DEBUG_DROP("Dropping (dup): %s, %s, %s\n", + print_mac(mac1, header->addr1), + print_mac(mac2, header->addr2), + print_mac(mac3, header->addr3)); else iwl3945_handle_data_packet(priv, 1, rxb, &stats, phy_flags); break; } + } } int iwl_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv, void *ptr, @@ -563,6 +570,7 @@ u8 iwl_hw_find_station(struct iwl_priv *priv, const u8 *addr) int i; int ret = IWL_INVALID_STATION; unsigned long flags; + DECLARE_MAC_BUF(mac); spin_lock_irqsave(&priv->sta_lock, flags); for (i = IWL_STA_ID; i < priv->hw_setting.max_stations; i++) @@ -573,8 +581,8 @@ u8 iwl_hw_find_station(struct iwl_priv *priv, const u8 *addr) goto out; } - IWL_DEBUG_INFO("can not find STA " MAC_FMT " (total %d)\n", - MAC_ARG(addr), priv->num_stations); + IWL_DEBUG_INFO("can not find STA %s (total %d)\n", + print_mac(mac, addr), priv->num_stations); out: spin_unlock_irqrestore(&priv->sta_lock, flags); return ret; diff --git a/drivers/net/wireless/iwlwifi/iwl-4965-rs.c b/drivers/net/wireless/iwlwifi/iwl-4965-rs.c index f3638607d641..7b74481f5282 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965-rs.c +++ b/drivers/net/wireless/iwlwifi/iwl-4965-rs.c @@ -1737,10 +1737,11 @@ static struct ieee80211_rate *rs_get_rate(void *priv_rate, if ((priv->iw_mode == IEEE80211_IF_TYPE_IBSS) && !lq->ibss_sta_added) { u8 sta_id = iwl_hw_find_station(priv, hdr->addr1); + DECLARE_MAC_BUF(mac); if (sta_id == IWL_INVALID_STATION) { - IWL_DEBUG_RATE("LQ: ADD station " MAC_FMT "\n", - MAC_ARG(hdr->addr1)); + IWL_DEBUG_RATE("LQ: ADD station %s\n", + print_mac(mac, hdr->addr1)); sta_id = iwl_add_station(priv, hdr->addr1, 0, CMD_ASYNC); } @@ -1811,14 +1812,16 @@ static void rs_rate_init(void *priv_rate, void *priv_sta, crl->ibss_sta_added = 0; if (priv->iw_mode == IEEE80211_IF_TYPE_AP) { u8 sta_id = iwl_hw_find_station(priv, sta->addr); + DECLARE_MAC_BUF(mac); + /* for IBSS the call are from tasklet */ - IWL_DEBUG_HT("LQ: ADD station " MAC_FMT " \n", - MAC_ARG(sta->addr)); + IWL_DEBUG_HT("LQ: ADD station %s\n", + print_mac(mac, sta->addr)); if (sta_id == IWL_INVALID_STATION) { - IWL_DEBUG_RATE("LQ: ADD station " MAC_FMT "\n", - MAC_ARG(sta->addr)); - sta_id = iwl_add_station(priv, + IWL_DEBUG_RATE("LQ: ADD station %s\n", + print_mac(mac, sta->addr)); + sta_id = iwl_add_station(priv, sta->addr, 0, CMD_ASYNC); } if ((sta_id != IWL_INVALID_STATION)) { diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c index ba35b3ac7c7e..e624f2a41e0e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965.c +++ b/drivers/net/wireless/iwlwifi/iwl-4965.c @@ -164,6 +164,7 @@ u8 iwl_hw_find_station(struct iwl_priv *priv, const u8 *addr) int start = 0; int ret = IWL_INVALID_STATION; unsigned long flags; + DECLARE_MAC_BUF(mac); if ((priv->iw_mode == IEEE80211_IF_TYPE_IBSS) || (priv->iw_mode == IEEE80211_IF_TYPE_AP)) @@ -181,8 +182,8 @@ u8 iwl_hw_find_station(struct iwl_priv *priv, const u8 *addr) goto out; } - IWL_DEBUG_ASSOC("can not find STA " MAC_FMT " total %d\n", - MAC_ARG(addr), priv->num_stations); + IWL_DEBUG_ASSOC("can not find STA %s total %d\n", + print_mac(mac, addr), priv->num_stations); out: spin_unlock_irqrestore(&priv->sta_lock, flags); @@ -3909,12 +3910,15 @@ static void iwl4965_rx_reply_rx(struct iwl_priv *priv, case IEEE80211_STYPE_PROBE_REQ: if ((priv->iw_mode == IEEE80211_IF_TYPE_IBSS) && !iwl_is_associated(priv)) { + DECLARE_MAC_BUF(mac1); + DECLARE_MAC_BUF(mac2); + DECLARE_MAC_BUF(mac3); + IWL_DEBUG_DROP("Dropping (non network): " - MAC_FMT ", " MAC_FMT ", " - MAC_FMT "\n", - MAC_ARG(header->addr1), - MAC_ARG(header->addr2), - MAC_ARG(header->addr3)); + "%s, %s, %s\n", + print_mac(mac1, header->addr1), + print_mac(mac2, header->addr2), + print_mac(mac3, header->addr3)); return; } } @@ -3936,28 +3940,31 @@ static void iwl4965_rx_reply_rx(struct iwl_priv *priv, break; - case IEEE80211_FTYPE_DATA: + case IEEE80211_FTYPE_DATA: { + DECLARE_MAC_BUF(mac1); + DECLARE_MAC_BUF(mac2); + DECLARE_MAC_BUF(mac3); + if (priv->iw_mode == IEEE80211_IF_TYPE_AP) iwl4965_update_ps_mode(priv, fc & IEEE80211_FCTL_PM, header->addr2); if (unlikely(!network_packet)) IWL_DEBUG_DROP("Dropping (non network): " - MAC_FMT ", " MAC_FMT ", " - MAC_FMT "\n", - MAC_ARG(header->addr1), - MAC_ARG(header->addr2), - MAC_ARG(header->addr3)); + "%s, %s, %s\n", + print_mac(mac1, header->addr1), + print_mac(mac2, header->addr2), + print_mac(mac3, header->addr3)); else if (unlikely(is_duplicate_packet(priv, header))) - IWL_DEBUG_DROP("Dropping (dup): " MAC_FMT ", " - MAC_FMT ", " MAC_FMT "\n", - MAC_ARG(header->addr1), - MAC_ARG(header->addr2), - MAC_ARG(header->addr3)); + IWL_DEBUG_DROP("Dropping (dup): %s, %s, %s\n", + print_mac(mac1, header->addr1), + print_mac(mac2, header->addr2), + print_mac(mac3, header->addr3)); else iwl4965_handle_data_packet(priv, 1, include_phy, rxb, &stats); break; + } default: break; @@ -4106,10 +4113,12 @@ static void iwl4965_rx_reply_compressed_ba(struct iwl_priv *priv, /* TODO: Need to get this copy more sefely - now good for debug */ /* - IWL_DEBUG_TX_REPLY("REPLY_COMPRESSED_BA [%d]Received from " MAC_FMT ", - sta_id = %d\n", + { + DECLARE_MAC_BUF(mac); + IWL_DEBUG_TX_REPLY("REPLY_COMPRESSED_BA [%d]Received from %s, " + "sta_id = %d\n", agg->wait_for_ba, - MAC_ARG((u8*) &ba_resp->sta_addr_lo32), + print_mac(mac, (u8*) &ba_resp->sta_addr_lo32), ba_resp->sta_id); IWL_DEBUG_TX_REPLY("TID = %d, SeqCtl = %d, bitmap = 0x%X%X, scd_flow = " "%d, scd_ssn = %d\n", @@ -4123,6 +4132,7 @@ static void iwl4965_rx_reply_compressed_ba(struct iwl_priv *priv, agg->start_idx, agg->bitmap1, agg->bitmap0); + } */ iwl4965_tx_status_reply_compressed_ba(priv, agg, ba_resp); /* releases all the TFDs until the SSN */ @@ -4539,14 +4549,15 @@ int iwl_mac_ht_tx_agg_start(struct ieee80211_hw *hw, u8 *da, u16 tid, int ssn = -1; unsigned long flags; struct iwl_tid_data *tid_data; + DECLARE_MAC_BUF(mac); if (likely(tid < ARRAY_SIZE(default_tid_to_tx_fifo))) tx_fifo = default_tid_to_tx_fifo[tid]; else return -EINVAL; - IWL_WARNING("iwl-AGG iwl_mac_ht_tx_agg_start on da=" MAC_FMT - " tid=%d\n", MAC_ARG(da), tid); + IWL_WARNING("iwl-AGG iwl_mac_ht_tx_agg_start on da=%s" + " tid=%d\n", print_mac(mac, da), tid); sta_id = iwl_hw_find_station(priv, da); if (sta_id == IWL_INVALID_STATION) @@ -4577,6 +4588,8 @@ int iwl_mac_ht_tx_agg_stop(struct ieee80211_hw *hw, u8 *da, u16 tid, int tx_fifo_id, txq_id, sta_id, ssn = -1; struct iwl_tid_data *tid_data; int rc; + DECLARE_MAC_BUF(mac); + if (!da) { IWL_ERROR("%s: da = NULL\n", __func__); return -EINVAL; @@ -4602,8 +4615,8 @@ int iwl_mac_ht_tx_agg_stop(struct ieee80211_hw *hw, u8 *da, u16 tid, return rc; iwl4965_ba_status(priv, tid, BA_STATUS_INITIATOR_DELBA); - IWL_DEBUG_INFO("iwl_mac_ht_tx_agg_stop on da=" MAC_FMT " tid=%d\n", - MAC_ARG(da), tid); + IWL_DEBUG_INFO("iwl_mac_ht_tx_agg_stop on da=%s tid=%d\n", + print_mac(mac, da), tid); return 0; } @@ -4613,9 +4626,10 @@ int iwl_mac_ht_rx_agg_start(struct ieee80211_hw *hw, u8 *da, { struct iwl_priv *priv = hw->priv; int sta_id; + DECLARE_MAC_BUF(mac); - IWL_WARNING("iwl-AGG iwl_mac_ht_rx_agg_start on da=" MAC_FMT - " tid=%d\n", MAC_ARG(da), tid); + IWL_WARNING("iwl-AGG iwl_mac_ht_rx_agg_start on da=%s" + " tid=%d\n", print_mac(mac, da), tid); sta_id = iwl_hw_find_station(priv, da); iwl4965_sta_modify_add_ba_tid(priv, sta_id, tid, start_seq_num); return 0; @@ -4626,9 +4640,10 @@ int iwl_mac_ht_rx_agg_stop(struct ieee80211_hw *hw, u8 *da, { struct iwl_priv *priv = hw->priv; int sta_id; + DECLARE_MAC_BUF(mac); - IWL_WARNING("iwl-AGG iwl_mac_ht_rx_agg_stop on da=" MAC_FMT " tid=%d\n", - MAC_ARG(da), tid); + IWL_WARNING("iwl-AGG iwl_mac_ht_rx_agg_stop on da=%s tid=%d\n", + print_mac(mac, da), tid); sta_id = iwl_hw_find_station(priv, da); iwl4965_sta_modify_del_ba_tid(priv, sta_id, tid); return 0; diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index 474b6402040c..cc405f4a8647 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c @@ -460,6 +460,7 @@ u8 iwl_add_station(struct iwl_priv *priv, const u8 *addr, int is_ap, u8 flags) int index = IWL_INVALID_STATION; struct iwl_station_entry *station; unsigned long flags_spin; + DECLARE_MAC_BUF(mac); spin_lock_irqsave(&priv->sta_lock, flags_spin); if (is_ap) @@ -492,7 +493,7 @@ u8 iwl_add_station(struct iwl_priv *priv, const u8 *addr, int is_ap, u8 flags) return index; } - IWL_DEBUG_ASSOC("Add STA ID %d: " MAC_FMT "\n", index, MAC_ARG(addr)); + IWL_DEBUG_ASSOC("Add STA ID %d: %s\n", index, print_mac(mac, addr)); station = &priv->stations[index]; station->used = 1; priv->num_stations++; @@ -1064,6 +1065,7 @@ static int iwl_commit_rxon(struct iwl_priv *priv) /* cast away the const for active_rxon in this function */ struct iwl_rxon_cmd *active_rxon = (void *)&priv->active_rxon; int rc = 0; + DECLARE_MAC_BUF(mac); if (!iwl_is_alive(priv)) return -1; @@ -1134,11 +1136,11 @@ static int iwl_commit_rxon(struct iwl_priv *priv) IWL_DEBUG_INFO("Sending RXON\n" "* with%s RXON_FILTER_ASSOC_MSK\n" "* channel = %d\n" - "* bssid = " MAC_FMT "\n", + "* bssid = %s\n", ((priv->staging_rxon.filter_flags & RXON_FILTER_ASSOC_MSK) ? "" : "out"), le16_to_cpu(priv->staging_rxon.channel), - MAC_ARG(priv->staging_rxon.bssid_addr)); + print_mac(mac, priv->staging_rxon.bssid_addr)); /* Apply the new configuration */ rc = iwl_send_cmd_pdu(priv, REPLY_RXON, @@ -2693,7 +2695,9 @@ static int iwl_get_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr) /* If this frame is part of a IBSS network, then we use the * target specific station id */ - case IEEE80211_IF_TYPE_IBSS: + case IEEE80211_IF_TYPE_IBSS: { + DECLARE_MAC_BUF(mac); + sta_id = iwl_hw_find_station(priv, hdr->addr1); if (sta_id != IWL_INVALID_STATION) return sta_id; @@ -2703,12 +2707,12 @@ static int iwl_get_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr) if (sta_id != IWL_INVALID_STATION) return sta_id; - IWL_DEBUG_DROP("Station " MAC_FMT " not in station map. " + IWL_DEBUG_DROP("Station %s not in station map. " "Defaulting to broadcast...\n", - MAC_ARG(hdr->addr1)); + print_mac(mac, hdr->addr1)); iwl_print_hex_dump(IWL_DL_DROP, (u8 *) hdr, sizeof(*hdr)); return priv->hw_setting.bcast_sta_id; - + } default: IWL_WARNING("Unkown mode of operation: %d", priv->iw_mode); return priv->hw_setting.bcast_sta_id; @@ -2781,8 +2785,10 @@ static int iwl_tx_skb(struct iwl_priv *priv, hdr_len = ieee80211_get_hdrlen(fc); sta_id = iwl_get_sta_id(priv, hdr); if (sta_id == IWL_INVALID_STATION) { - IWL_DEBUG_DROP("Dropping - INVALID STATION: " MAC_FMT "\n", - MAC_ARG(hdr->addr1)); + DECLARE_MAC_BUF(mac); + + IWL_DEBUG_DROP("Dropping - INVALID STATION: %s\n", + print_mac(mac, hdr->addr1)); goto drop; } @@ -4385,6 +4391,8 @@ int iwl_tx_queue_update_write_ptr(struct iwl_priv *priv, #ifdef CONFIG_IWLWIFI_DEBUG static void iwl_print_rx_config_cmd(struct iwl_rxon_cmd *rxon) { + DECLARE_MAC_BUF(mac); + IWL_DEBUG_RADIO("RX CONFIG:\n"); iwl_print_hex_dump(IWL_DL_RADIO, (u8 *) rxon, sizeof(*rxon)); IWL_DEBUG_RADIO("u16 channel: 0x%x\n", le16_to_cpu(rxon->channel)); @@ -4395,10 +4403,10 @@ static void iwl_print_rx_config_cmd(struct iwl_rxon_cmd *rxon) IWL_DEBUG_RADIO("u8 ofdm_basic_rates: 0x%02x\n", rxon->ofdm_basic_rates); IWL_DEBUG_RADIO("u8 cck_basic_rates: 0x%02x\n", rxon->cck_basic_rates); - IWL_DEBUG_RADIO("u8[6] node_addr: " MAC_FMT "\n", - MAC_ARG(rxon->node_addr)); - IWL_DEBUG_RADIO("u8[6] bssid_addr: " MAC_FMT "\n", - MAC_ARG(rxon->bssid_addr)); + IWL_DEBUG_RADIO("u8[6] node_addr: %s\n", + print_mac(mac, rxon->node_addr)); + IWL_DEBUG_RADIO("u8[6] bssid_addr: %s\n", + print_mac(mac, rxon->bssid_addr)); IWL_DEBUG_RADIO("u16 assoc_id: 0x%x\n", le16_to_cpu(rxon->assoc_id)); } #endif @@ -6322,6 +6330,7 @@ static void iwl_down(struct iwl_priv *priv) static int __iwl_up(struct iwl_priv *priv) { + DECLARE_MAC_BUF(mac); int rc, i; if (test_bit(STATUS_EXIT_PENDING, &priv->status)) { @@ -6381,8 +6390,8 @@ static int __iwl_up(struct iwl_priv *priv) /* MAC Address location in EEPROM same for 3945/4965 */ get_eeprom_mac(priv, priv->mac_addr); - IWL_DEBUG_INFO("MAC address: " MAC_FMT "\n", - MAC_ARG(priv->mac_addr)); + IWL_DEBUG_INFO("MAC address: %s\n", + print_mac(mac, priv->mac_addr)); SET_IEEE80211_PERM_ADDR(priv->hw, priv->mac_addr); @@ -6728,6 +6737,7 @@ static void iwl_bg_post_associate(struct work_struct *data) int rc = 0; struct ieee80211_conf *conf = NULL; + DECLARE_MAC_BUF(mac); if (priv->iw_mode == IEEE80211_IF_TYPE_AP) { IWL_ERROR("%s Should not be called in AP mode\n", __FUNCTION__); @@ -6735,8 +6745,9 @@ static void iwl_bg_post_associate(struct work_struct *data) } - IWL_DEBUG_ASSOC("Associated as %d to: " MAC_FMT "\n", - priv->assoc_id, MAC_ARG(priv->active_rxon.bssid_addr)); + IWL_DEBUG_ASSOC("Associated as %d to: %s\n", + priv->assoc_id, + print_mac(mac, priv->active_rxon.bssid_addr)); if (test_bit(STATUS_EXIT_PENDING, &priv->status)) return; @@ -6916,11 +6927,12 @@ static int iwl_mac_add_interface(struct ieee80211_hw *hw, { struct iwl_priv *priv = hw->priv; unsigned long flags; + DECLARE_MAC_BUF(mac); IWL_DEBUG_MAC80211("enter: id %d, type %d\n", conf->if_id, conf->type); if (conf->mac_addr) - IWL_DEBUG_MAC80211("enter: MAC " MAC_FMT "\n", - MAC_ARG(conf->mac_addr)); + IWL_DEBUG_MAC80211("enter: MAC %s\n", + print_mac(mac, conf->mac_addr)); if (priv->interface_id) { IWL_DEBUG_MAC80211("leave - interface_id != 0\n"); @@ -7094,6 +7106,7 @@ static int iwl_mac_config_interface(struct ieee80211_hw *hw, int if_id, struct ieee80211_if_conf *conf) { struct iwl_priv *priv = hw->priv; + DECLARE_MAC_BUF(mac); unsigned long flags; int rc; @@ -7111,8 +7124,8 @@ static int iwl_mac_config_interface(struct ieee80211_hw *hw, int if_id, IWL_DEBUG_MAC80211("enter: interface id %d\n", if_id); if (conf->bssid) - IWL_DEBUG_MAC80211("bssid: " MAC_FMT "\n", - MAC_ARG(conf->bssid)); + IWL_DEBUG_MAC80211("bssid: %s\n", + print_mac(mac, conf->bssid)); if (unlikely(test_bit(STATUS_SCANNING, &priv->status)) && !(priv->hw->flags & IEEE80211_HW_NO_PROBE_FILTERING)) { @@ -7131,8 +7144,8 @@ static int iwl_mac_config_interface(struct ieee80211_hw *hw, int if_id, if (!conf->bssid) { conf->bssid = priv->mac_addr; memcpy(priv->bssid, priv->mac_addr, ETH_ALEN); - IWL_DEBUG_MAC80211("bssid was set to: " MAC_FMT "\n", - MAC_ARG(conf->bssid)); + IWL_DEBUG_MAC80211("bssid was set to: %s\n", + print_mac(mac, conf->bssid)); } if (priv->ibss_beacon) dev_kfree_skb(priv->ibss_beacon); @@ -7282,8 +7295,10 @@ static int iwl_mac_set_key(struct ieee80211_hw *hw, set_key_cmd cmd, sta_id = iwl_hw_find_station(priv, addr); if (sta_id == IWL_INVALID_STATION) { - IWL_DEBUG_MAC80211("leave - " MAC_FMT " not in station map.\n", - MAC_ARG(addr)); + DECLARE_MAC_BUF(mac); + + IWL_DEBUG_MAC80211("leave - %s not in station map.\n", + print_mac(mac, addr)); return -EINVAL; } diff --git a/drivers/net/wireless/iwlwifi/iwl4965-base.c b/drivers/net/wireless/iwlwifi/iwl4965-base.c index b79dabc8c01c..6cea3118b7c1 100644 --- a/drivers/net/wireless/iwlwifi/iwl4965-base.c +++ b/drivers/net/wireless/iwlwifi/iwl4965-base.c @@ -459,6 +459,7 @@ u8 iwl_add_station(struct iwl_priv *priv, const u8 *addr, int is_ap, u8 flags) int index = IWL_INVALID_STATION; struct iwl_station_entry *station; unsigned long flags_spin; + DECLARE_MAC_BUF(mac); spin_lock_irqsave(&priv->sta_lock, flags_spin); if (is_ap) @@ -493,7 +494,7 @@ u8 iwl_add_station(struct iwl_priv *priv, const u8 *addr, int is_ap, u8 flags) } - IWL_DEBUG_ASSOC("Add STA ID %d: " MAC_FMT "\n", index, MAC_ARG(addr)); + IWL_DEBUG_ASSOC("Add STA ID %d: %s\n", index, print_mac(mac, addr)); station = &priv->stations[index]; station->used = 1; priv->num_stations++; @@ -1083,6 +1084,7 @@ static int iwl_commit_rxon(struct iwl_priv *priv) { /* cast away the const for active_rxon in this function */ struct iwl_rxon_cmd *active_rxon = (void *)&priv->active_rxon; + DECLARE_MAC_BUF(mac); int rc = 0; if (!iwl_is_alive(priv)) @@ -1160,11 +1162,11 @@ static int iwl_commit_rxon(struct iwl_priv *priv) IWL_DEBUG_INFO("Sending RXON\n" "* with%s RXON_FILTER_ASSOC_MSK\n" "* channel = %d\n" - "* bssid = " MAC_FMT "\n", + "* bssid = %s\n", ((priv->staging_rxon.filter_flags & RXON_FILTER_ASSOC_MSK) ? "" : "out"), le16_to_cpu(priv->staging_rxon.channel), - MAC_ARG(priv->staging_rxon.bssid_addr)); + print_mac(mac, priv->staging_rxon.bssid_addr)); /* Apply the new configuration */ rc = iwl_send_cmd_pdu(priv, REPLY_RXON, @@ -2748,6 +2750,7 @@ static int iwl_get_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr) { int sta_id; u16 fc = le16_to_cpu(hdr->frame_control); + DECLARE_MAC_BUF(mac); /* If this frame is broadcast or not data then use the broadcast * station id */ @@ -2781,9 +2784,9 @@ static int iwl_get_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr) if (sta_id != IWL_INVALID_STATION) return sta_id; - IWL_DEBUG_DROP("Station " MAC_FMT " not in station map. " + IWL_DEBUG_DROP("Station %s not in station map. " "Defaulting to broadcast...\n", - MAC_ARG(hdr->addr1)); + print_mac(mac, hdr->addr1)); iwl_print_hex_dump(IWL_DL_DROP, (u8 *) hdr, sizeof(*hdr)); return priv->hw_setting.bcast_sta_id; @@ -2859,8 +2862,10 @@ static int iwl_tx_skb(struct iwl_priv *priv, hdr_len = ieee80211_get_hdrlen(fc); sta_id = iwl_get_sta_id(priv, hdr); if (sta_id == IWL_INVALID_STATION) { - IWL_DEBUG_DROP("Dropping - INVALID STATION: " MAC_FMT "\n", - MAC_ARG(hdr->addr1)); + DECLARE_MAC_BUF(mac); + + IWL_DEBUG_DROP("Dropping - INVALID STATION: %s\n", + print_mac(mac, hdr->addr1)); goto drop; } @@ -4703,6 +4708,8 @@ int iwl_tx_queue_update_write_ptr(struct iwl_priv *priv, #ifdef CONFIG_IWLWIFI_DEBUG static void iwl_print_rx_config_cmd(struct iwl_rxon_cmd *rxon) { + DECLARE_MAC_BUF(mac); + IWL_DEBUG_RADIO("RX CONFIG:\n"); iwl_print_hex_dump(IWL_DL_RADIO, (u8 *) rxon, sizeof(*rxon)); IWL_DEBUG_RADIO("u16 channel: 0x%x\n", le16_to_cpu(rxon->channel)); @@ -4713,10 +4720,10 @@ static void iwl_print_rx_config_cmd(struct iwl_rxon_cmd *rxon) IWL_DEBUG_RADIO("u8 ofdm_basic_rates: 0x%02x\n", rxon->ofdm_basic_rates); IWL_DEBUG_RADIO("u8 cck_basic_rates: 0x%02x\n", rxon->cck_basic_rates); - IWL_DEBUG_RADIO("u8[6] node_addr: " MAC_FMT "\n", - MAC_ARG(rxon->node_addr)); - IWL_DEBUG_RADIO("u8[6] bssid_addr: " MAC_FMT "\n", - MAC_ARG(rxon->bssid_addr)); + IWL_DEBUG_RADIO("u8[6] node_addr: %s\n", + print_mac(mac, rxon->node_addr)); + IWL_DEBUG_RADIO("u8[6] bssid_addr: %s\n", + print_mac(mac, rxon->bssid_addr)); IWL_DEBUG_RADIO("u16 assoc_id: 0x%x\n", le16_to_cpu(rxon->assoc_id)); } #endif @@ -6670,6 +6677,7 @@ static void iwl_down(struct iwl_priv *priv) static int __iwl_up(struct iwl_priv *priv) { + DECLARE_MAC_BUF(mac); int rc, i; u32 hw_rf_kill = 0; @@ -6742,8 +6750,8 @@ static int __iwl_up(struct iwl_priv *priv) /* MAC Address location in EEPROM same for 3945/4965 */ get_eeprom_mac(priv, priv->mac_addr); - IWL_DEBUG_INFO("MAC address: " MAC_FMT "\n", - MAC_ARG(priv->mac_addr)); + IWL_DEBUG_INFO("MAC address: %s\n", + print_mac(mac, priv->mac_addr)); SET_IEEE80211_PERM_ADDR(priv->hw, priv->mac_addr); @@ -7096,14 +7104,16 @@ static void iwl_bg_post_associate(struct work_struct *data) int rc = 0; struct ieee80211_conf *conf = NULL; + DECLARE_MAC_BUF(mac); if (priv->iw_mode == IEEE80211_IF_TYPE_AP) { IWL_ERROR("%s Should not be called in AP mode\n", __FUNCTION__); return; } - IWL_DEBUG_ASSOC("Associated as %d to: " MAC_FMT "\n", - priv->assoc_id, MAC_ARG(priv->active_rxon.bssid_addr)); + IWL_DEBUG_ASSOC("Associated as %d to: %s\n", + priv->assoc_id, + print_mac(mac, priv->active_rxon.bssid_addr)); if (test_bit(STATUS_EXIT_PENDING, &priv->status)) @@ -7299,11 +7309,12 @@ static int iwl_mac_add_interface(struct ieee80211_hw *hw, { struct iwl_priv *priv = hw->priv; unsigned long flags; + DECLARE_MAC_BUF(mac); IWL_DEBUG_MAC80211("enter: id %d, type %d\n", conf->if_id, conf->type); if (conf->mac_addr) - IWL_DEBUG_MAC80211("enter: MAC " MAC_FMT "\n", - MAC_ARG(conf->mac_addr)); + IWL_DEBUG_MAC80211("enter: MAC %s\n", + print_mac(mac, conf->mac_addr)); if (priv->interface_id) { IWL_DEBUG_MAC80211("leave - interface_id != 0\n"); @@ -7494,6 +7505,7 @@ static int iwl_mac_config_interface(struct ieee80211_hw *hw, int if_id, struct ieee80211_if_conf *conf) { struct iwl_priv *priv = hw->priv; + DECLARE_MAC_BUF(mac); unsigned long flags; int rc; @@ -7511,8 +7523,8 @@ static int iwl_mac_config_interface(struct ieee80211_hw *hw, int if_id, IWL_DEBUG_MAC80211("enter: interface id %d\n", if_id); if (conf->bssid) - IWL_DEBUG_MAC80211("bssid: " MAC_FMT "\n", - MAC_ARG(conf->bssid)); + IWL_DEBUG_MAC80211("bssid: %s\n", + print_mac(mac, conf->bssid)); if (unlikely(test_bit(STATUS_SCANNING, &priv->status)) && !(priv->hw->flags & IEEE80211_HW_NO_PROBE_FILTERING)) { @@ -7531,8 +7543,8 @@ static int iwl_mac_config_interface(struct ieee80211_hw *hw, int if_id, if (!conf->bssid) { conf->bssid = priv->mac_addr; memcpy(priv->bssid, priv->mac_addr, ETH_ALEN); - IWL_DEBUG_MAC80211("bssid was set to: " MAC_FMT "\n", - MAC_ARG(conf->bssid)); + IWL_DEBUG_MAC80211("bssid was set to: %s\n", + print_mac(mac, conf->bssid)); } if (priv->ibss_beacon) dev_kfree_skb(priv->ibss_beacon); @@ -7666,6 +7678,7 @@ static int iwl_mac_set_key(struct ieee80211_hw *hw, set_key_cmd cmd, struct ieee80211_key_conf *key) { struct iwl_priv *priv = hw->priv; + DECLARE_MAC_BUF(mac); int rc = 0; u8 sta_id; @@ -7682,8 +7695,8 @@ static int iwl_mac_set_key(struct ieee80211_hw *hw, set_key_cmd cmd, sta_id = iwl_hw_find_station(priv, addr); if (sta_id == IWL_INVALID_STATION) { - IWL_DEBUG_MAC80211("leave - " MAC_FMT " not in station map.\n", - MAC_ARG(addr)); + IWL_DEBUG_MAC80211("leave - %s not in station map.\n", + print_mac(mac, addr)); return -EINVAL; } diff --git a/drivers/net/wireless/libertas/assoc.c b/drivers/net/wireless/libertas/assoc.c index 3131afcf4590..2c6ddb1f0072 100644 --- a/drivers/net/wireless/libertas/assoc.c +++ b/drivers/net/wireless/libertas/assoc.c @@ -16,6 +16,7 @@ static const u8 bssid_off[ETH_ALEN] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; static void print_assoc_req(const char * extra, struct assoc_request * assoc_req) { + DECLARE_MAC_BUF(mac); lbs_deb_assoc( "#### Association Request: %s\n" " flags: 0x%08lX\n" @@ -23,13 +24,13 @@ static void print_assoc_req(const char * extra, struct assoc_request * assoc_req " channel: %d\n" " band: %d\n" " mode: %d\n" - " BSSID: " MAC_FMT "\n" + " BSSID: %s\n" " Encryption:%s%s%s\n" " auth: %d\n", extra, assoc_req->flags, escape_essid(assoc_req->ssid, assoc_req->ssid_len), assoc_req->channel, assoc_req->band, assoc_req->mode, - MAC_ARG(assoc_req->bssid), + print_mac(mac, assoc_req->bssid), assoc_req->secinfo.WPAenabled ? " WPA" : "", assoc_req->secinfo.WPA2enabled ? " WPA2" : "", assoc_req->secinfo.wep_enabled ? " WEP" : "", @@ -104,16 +105,17 @@ static int assoc_helper_bssid(wlan_private *priv, wlan_adapter *adapter = priv->adapter; int ret = 0; struct bss_descriptor * bss; + DECLARE_MAC_BUF(mac); - lbs_deb_enter_args(LBS_DEB_ASSOC, "BSSID " MAC_FMT, - MAC_ARG(assoc_req->bssid)); + lbs_deb_enter_args(LBS_DEB_ASSOC, "BSSID %s", + print_mac(mac, assoc_req->bssid)); /* Search for index position in list for requested MAC */ bss = libertas_find_bssid_in_list(adapter, assoc_req->bssid, assoc_req->mode); if (bss == NULL) { - lbs_deb_assoc("ASSOC: WAP: BSSID " MAC_FMT " not found, " - "cannot associate.\n", MAC_ARG(assoc_req->bssid)); + lbs_deb_assoc("ASSOC: WAP: BSSID %s not found, " + "cannot associate.\n", print_mac(mac, assoc_req->bssid)); goto out; } @@ -481,6 +483,7 @@ void libertas_association_worker(struct work_struct *work) struct assoc_request * assoc_req = NULL; int ret = 0; int find_any_ssid = 0; + DECLARE_MAC_BUF(mac); lbs_deb_enter(LBS_DEB_ASSOC); @@ -629,10 +632,10 @@ void libertas_association_worker(struct work_struct *work) if (success) { lbs_deb_assoc("ASSOC: association attempt successful. " - "Associated to '%s' (" MAC_FMT ")\n", + "Associated to '%s' (%s)\n", escape_essid(adapter->curbssparams.ssid, adapter->curbssparams.ssid_len), - MAC_ARG(adapter->curbssparams.bssid)); + print_mac(mac, adapter->curbssparams.bssid)); libertas_prepare_and_send_command(priv, CMD_802_11_RSSI, 0, CMD_OPTION_WAITFORRSP, 0, NULL); diff --git a/drivers/net/wireless/libertas/cmdresp.c b/drivers/net/wireless/libertas/cmdresp.c index d64ad87db459..fe70e30b1f3c 100644 --- a/drivers/net/wireless/libertas/cmdresp.c +++ b/drivers/net/wireless/libertas/cmdresp.c @@ -159,6 +159,7 @@ static int wlan_ret_get_hw_spec(wlan_private * priv, struct cmd_ds_get_hw_spec *hwspec = &resp->params.hwspec; wlan_adapter *adapter = priv->adapter; int ret = 0; + DECLARE_MAC_BUF(mac); lbs_deb_enter(LBS_DEB_CMD); @@ -169,8 +170,8 @@ static int wlan_ret_get_hw_spec(wlan_private * priv, lbs_deb_cmd("GET_HW_SPEC: firmware release %u.%u.%up%u\n", adapter->fwreleasenumber[2], adapter->fwreleasenumber[1], adapter->fwreleasenumber[0], adapter->fwreleasenumber[3]); - lbs_deb_cmd("GET_HW_SPEC: MAC addr " MAC_FMT "\n", - MAC_ARG(hwspec->permanentaddr)); + lbs_deb_cmd("GET_HW_SPEC: MAC addr %s\n", + print_mac(mac, hwspec->permanentaddr)); lbs_deb_cmd("GET_HW_SPEC: hardware interface 0x%x, hardware spec 0x%04x\n", hwspec->hwifversion, hwspec->version); diff --git a/drivers/net/wireless/libertas/debugfs.c b/drivers/net/wireless/libertas/debugfs.c index 816f42e4f5b4..cb00b080409e 100644 --- a/drivers/net/wireless/libertas/debugfs.c +++ b/drivers/net/wireless/libertas/debugfs.c @@ -63,6 +63,7 @@ static ssize_t libertas_getscantable(struct file *file, char __user *userbuf, int numscansdone = 0, res; unsigned long addr = get_zeroed_page(GFP_KERNEL); char *buf = (char *)addr; + DECLARE_MAC_BUF(mac); struct bss_descriptor * iter_bss; pos += snprintf(buf+pos, len-pos, @@ -75,9 +76,9 @@ static ssize_t libertas_getscantable(struct file *file, char __user *userbuf, u16 spectrum_mgmt = (iter_bss->capability & WLAN_CAPABILITY_SPECTRUM_MGMT); pos += snprintf(buf+pos, len-pos, - "%02u| %03d | %04ld | " MAC_FMT " |", + "%02u| %03d | %04ld | %s |", numscansdone, iter_bss->channel, iter_bss->rssi, - MAC_ARG(iter_bss->bssid)); + print_mac(mac, iter_bss->bssid)); pos += snprintf(buf+pos, len-pos, " %04x-", iter_bss->capability); pos += snprintf(buf+pos, len-pos, "%c%c%c |", ibss ? 'A' : 'I', privacy ? 'P' : ' ', diff --git a/drivers/net/wireless/libertas/join.c b/drivers/net/wireless/libertas/join.c index 0ad1362b14e2..8dcff00574f3 100644 --- a/drivers/net/wireless/libertas/join.c +++ b/drivers/net/wireless/libertas/join.c @@ -293,6 +293,7 @@ int libertas_cmd_80211_authenticate(wlan_private * priv, struct cmd_ds_802_11_authenticate *pauthenticate = &cmd->params.auth; int ret = -1; u8 *bssid = pdata_buf; + DECLARE_MAC_BUF(mac); lbs_deb_enter(LBS_DEB_JOIN); @@ -319,8 +320,8 @@ int libertas_cmd_80211_authenticate(wlan_private * priv, memcpy(pauthenticate->macaddr, bssid, ETH_ALEN); - lbs_deb_join("AUTH_CMD: BSSID is : " MAC_FMT " auth=0x%X\n", - MAC_ARG(bssid), pauthenticate->authtype); + lbs_deb_join("AUTH_CMD: BSSID is : %s auth=0x%X\n", + print_mac(mac, bssid), pauthenticate->authtype); ret = 0; out: @@ -598,6 +599,7 @@ int libertas_cmd_80211_ad_hoc_join(wlan_private * priv, int cmdappendsize = 0; int ret = 0; u16 ratesize = 0; + DECLARE_MAC_BUF(mac); lbs_deb_enter(LBS_DEB_JOIN); @@ -621,8 +623,9 @@ int libertas_cmd_80211_ad_hoc_join(wlan_private * priv, /* information on BSSID descriptor passed to FW */ lbs_deb_join( - "ADHOC_J_CMD: BSSID = " MAC_FMT ", SSID = '%s'\n", - MAC_ARG(join_cmd->bss.bssid), join_cmd->bss.ssid); + "ADHOC_J_CMD: BSSID = %s, SSID = '%s'\n", + print_mac(mac, join_cmd->bss.bssid), + join_cmd->bss.ssid); /* failtimeout */ join_cmd->failtimeout = cpu_to_le16(MRVDRV_ASSOCIATION_TIME_OUT); @@ -829,6 +832,7 @@ int libertas_ret_80211_ad_hoc_start(wlan_private * priv, struct cmd_ds_802_11_ad_hoc_result *padhocresult; union iwreq_data wrqu; struct bss_descriptor *bss; + DECLARE_MAC_BUF(mac); lbs_deb_enter(LBS_DEB_JOIN); @@ -894,8 +898,8 @@ int libertas_ret_80211_ad_hoc_start(wlan_private * priv, lbs_deb_join("ADHOC_RESP: - Joined/Started Ad Hoc\n"); lbs_deb_join("ADHOC_RESP: channel = %d\n", adapter->curbssparams.channel); - lbs_deb_join("ADHOC_RESP: BSSID = " MAC_FMT "\n", - MAC_ARG(padhocresult->bssid)); + lbs_deb_join("ADHOC_RESP: BSSID = %s\n", + print_mac(mac, padhocresult->bssid)); done: lbs_deb_leave_args(LBS_DEB_JOIN, "ret %d", ret); diff --git a/drivers/net/wireless/libertas/main.c b/drivers/net/wireless/libertas/main.c index a54171af7b97..5ead08312e1e 100644 --- a/drivers/net/wireless/libertas/main.c +++ b/drivers/net/wireless/libertas/main.c @@ -677,6 +677,7 @@ static void libertas_set_multicast_list(struct net_device *dev) wlan_private *priv = dev->priv; wlan_adapter *adapter = priv->adapter; int oldpacketfilter; + DECLARE_MAC_BUF(mac); lbs_deb_enter(LBS_DEB_NET); @@ -723,14 +724,9 @@ static void libertas_set_multicast_list(struct net_device *dev) dev->mc_count); for (i = 0; i < dev->mc_count; i++) { - lbs_deb_net("Multicast address %d:" - MAC_FMT "\n", i, - adapter->multicastlist[i][0], - adapter->multicastlist[i][1], - adapter->multicastlist[i][2], - adapter->multicastlist[i][3], - adapter->multicastlist[i][4], - adapter->multicastlist[i][5]); + lbs_deb_net("Multicast address %d:%s\n", + i, print_mac(mac, + adapter->multicastlist[i])); } /* send multicast addresses to firmware */ libertas_prepare_and_send_command(priv, diff --git a/drivers/net/wireless/libertas/scan.c b/drivers/net/wireless/libertas/scan.c index e2e9ebcd8340..8f073ad1957f 100644 --- a/drivers/net/wireless/libertas/scan.c +++ b/drivers/net/wireless/libertas/scan.c @@ -777,6 +777,7 @@ int wlan_scan_networks(wlan_private * priv, #ifdef CONFIG_LIBERTAS_DEBUG struct bss_descriptor * iter_bss; int i = 0; + DECLARE_MAC_BUF(mac); #endif lbs_deb_enter(LBS_DEB_SCAN); @@ -831,8 +832,8 @@ int wlan_scan_networks(wlan_private * priv, /* Dump the scan table */ mutex_lock(&adapter->lock); list_for_each_entry (iter_bss, &adapter->network_list, list) { - lbs_deb_scan("Scan:(%02d) " MAC_FMT ", RSSI[%03d], SSID[%s]\n", - i++, MAC_ARG(iter_bss->bssid), (s32) iter_bss->rssi, + lbs_deb_scan("Scan:(%02d) %s, RSSI[%03d], SSID[%s]\n", + i++, print_mac(mac, iter_bss->bssid), (s32) iter_bss->rssi, escape_essid(iter_bss->ssid, iter_bss->ssid_len)); } mutex_unlock(&adapter->lock); @@ -876,6 +877,7 @@ static int libertas_process_bss(struct bss_descriptor * bss, struct ieeetypes_dsparamset *pDS; struct ieeetypes_cfparamset *pCF; struct ieeetypes_ibssparamset *pibss; + DECLARE_MAC_BUF(mac); struct ieeetypes_countryinfoset *pcountryinfo; u8 *pos, *end, *p; u8 n_ex_rates = 0, got_basic_rates = 0, n_basic_rates = 0; @@ -906,7 +908,7 @@ static int libertas_process_bss(struct bss_descriptor * bss, *bytesleft -= beaconsize; memcpy(bss->bssid, pos, ETH_ALEN); - lbs_deb_scan("process_bss: AP BSSID " MAC_FMT "\n", MAC_ARG(bss->bssid)); + lbs_deb_scan("process_bss: AP BSSID %s\n", print_mac(mac, bss->bssid)); pos += ETH_ALEN; if ((end - pos) < 12) { @@ -1724,6 +1726,7 @@ int libertas_ret_80211_scan(wlan_private * priv, struct cmd_ds_command *resp) struct bss_descriptor new; struct bss_descriptor * found = NULL; struct bss_descriptor * oldest = NULL; + DECLARE_MAC_BUF(mac); /* Process the data fields and IEs returned for this BSS */ memset(&new, 0, sizeof (struct bss_descriptor)); @@ -1762,9 +1765,8 @@ int libertas_ret_80211_scan(wlan_private * priv, struct cmd_ds_command *resp) continue; } - lbs_deb_scan("SCAN_RESP: BSSID = " MAC_FMT "\n", - new.bssid[0], new.bssid[1], new.bssid[2], - new.bssid[3], new.bssid[4], new.bssid[5]); + lbs_deb_scan("SCAN_RESP: BSSID = %s\n", + print_mac(mac, new.bssid)); /* Copy the locally created newbssentry to the scan table */ memcpy(found, &new, offsetof(struct bss_descriptor, list)); diff --git a/drivers/net/wireless/libertas/wext.c b/drivers/net/wireless/libertas/wext.c index f8036efd7294..0b2103e0af57 100644 --- a/drivers/net/wireless/libertas/wext.c +++ b/drivers/net/wireless/libertas/wext.c @@ -1160,7 +1160,7 @@ static int wlan_get_encode(struct net_device *dev, dwrq->flags |= IW_ENCODE_NOKEY; - lbs_deb_wext("key: " MAC_FMT ", keylen %d\n", + lbs_deb_wext("key: %02x:%02x:%02x:%02x:%02x:%02x, keylen %d\n", extra[0], extra[1], extra[2], extra[3], extra[4], extra[5], dwrq->length); @@ -1980,13 +1980,14 @@ static int wlan_set_wap(struct net_device *dev, struct iw_request_info *info, wlan_adapter *adapter = priv->adapter; struct assoc_request * assoc_req; int ret = 0; + DECLARE_MAC_BUF(mac); lbs_deb_enter(LBS_DEB_WEXT); if (awrq->sa_family != ARPHRD_ETHER) return -EINVAL; - lbs_deb_wext("ASSOC: WAP: sa_data " MAC_FMT "\n", MAC_ARG(awrq->sa_data)); + lbs_deb_wext("ASSOC: WAP: sa_data %s\n", print_mac(mac, awrq->sa_data)); mutex_lock(&adapter->lock); diff --git a/drivers/net/wireless/netwave_cs.c b/drivers/net/wireless/netwave_cs.c index d8a59afa7178..c2d71afd57e5 100644 --- a/drivers/net/wireless/netwave_cs.c +++ b/drivers/net/wireless/netwave_cs.c @@ -737,6 +737,7 @@ static int netwave_pcmcia_config(struct pcmcia_device *link) { win_req_t req; memreq_t mem; u_char __iomem *ramBase = NULL; + DECLARE_MAC_BUF(mac); DEBUG(0, "netwave_pcmcia_config(0x%p)\n", link); @@ -805,12 +806,13 @@ static int netwave_pcmcia_config(struct pcmcia_device *link) { for (i = 0; i < 6; i++) dev->dev_addr[i] = readb(ramBase + NETWAVE_EREG_PA + i); - printk(KERN_INFO "%s: Netwave: port %#3lx, irq %d, mem %lx id " - "%c%c, hw_addr ", dev->name, dev->base_addr, dev->irq, - (u_long) ramBase, (int) readb(ramBase+NETWAVE_EREG_NI), - (int) readb(ramBase+NETWAVE_EREG_NI+1)); - for (i = 0; i < 6; i++) - printk("%02X%s", dev->dev_addr[i], ((i<5) ? ":" : "\n")); + printk(KERN_INFO "%s: Netwave: port %#3lx, irq %d, mem %lx" + "id %c%c, hw_addr %s\n", + dev->name, dev->base_addr, dev->irq, + (u_long) ramBase, + (int) readb(ramBase+NETWAVE_EREG_NI), + (int) readb(ramBase+NETWAVE_EREG_NI+1), + print_mac(mac, dev->dev_addr)); /* get revision words */ printk(KERN_DEBUG "Netwave_reset: revision %04x %04x\n", diff --git a/drivers/net/wireless/orinoco.c b/drivers/net/wireless/orinoco.c index 062286dc8e15..ca6c2da7bc5d 100644 --- a/drivers/net/wireless/orinoco.c +++ b/drivers/net/wireless/orinoco.c @@ -2232,6 +2232,7 @@ static int orinoco_init(struct net_device *dev) struct hermes_idstring nickbuf; u16 reclen; int len; + DECLARE_MAC_BUF(mac); /* No need to lock, the hw_unavailable flag is already set in * alloc_orinocodev() */ @@ -2274,10 +2275,8 @@ static int orinoco_init(struct net_device *dev) goto out; } - printk(KERN_DEBUG "%s: MAC address %02X:%02X:%02X:%02X:%02X:%02X\n", - dev->name, dev->dev_addr[0], dev->dev_addr[1], - dev->dev_addr[2], dev->dev_addr[3], dev->dev_addr[4], - dev->dev_addr[5]); + printk(KERN_DEBUG "%s: MAC address %s\n", + dev->name, print_mac(mac, dev->dev_addr)); /* Get the station name */ err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CNFOWNNAME, diff --git a/drivers/net/wireless/prism54/isl_ioctl.c b/drivers/net/wireless/prism54/isl_ioctl.c index 77ea13bf0c02..6d80ca421cf0 100644 --- a/drivers/net/wireless/prism54/isl_ioctl.c +++ b/drivers/net/wireless/prism54/isl_ioctl.c @@ -2029,12 +2029,12 @@ static void format_event(islpci_private *priv, char *dest, const char *str, const struct obj_mlme *mlme, u16 *length, int error) { - const u8 *a = mlme->address; + DECLARE_MAC_BUF(mac); int n = snprintf(dest, IW_CUSTOM_MAX, - "%s %s %2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X %s (%2.2X)", + "%s %s %s %s (%2.2X)", str, ((priv->iw_mode == IW_MODE_MASTER) ? "from" : "to"), - a[0], a[1], a[2], a[3], a[4], a[5], + print_mac(mac, mlme->address), (error ? (mlme->code ? " : REJECTED " : " : ACCEPTED ") : ""), mlme->code); BUG_ON(n > IW_CUSTOM_MAX); @@ -2105,15 +2105,13 @@ struct ieee80211_beacon_phdr { #define WLAN_EID_GENERIC 0xdd static u8 wpa_oid[4] = { 0x00, 0x50, 0xf2, 1 }; -#define MAC2STR(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5] -#define MACSTR "%02x:%02x:%02x:%02x:%02x:%02x" - static void prism54_wpa_bss_ie_add(islpci_private *priv, u8 *bssid, u8 *wpa_ie, size_t wpa_ie_len) { struct list_head *ptr; struct islpci_bss_wpa_ie *bss = NULL; + DECLARE_MAC_BUF(mac); if (wpa_ie_len > MAX_WPA_IE_LEN) wpa_ie_len = MAX_WPA_IE_LEN; @@ -2154,8 +2152,8 @@ prism54_wpa_bss_ie_add(islpci_private *priv, u8 *bssid, bss->wpa_ie_len = wpa_ie_len; bss->last_update = jiffies; } else { - printk(KERN_DEBUG "Failed to add BSS WPA entry for " MACSTR - "\n", MAC2STR(bssid)); + printk(KERN_DEBUG "Failed to add BSS WPA entry for " + "%s\n", print_mac(mac, bssid)); } /* expire old entries from WPA list */ @@ -2221,6 +2219,7 @@ prism54_process_bss_data(islpci_private *priv, u32 oid, u8 *addr, { struct ieee80211_beacon_phdr *hdr; u8 *pos, *end; + DECLARE_MAC_BUF(mac); if (!priv->wpa) return; @@ -2231,7 +2230,7 @@ prism54_process_bss_data(islpci_private *priv, u32 oid, u8 *addr, while (pos < end) { if (pos + 2 + pos[1] > end) { printk(KERN_DEBUG "Parsing Beacon/ProbeResp failed " - "for " MACSTR "\n", MAC2STR(addr)); + "for %s\n", print_mac(mac, addr)); return; } if (pos[0] == WLAN_EID_GENERIC && pos[1] >= 4 && @@ -2270,6 +2269,7 @@ prism54_process_trap_helper(islpci_private *priv, enum oid_num_t oid, size_t len = 0; /* u16, better? */ u8 *payload = NULL, *pos = NULL; int ret; + DECLARE_MAC_BUF(mac); /* I think all trapable objects are listed here. * Some oids have a EX version. The difference is that they are emitted @@ -2358,14 +2358,8 @@ prism54_process_trap_helper(islpci_private *priv, enum oid_num_t oid, break; memcpy(&confirm->address, mlmeex->address, ETH_ALEN); - printk(KERN_DEBUG "Authenticate from: address:\t%02x:%02x:%02x:%02x:%02x:%02x\n", - mlmeex->address[0], - mlmeex->address[1], - mlmeex->address[2], - mlmeex->address[3], - mlmeex->address[4], - mlmeex->address[5] - ); + printk(KERN_DEBUG "Authenticate from: address:\t%s\n", + print_mac(mac, mlmeex->address)); confirm->id = -1; /* or mlmeex->id ? */ confirm->state = 0; /* not used */ confirm->code = 0; @@ -2410,15 +2404,8 @@ prism54_process_trap_helper(islpci_private *priv, enum oid_num_t oid, wpa_ie_len = prism54_wpa_bss_ie_get(priv, mlmeex->address, wpa_ie); if (!wpa_ie_len) { - printk(KERN_DEBUG "No WPA IE found from " - "address:\t%02x:%02x:%02x:%02x:%02x:%02x\n", - mlmeex->address[0], - mlmeex->address[1], - mlmeex->address[2], - mlmeex->address[3], - mlmeex->address[4], - mlmeex->address[5] - ); + printk(KERN_DEBUG "No WPA IE found from address:\t%s\n", + print_mac(mac, mlmeex->address)); kfree(confirm); break; } @@ -2454,15 +2441,8 @@ prism54_process_trap_helper(islpci_private *priv, enum oid_num_t oid, wpa_ie_len = prism54_wpa_bss_ie_get(priv, mlmeex->address, wpa_ie); if (!wpa_ie_len) { - printk(KERN_DEBUG "No WPA IE found from " - "address:\t%02x:%02x:%02x:%02x:%02x:%02x\n", - mlmeex->address[0], - mlmeex->address[1], - mlmeex->address[2], - mlmeex->address[3], - mlmeex->address[4], - mlmeex->address[5] - ); + printk(KERN_DEBUG "No WPA IE found from address:\t%s\n", + print_mac(mac, mlmeex->address)); kfree(confirm); break; } diff --git a/drivers/net/wireless/ray_cs.c b/drivers/net/wireless/ray_cs.c index 429bca8d0b5f..f87fe10059ae 100644 --- a/drivers/net/wireless/ray_cs.c +++ b/drivers/net/wireless/ray_cs.c @@ -412,6 +412,7 @@ static int ray_config(struct pcmcia_device *link) memreq_t mem; struct net_device *dev = (struct net_device *)link->priv; ray_dev_t *local = netdev_priv(dev); + DECLARE_MAC_BUF(mac); DEBUG(1, "ray_config(0x%p)\n", link); @@ -482,10 +483,8 @@ static int ray_config(struct pcmcia_device *link) strcpy(local->node.dev_name, dev->name); link->dev_node = &local->node; - printk(KERN_INFO "%s: RayLink, irq %d, hw_addr ", - dev->name, dev->irq); - for (i = 0; i < 6; i++) - printk("%02X%s", dev->dev_addr[i], ((i<5) ? ":" : "\n")); + printk(KERN_INFO "%s: RayLink, irq %d, hw_addr %s\n", + dev->name, dev->irq, print_mac(mac, dev->dev_addr)); return 0; @@ -2610,6 +2609,7 @@ static int ray_cs_proc_read(char *buf, char **start, off_t offset, int len) UCHAR *p; struct freq_hop_element *pfh; UCHAR c[33]; + DECLARE_MAC_BUF(mac); link = this_device; if (!link) @@ -2639,9 +2639,8 @@ static int ray_cs_proc_read(char *buf, char **start, off_t offset, int len) nettype[local->sparm.b5.a_network_type], c); p = local->bss_id; - len += sprintf(buf + len, - "BSSID = %02x:%02x:%02x:%02x:%02x:%02x\n", - p[0],p[1],p[2],p[3],p[4],p[5]); + len += sprintf(buf + len, "BSSID = %s\n", + print_mac(mac, p)); len += sprintf(buf + len, "Country code = %d\n", local->sparm.b5.a_curr_country_code); diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c index 38e2188937c5..398c20105c81 100644 --- a/drivers/net/wireless/rt2x00/rt2400pci.c +++ b/drivers/net/wireless/rt2x00/rt2400pci.c @@ -1362,8 +1362,10 @@ static int rt2400pci_validate_eeprom(struct rt2x00_dev *rt2x00dev) */ mac = rt2x00_eeprom_addr(rt2x00dev, EEPROM_MAC_ADDR_0); if (!is_valid_ether_addr(mac)) { + DECLARE_MAC_BUF(macbuf); + random_ether_addr(mac); - EEPROM(rt2x00dev, "MAC: " MAC_FMT "\n", MAC_ARG(mac)); + EEPROM(rt2x00dev, "MAC: %s\n", print_mac(macbuf, mac)); } rt2x00_eeprom_read(rt2x00dev, EEPROM_ANTENNA, &word); diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c index f6115c626fa7..e8d63aaab7bc 100644 --- a/drivers/net/wireless/rt2x00/rt2500pci.c +++ b/drivers/net/wireless/rt2x00/rt2500pci.c @@ -1509,8 +1509,11 @@ static int rt2500pci_validate_eeprom(struct rt2x00_dev *rt2x00dev) */ mac = rt2x00_eeprom_addr(rt2x00dev, EEPROM_MAC_ADDR_0); if (!is_valid_ether_addr(mac)) { + DECLARE_MAC_BUF(macbuf); + random_ether_addr(mac); - EEPROM(rt2x00dev, "MAC: " MAC_FMT "\n", MAC_ARG(mac)); + EEPROM(rt2x00dev, "MAC: %s\n", + print_mac(macbuf, mac)); } rt2x00_eeprom_read(rt2x00dev, EEPROM_ANTENNA, &word); diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c index 847bd7f58eed..614600c5510d 100644 --- a/drivers/net/wireless/rt2x00/rt2500usb.c +++ b/drivers/net/wireless/rt2x00/rt2500usb.c @@ -1233,8 +1233,10 @@ static int rt2500usb_validate_eeprom(struct rt2x00_dev *rt2x00dev) */ mac = rt2x00_eeprom_addr(rt2x00dev, EEPROM_MAC_ADDR_0); if (!is_valid_ether_addr(mac)) { + DECLARE_MAC_BUF(macbuf); + random_ether_addr(mac); - EEPROM(rt2x00dev, "MAC: " MAC_FMT "\n", MAC_ARG(mac)); + EEPROM(rt2x00dev, "MAC: %s\n", print_mac(macbuf, mac)); } rt2x00_eeprom_read(rt2x00dev, EEPROM_ANTENNA, &word); diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c index 730bed5a1984..09c8c96e2f83 100644 --- a/drivers/net/wireless/rt2x00/rt61pci.c +++ b/drivers/net/wireless/rt2x00/rt61pci.c @@ -2019,8 +2019,10 @@ static int rt61pci_validate_eeprom(struct rt2x00_dev *rt2x00dev) */ mac = rt2x00_eeprom_addr(rt2x00dev, EEPROM_MAC_ADDR_0); if (!is_valid_ether_addr(mac)) { + DECLARE_MAC_BUF(macbuf); + random_ether_addr(mac); - EEPROM(rt2x00dev, "MAC: " MAC_FMT "\n", MAC_ARG(mac)); + EEPROM(rt2x00dev, "MAC: %s\n", print_mac(macbuf, mac)); } rt2x00_eeprom_read(rt2x00dev, EEPROM_ANTENNA, &word); diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c index b047c7c0f9ee..3397881bd63d 100644 --- a/drivers/net/wireless/rt2x00/rt73usb.c +++ b/drivers/net/wireless/rt2x00/rt73usb.c @@ -1475,8 +1475,10 @@ static int rt73usb_validate_eeprom(struct rt2x00_dev *rt2x00dev) */ mac = rt2x00_eeprom_addr(rt2x00dev, EEPROM_MAC_ADDR_0); if (!is_valid_ether_addr(mac)) { + DECLARE_MAC_BUF(macbuf); + random_ether_addr(mac); - EEPROM(rt2x00dev, "MAC: " MAC_FMT "\n", MAC_ARG(mac)); + EEPROM(rt2x00dev, "MAC: %s\n", print_mac(macbuf, mac)); } rt2x00_eeprom_read(rt2x00dev, EEPROM_ANTENNA, &word); diff --git a/drivers/net/wireless/rtl8187_dev.c b/drivers/net/wireless/rtl8187_dev.c index 7dbf11e30db3..bf9f0cc5a645 100644 --- a/drivers/net/wireless/rtl8187_dev.c +++ b/drivers/net/wireless/rtl8187_dev.c @@ -574,6 +574,7 @@ static int __devinit rtl8187_probe(struct usb_interface *intf, struct ieee80211_channel *channel; u16 txpwr, reg; int err, i; + DECLARE_MAC_BUF(mac); dev = ieee80211_alloc_hw(sizeof(*priv), &rtl8187_ops); if (!dev) { @@ -681,8 +682,8 @@ static int __devinit rtl8187_probe(struct usb_interface *intf, goto err_free_dev; } - printk(KERN_INFO "%s: hwaddr " MAC_FMT ", rtl8187 V%d + %s\n", - wiphy_name(dev->wiphy), MAC_ARG(dev->wiphy->perm_addr), + printk(KERN_INFO "%s: hwaddr %s, rtl8187 V%d + %s\n", + wiphy_name(dev->wiphy), print_mac(mac, dev->wiphy->perm_addr), priv->asic_rev, priv->rf_init == rtl8225_rf_init ? "rtl8225" : "rtl8225z2"); diff --git a/drivers/net/wireless/wavelan.c b/drivers/net/wireless/wavelan.c index 33ed9fe95f3d..a1f8a1687842 100644 --- a/drivers/net/wireless/wavelan.c +++ b/drivers/net/wireless/wavelan.c @@ -880,6 +880,8 @@ static void wv_82586_reconfig(struct net_device * dev) */ static void wv_psa_show(psa_t * p) { + DECLARE_MAC_BUF(mac); + printk(KERN_DEBUG "##### WaveLAN PSA contents: #####\n"); printk(KERN_DEBUG "psa_io_base_addr_1: 0x%02X %02X %02X %02X\n", p->psa_io_base_addr_1, @@ -891,22 +893,13 @@ static void wv_psa_show(psa_t * p) printk(KERN_DEBUG "psa_holi_params: 0x%02x, ", p->psa_holi_params); printk("psa_int_req_no: %d\n", p->psa_int_req_no); #ifdef DEBUG_SHOW_UNUSED - printk(KERN_DEBUG - "psa_unused0[]: %02X:%02X:%02X:%02X:%02X:%02X:%02X\n", - p->psa_unused0[0], p->psa_unused0[1], p->psa_unused0[2], - p->psa_unused0[3], p->psa_unused0[4], p->psa_unused0[5], - p->psa_unused0[6]); + printk(KERN_DEBUG "psa_unused0[]: %s\n", + print_mac(mac, p->psa_unused0)); #endif /* DEBUG_SHOW_UNUSED */ - printk(KERN_DEBUG - "psa_univ_mac_addr[]: %02x:%02x:%02x:%02x:%02x:%02x\n", - p->psa_univ_mac_addr[0], p->psa_univ_mac_addr[1], - p->psa_univ_mac_addr[2], p->psa_univ_mac_addr[3], - p->psa_univ_mac_addr[4], p->psa_univ_mac_addr[5]); - printk(KERN_DEBUG - "psa_local_mac_addr[]: %02x:%02x:%02x:%02x:%02x:%02x\n", - p->psa_local_mac_addr[0], p->psa_local_mac_addr[1], - p->psa_local_mac_addr[2], p->psa_local_mac_addr[3], - p->psa_local_mac_addr[4], p->psa_local_mac_addr[5]); + printk(KERN_DEBUG "psa_univ_mac_addr[]: %s\n", + print_mac(mac, p->psa_univ_mac_addr)); + printk(KERN_DEBUG "psa_local_mac_addr[]: %s\n", + print_mac(mac, p->psa_local_mac_addr)); printk(KERN_DEBUG "psa_univ_local_sel: %d, ", p->psa_univ_local_sel); printk("psa_comp_number: %d, ", p->psa_comp_number); @@ -1248,14 +1241,14 @@ static inline void wv_packet_info(u8 * p, /* Packet to dump */ { /* Name of the function */ int i; int maxi; + DECLARE_MAC_BUF(mac); printk(KERN_DEBUG - "%s: %s(): dest %02X:%02X:%02X:%02X:%02X:%02X, length %d\n", - msg1, msg2, p[0], p[1], p[2], p[3], p[4], p[5], length); + "%s: %s(): dest %s, length %d\n", + msg1, msg2, print_mac(mac, p), length); printk(KERN_DEBUG - "%s: %s(): src %02X:%02X:%02X:%02X:%02X:%02X, type 0x%02X%02X\n", - msg1, msg2, p[6], p[7], p[8], p[9], p[10], p[11], p[12], - p[13]); + "%s: %s(): src %s, type 0x%02X%02X\n", + msg1, msg2, print_mac(mac, &p[6]), p[12], p[13]); #ifdef DEBUG_PACKET_DUMP @@ -1286,7 +1279,9 @@ static void wv_init_info(struct net_device * dev) short ioaddr = dev->base_addr; net_local *lp = (net_local *) dev->priv; psa_t psa; - int i; +#ifdef DEBUG_BASIC_SHOW + DECLARE_MAC_BUF(mac); +#endif /* Read the parameter storage area */ psa_read(ioaddr, lp->hacr, 0, (unsigned char *) &psa, sizeof(psa)); @@ -1303,10 +1298,8 @@ static void wv_init_info(struct net_device * dev) #ifdef DEBUG_BASIC_SHOW /* Now, let's go for the basic stuff. */ - printk(KERN_NOTICE "%s: WaveLAN at %#x,", dev->name, ioaddr); - for (i = 0; i < WAVELAN_ADDR_SIZE; i++) - printk("%s%02X", (i == 0) ? " " : ":", dev->dev_addr[i]); - printk(", IRQ %d", dev->irq); + printk(KERN_NOTICE "%s: WaveLAN at %#x, %s, IRQ %d", + dev->name, ioaddr, print_mac(mac, dev->dev_addr), dev->irq); /* Print current network ID. */ if (psa.psa_nwid_select) @@ -3596,15 +3589,15 @@ static void wv_82586_config(struct net_device * dev) WAVELAN_ADDR_SIZE >> 1); #ifdef DEBUG_CONFIG_INFO + { + DECLARE_MAC_BUF(mac); printk(KERN_DEBUG "%s: wv_82586_config(): set %d multicast addresses:\n", dev->name, lp->mc_count); for (dmi = dev->mc_list; dmi; dmi = dmi->next) - printk(KERN_DEBUG - " %02x:%02x:%02x:%02x:%02x:%02x\n", - dmi->dmi_addr[0], dmi->dmi_addr[1], - dmi->dmi_addr[2], dmi->dmi_addr[3], - dmi->dmi_addr[4], dmi->dmi_addr[5]); + printk(KERN_DEBUG " %s\n", + print_mac(mac, dmi->dmi_addr)); + } #endif } diff --git a/drivers/net/wireless/wavelan_cs.c b/drivers/net/wireless/wavelan_cs.c index 9b7f44957869..577c647824fe 100644 --- a/drivers/net/wireless/wavelan_cs.c +++ b/drivers/net/wireless/wavelan_cs.c @@ -1042,6 +1042,7 @@ wv_82593_reconfig(struct net_device * dev) static void wv_psa_show(psa_t * p) { + DECLARE_MAC_BUF(mac); printk(KERN_DEBUG "##### wavelan psa contents: #####\n"); printk(KERN_DEBUG "psa_io_base_addr_1: 0x%02X %02X %02X %02X\n", p->psa_io_base_addr_1, @@ -1055,29 +1056,13 @@ wv_psa_show(psa_t * p) printk(KERN_DEBUG "psa_holi_params: 0x%02x, ", p->psa_holi_params); printk("psa_int_req_no: %d\n", p->psa_int_req_no); #ifdef DEBUG_SHOW_UNUSED - printk(KERN_DEBUG "psa_unused0[]: %02X:%02X:%02X:%02X:%02X:%02X:%02X\n", - p->psa_unused0[0], - p->psa_unused0[1], - p->psa_unused0[2], - p->psa_unused0[3], - p->psa_unused0[4], - p->psa_unused0[5], - p->psa_unused0[6]); + printk(KERN_DEBUG "psa_unused0[]: %s\n", + print_mac(mac, p->psa_unused0)); #endif /* DEBUG_SHOW_UNUSED */ - printk(KERN_DEBUG "psa_univ_mac_addr[]: %02x:%02x:%02x:%02x:%02x:%02x\n", - p->psa_univ_mac_addr[0], - p->psa_univ_mac_addr[1], - p->psa_univ_mac_addr[2], - p->psa_univ_mac_addr[3], - p->psa_univ_mac_addr[4], - p->psa_univ_mac_addr[5]); - printk(KERN_DEBUG "psa_local_mac_addr[]: %02x:%02x:%02x:%02x:%02x:%02x\n", - p->psa_local_mac_addr[0], - p->psa_local_mac_addr[1], - p->psa_local_mac_addr[2], - p->psa_local_mac_addr[3], - p->psa_local_mac_addr[4], - p->psa_local_mac_addr[5]); + printk(KERN_DEBUG "psa_univ_mac_addr[]: %s\n", + print_mac(mac, p->psa_univ_mac_addr)); + printk(KERN_DEBUG "psa_local_mac_addr[]: %s\n", + print_mac(mac, p->psa_local_mac_addr)); printk(KERN_DEBUG "psa_univ_local_sel: %d, ", p->psa_univ_local_sel); printk("psa_comp_number: %d, ", p->psa_comp_number); printk("psa_thr_pre_set: 0x%02x\n", p->psa_thr_pre_set); @@ -1277,11 +1262,12 @@ wv_packet_info(u_char * p, /* Packet to dump */ { int i; int maxi; + DECLARE_MAC_BUF(mac); - printk(KERN_DEBUG "%s: %s(): dest %02X:%02X:%02X:%02X:%02X:%02X, length %d\n", - msg1, msg2, p[0], p[1], p[2], p[3], p[4], p[5], length); - printk(KERN_DEBUG "%s: %s(): src %02X:%02X:%02X:%02X:%02X:%02X, type 0x%02X%02X\n", - msg1, msg2, p[6], p[7], p[8], p[9], p[10], p[11], p[12], p[13]); + printk(KERN_DEBUG "%s: %s(): dest %s, length %d\n", + msg1, msg2, print_mac(mac, p), length); + printk(KERN_DEBUG "%s: %s(): src %s, type 0x%02X%02X\n", + msg1, msg2, print_mac(mac, &p[6]), p[12], p[13]); #ifdef DEBUG_PACKET_DUMP @@ -1312,7 +1298,7 @@ wv_init_info(struct net_device * dev) { kio_addr_t base = dev->base_addr; psa_t psa; - int i; + DECLARE_MAC_BUF(mac); /* Read the parameter storage area */ psa_read(dev, 0, (unsigned char *) &psa, sizeof(psa)); @@ -1329,10 +1315,10 @@ wv_init_info(struct net_device * dev) #ifdef DEBUG_BASIC_SHOW /* Now, let's go for the basic stuff */ - printk(KERN_NOTICE "%s: WaveLAN: port %#lx, irq %d, hw_addr", - dev->name, base, dev->irq); - for(i = 0; i < WAVELAN_ADDR_SIZE; i++) - printk("%s%02X", (i == 0) ? " " : ":", dev->dev_addr[i]); + printk(KERN_NOTICE "%s: WaveLAN: port %#lx, irq %d, " + "hw_addr %s", + dev->name, base, dev->irq, + print_mac(mac, dev->dev_addr)); /* Print current network id */ if(psa.psa_nwid_select) @@ -3691,12 +3677,12 @@ wv_82593_config(struct net_device * dev) int addrs_len = WAVELAN_ADDR_SIZE * lp->mc_count; #ifdef DEBUG_CONFIG_INFO + DECLARE_MAC_BUF(mac); printk(KERN_DEBUG "%s: wv_hw_config(): set %d multicast addresses:\n", dev->name, lp->mc_count); for(dmi=dev->mc_list; dmi; dmi=dmi->next) - printk(KERN_DEBUG " %02x:%02x:%02x:%02x:%02x:%02x\n", - dmi->dmi_addr[0], dmi->dmi_addr[1], dmi->dmi_addr[2], - dmi->dmi_addr[3], dmi->dmi_addr[4], dmi->dmi_addr[5] ); + printk(KERN_DEBUG " %s\n", + print_mac(mac, dmi->dmi_addr)); #endif /* Initialize adapter's ethernet multicast addresses */ diff --git a/drivers/net/wireless/wl3501_cs.c b/drivers/net/wireless/wl3501_cs.c index 2690f291e3f7..42a36b3f3ff7 100644 --- a/drivers/net/wireless/wl3501_cs.c +++ b/drivers/net/wireless/wl3501_cs.c @@ -860,11 +860,10 @@ static int wl3501_esbq_confirm(struct wl3501_card *this) static void wl3501_online(struct net_device *dev) { struct wl3501_card *this = netdev_priv(dev); + DECLARE_MAC_BUF(mac); - printk(KERN_INFO "%s: Wireless LAN online. BSSID: " - "%02X %02X %02X %02X %02X %02X\n", dev->name, - this->bssid[0], this->bssid[1], this->bssid[2], - this->bssid[3], this->bssid[4], this->bssid[5]); + printk(KERN_INFO "%s: Wireless LAN online. BSSID: %s\n", + dev->name, print_mac(mac, this->bssid)); netif_wake_queue(dev); } @@ -1966,6 +1965,7 @@ static int wl3501_config(struct pcmcia_device *link) struct net_device *dev = link->priv; int i = 0, j, last_fn, last_ret; struct wl3501_card *this; + DECLARE_MAC_BUF(mac); /* Try allocating IO ports. This tries a few fixed addresses. If you * want, you can also read the card's config table to pick addresses -- @@ -2019,14 +2019,14 @@ static int wl3501_config(struct pcmcia_device *link) } strcpy(this->node.dev_name, dev->name); - /* print probe information */ - printk(KERN_INFO "%s: wl3501 @ 0x%3.3x, IRQ %d, MAC addr in flash ROM:", - dev->name, this->base_addr, (int)dev->irq); - for (i = 0; i < 6; i++) { + for (i = 0; i < 6; i++) dev->dev_addr[i] = ((char *)&this->mac_addr)[i]; - printk("%c%02x", i ? ':' : ' ', dev->dev_addr[i]); - } - printk("\n"); + + /* print probe information */ + printk(KERN_INFO "%s: wl3501 @ 0x%3.3x, IRQ %d, " + "MAC addr in flash ROM:%s\n", + dev->name, this->base_addr, (int)dev->irq, + print_mac(mac, dev->dev_addr)); /* * Initialize card parameters - added by jss */ diff --git a/drivers/net/wireless/zd1211rw/zd_chip.c b/drivers/net/wireless/zd1211rw/zd_chip.c index 495904218b1b..750c0f99e86f 100644 --- a/drivers/net/wireless/zd1211rw/zd_chip.c +++ b/drivers/net/wireless/zd1211rw/zd_chip.c @@ -377,6 +377,7 @@ int zd_write_mac_addr(struct zd_chip *chip, const u8 *mac_addr) [0] = { .addr = CR_MAC_ADDR_P1 }, [1] = { .addr = CR_MAC_ADDR_P2 }, }; + DECLARE_MAC_BUF(mac); reqs[0].value = (mac_addr[3] << 24) | (mac_addr[2] << 16) @@ -386,7 +387,7 @@ int zd_write_mac_addr(struct zd_chip *chip, const u8 *mac_addr) | mac_addr[4]; dev_dbg_f(zd_chip_dev(chip), - "mac addr " MAC_FMT "\n", MAC_ARG(mac_addr)); + "mac addr %s\n", print_mac(mac, mac_addr)); mutex_lock(&chip->mutex); r = zd_iowrite32a_locked(chip, reqs, ARRAY_SIZE(reqs)); diff --git a/drivers/net/wireless/zd1211rw/zd_mac.c b/drivers/net/wireless/zd1211rw/zd_mac.c index 451308d7095d..06b342b39792 100644 --- a/drivers/net/wireless/zd1211rw/zd_mac.c +++ b/drivers/net/wireless/zd1211rw/zd_mac.c @@ -289,12 +289,13 @@ int zd_mac_set_mac_address(struct net_device *netdev, void *p) struct sockaddr *addr = p; struct zd_mac *mac = zd_netdev_mac(netdev); struct zd_chip *chip = &mac->chip; + DECLARE_MAC_BUF(mac2); if (!is_valid_ether_addr(addr->sa_data)) return -EADDRNOTAVAIL; dev_dbg_f(zd_mac_dev(mac), - "Setting MAC to " MAC_FMT "\n", MAC_ARG(addr->sa_data)); + "Setting MAC to %s\n", print_mac(mac2, addr->sa_data)); if (netdev->flags & IFF_UP) { r = zd_write_mac_addr(chip, addr->sa_data); @@ -329,6 +330,7 @@ void zd_mac_set_multicast_list(struct net_device *dev) struct zd_mc_hash hash; struct dev_mc_list *mc; unsigned long flags; + DECLARE_MAC_BUF(mac2); if (dev->flags & (IFF_PROMISC|IFF_ALLMULTI) || ieee->iw_mode == IW_MODE_MONITOR) { @@ -336,8 +338,8 @@ void zd_mac_set_multicast_list(struct net_device *dev) } else { zd_mc_clear(&hash); for (mc = dev->mc_list; mc; mc = mc->next) { - dev_dbg_f(zd_mac_dev(mac), "mc addr " MAC_FMT "\n", - MAC_ARG(mc->dmi_addr)); + dev_dbg_f(zd_mac_dev(mac), "mc addr %s\n", + print_mac(mac2, mc->dmi_addr)); zd_mc_add_addr(&hash, mc->dmi_addr); } } diff --git a/drivers/net/yellowfin.c b/drivers/net/yellowfin.c index 709623e1c611..87f002ade531 100644 --- a/drivers/net/yellowfin.c +++ b/drivers/net/yellowfin.c @@ -374,6 +374,7 @@ static int __devinit yellowfin_init_one(struct pci_dev *pdev, #else int bar = 1; #endif + DECLARE_MAC_BUF(mac); /* when built into the kernel, we only print version if device is found */ #ifndef MODULE @@ -480,12 +481,10 @@ static int __devinit yellowfin_init_one(struct pci_dev *pdev, if (i) goto err_out_unmap_status; - printk(KERN_INFO "%s: %s type %8x at %p, ", + printk(KERN_INFO "%s: %s type %8x at %p, %s, IRQ %d.\n", dev->name, pci_id_tbl[chip_idx].name, - ioread32(ioaddr + ChipRev), ioaddr); - for (i = 0; i < 5; i++) - printk("%2.2x:", dev->dev_addr[i]); - printk("%2.2x, IRQ %d.\n", dev->dev_addr[i], irq); + ioread32(ioaddr + ChipRev), ioaddr, + print_mac(mac, dev->dev_addr), irq); if (np->drv_flags & HasMII) { int phy, phy_idx = 0; @@ -1101,11 +1100,11 @@ static int yellowfin_rx(struct net_device *dev) memcmp(le32_to_cpu(yp->rx_ring_dma + entry*sizeof(struct yellowfin_desc)), "\377\377\377\377\377\377", 6) != 0) { - if (bogus_rx++ == 0) - printk(KERN_WARNING "%s: Bad frame to %2.2x:%2.2x:%2.2x:%2.2x:" - "%2.2x:%2.2x.\n", - dev->name, buf_addr[0], buf_addr[1], buf_addr[2], - buf_addr[3], buf_addr[4], buf_addr[5]); + if (bogus_rx++ == 0) { + DECLARE_MAC_BUF(mac); + printk(KERN_WARNING "%s: Bad frame to %s\n", + dev->name, print_mac(mac, buf_addr)); + } #endif } else { struct sk_buff *skb; diff --git a/drivers/net/znet.c b/drivers/net/znet.c index 43712c7b9ecf..a86c022d6a94 100644 --- a/drivers/net/znet.c +++ b/drivers/net/znet.c @@ -370,6 +370,7 @@ static int __init znet_probe (void) struct net_device *dev; char *p; int err = -ENOMEM; + DECLARE_MAC_BUF(mac); /* This code scans the region 0xf0000 to 0xfffff for a "NETIDBLK". */ for(p = (char *)phys_to_virt(0xf0000); p < (char *)phys_to_virt(0x100000); p++) @@ -392,14 +393,14 @@ static int __init znet_probe (void) dev->base_addr = netinfo->iobase1; dev->irq = netinfo->irq1; - printk(KERN_INFO "%s: ZNET at %#3lx,", dev->name, dev->base_addr); - /* The station address is in the "netidblk" at 0x0f0000. */ for (i = 0; i < 6; i++) - printk(" %2.2x", dev->dev_addr[i] = netinfo->netid[i]); + dev->dev_addr[i] = netinfo->netid[i]; - printk(", using IRQ %d DMA %d and %d.\n", dev->irq, netinfo->dma1, - netinfo->dma2); + printk(KERN_INFO "%s: ZNET at %#3lx, %s" + ", using IRQ %d DMA %d and %d.\n", + dev->name, dev->base_addr, print_mac(mac, dev->dev_addr), + dev->irq, netinfo->dma1, netinfo->dma2); if (znet_debug > 1) { printk(KERN_INFO "%s: vendor '%16.16s' IRQ1 %d IRQ2 %d DMA1 %d DMA2 %d.\n", diff --git a/drivers/net/zorro8390.c b/drivers/net/zorro8390.c index fb215eb6dcf3..3926b2aa9cca 100644 --- a/drivers/net/zorro8390.c +++ b/drivers/net/zorro8390.c @@ -151,6 +151,7 @@ static int __devinit zorro8390_init(struct net_device *dev, 0x00, 0x02, 0x04, 0x06, 0x08, 0x0a, 0x0c, 0x0e, 0x10, 0x12, 0x14, 0x16, 0x18, 0x1a, 0x1c, 0x1e, }; + DECLARE_MAC_BUF(mac); /* Reset card. Who knows what dain-bramaged state it was left in. */ { @@ -211,12 +212,12 @@ static int __devinit zorro8390_init(struct net_device *dev, i = request_irq(IRQ_AMIGA_PORTS, __ei_interrupt, IRQF_SHARED, DRV_NAME, dev); if (i) return i; - for(i = 0; i < ETHER_ADDR_LEN; i++) { + for(i = 0; i < ETHER_ADDR_LEN; i++) + dev->dev_addr[i] = SA_prom[i]; + #ifdef DEBUG - printk(" %2.2x", SA_prom[i]); + printk("%s", print_mac(mac, dev->dev_addr)); #endif - dev->dev_addr[i] = SA_prom[i]; - } ei_status.name = name; ei_status.tx_start_page = start_page; @@ -243,10 +244,8 @@ static int __devinit zorro8390_init(struct net_device *dev, return err; } - printk(KERN_INFO "%s: %s at 0x%08lx, Ethernet Address " - "%02x:%02x:%02x:%02x:%02x:%02x\n", dev->name, name, board, - dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2], - dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]); + printk(KERN_INFO "%s: %s at 0x%08lx, Ethernet Address %s\n", + dev->name, name, board, print_mac(mac, dev->dev_addr)); return 0; } diff --git a/include/linux/if_ether.h b/include/linux/if_ether.h index 3213f6f4aa58..0e791e2c0c5a 100644 --- a/include/linux/if_ether.h +++ b/include/linux/if_ether.h @@ -120,6 +120,14 @@ static inline struct ethhdr *eth_hdr(const struct sk_buff *skb) #ifdef CONFIG_SYSCTL extern struct ctl_table ether_table[]; #endif + +/* + * Display a 6 byte device address (MAC) in a readable format. + */ +#define MAC_FMT "%02x:%02x:%02x:%02x:%02x:%02x" +extern char *print_mac(char *buf, const u8 *addr); +#define DECLARE_MAC_BUF(var) char var[18] __maybe_unused + #endif #endif /* _LINUX_IF_ETHER_H */ diff --git a/include/net/ieee80211.h b/include/net/ieee80211.h index bbd85cd61ed5..164d13211165 100644 --- a/include/net/ieee80211.h +++ b/include/net/ieee80211.h @@ -119,11 +119,6 @@ do { if (ieee80211_debug_level & (level)) \ #define IEEE80211_DEBUG(level, fmt, args...) do {} while (0) #endif /* CONFIG_IEEE80211_DEBUG */ -/* debug macros not dependent on CONFIG_IEEE80211_DEBUG */ - -#define MAC_FMT "%02x:%02x:%02x:%02x:%02x:%02x" -#define MAC_ARG(x) ((u8*)(x))[0],((u8*)(x))[1],((u8*)(x))[2],((u8*)(x))[3],((u8*)(x))[4],((u8*)(x))[5] - /* escape_essid() is intended to be used in debug (and possibly error) * messages. It should never be used for passing essid to user space. */ const char *escape_essid(const char *essid, u8 essid_len); diff --git a/include/net/mac80211.h b/include/net/mac80211.h index a2c14f95b9a0..947f3c820e42 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -1106,8 +1106,4 @@ static inline int ieee80211_get_morefrag(struct ieee80211_hdr *hdr) IEEE80211_FCTL_MOREFRAGS) != 0; } -#define MAC_FMT "%02x:%02x:%02x:%02x:%02x:%02x" -#define MAC_ARG(x) ((u8*)(x))[0], ((u8*)(x))[1], ((u8*)(x))[2], \ - ((u8*)(x))[3], ((u8*)(x))[4], ((u8*)(x))[5] - #endif /* MAC80211_H */ diff --git a/net/802/tr.c b/net/802/tr.c index 55c76d77d322..aa3c2e936abc 100644 --- a/net/802/tr.c +++ b/net/802/tr.c @@ -283,8 +283,10 @@ void tr_source_route(struct sk_buff *skb,struct trh_hdr *trh,struct net_device * if(entry) { #if TR_SR_DEBUG -printk("source routing for %02X:%02X:%02X:%02X:%02X:%02X\n",trh->daddr[0], - trh->daddr[1],trh->daddr[2],trh->daddr[3],trh->daddr[4],trh->daddr[5]); +{ +DECLARE_MAC_BUF(mac); +printk("source routing for %s\n",print_mac(mac, trh->daddr)); +} #endif if(!entry->local_ring && (ntohs(entry->rcf) & TR_RCF_LEN_MASK) >> 8) { @@ -366,10 +368,9 @@ static void tr_add_rif_info(struct trh_hdr *trh, struct net_device *dev) if(entry==NULL) { #if TR_SR_DEBUG -printk("adding rif_entry: addr:%02X:%02X:%02X:%02X:%02X:%02X rcf:%04X\n", - trh->saddr[0],trh->saddr[1],trh->saddr[2], - trh->saddr[3],trh->saddr[4],trh->saddr[5], - ntohs(trh->rcf)); + DECLARE_MAC_BUF(mac); + printk("adding rif_entry: addr:%s rcf:%04X\n", + print_mac(mac, trh->saddr), ntohs(trh->rcf)); #endif /* * Allocate our new entry. A failure to allocate loses @@ -414,10 +415,11 @@ printk("adding rif_entry: addr:%02X:%02X:%02X:%02X:%02X:%02X rcf:%04X\n", !(trh->rcf & htons(TR_RCF_BROADCAST_MASK))) { #if TR_SR_DEBUG -printk("updating rif_entry: addr:%02X:%02X:%02X:%02X:%02X:%02X rcf:%04X\n", - trh->saddr[0],trh->saddr[1],trh->saddr[2], - trh->saddr[3],trh->saddr[4],trh->saddr[5], - ntohs(trh->rcf)); +{ +DECLARE_MAC_BUF(mac); +printk("updating rif_entry: addr:%s rcf:%04X\n", + print_mac(mac, trh->saddr), ntohs(trh->rcf)); +} #endif entry->rcf = trh->rcf & htons((unsigned short)~TR_RCF_BROADCAST_MASK); memcpy(&(entry->rseg[0]),&(trh->rseg[0]),8*sizeof(unsigned short)); @@ -528,6 +530,7 @@ static int rif_seq_show(struct seq_file *seq, void *v) { int j, rcf_len, segment, brdgnmb; struct rif_cache *entry = v; + DECLARE_MAC_BUF(mac); if (v == SEQ_START_TOKEN) seq_puts(seq, @@ -537,10 +540,9 @@ static int rif_seq_show(struct seq_file *seq, void *v) long ttl = (long) (entry->last_used + sysctl_tr_rif_timeout) - (long) jiffies; - seq_printf(seq, "%s %02X:%02X:%02X:%02X:%02X:%02X %7li ", + seq_printf(seq, "%s %s %7li ", dev?dev->name:"?", - entry->addr[0],entry->addr[1],entry->addr[2], - entry->addr[3],entry->addr[4],entry->addr[5], + print_mac(mac, entry->addr), ttl/HZ); if (entry->local_ring) diff --git a/net/appletalk/aarp.c b/net/appletalk/aarp.c index e9a51a69870e..92cd74973c97 100644 --- a/net/appletalk/aarp.c +++ b/net/appletalk/aarp.c @@ -997,6 +997,7 @@ static int aarp_seq_show(struct seq_file *seq, void *v) struct aarp_iter_state *iter = seq->private; struct aarp_entry *entry = v; unsigned long now = jiffies; + DECLARE_MAC_BUF(mac); if (v == SEQ_START_TOKEN) seq_puts(seq, @@ -1007,13 +1008,7 @@ static int aarp_seq_show(struct seq_file *seq, void *v) ntohs(entry->target_addr.s_net), (unsigned int) entry->target_addr.s_node, entry->dev ? entry->dev->name : "????"); - seq_printf(seq, "%02X:%02X:%02X:%02X:%02X:%02X", - entry->hwaddr[0] & 0xFF, - entry->hwaddr[1] & 0xFF, - entry->hwaddr[2] & 0xFF, - entry->hwaddr[3] & 0xFF, - entry->hwaddr[4] & 0xFF, - entry->hwaddr[5] & 0xFF); + seq_printf(seq, "%s", print_mac(mac, entry->hwaddr)); seq_printf(seq, " %8s", dt2str((long)entry->expires_at - (long)now)); if (iter->table == unresolved) diff --git a/net/atm/br2684.c b/net/atm/br2684.c index 81eb4f4cbe10..c742d37bfb97 100644 --- a/net/atm/br2684.c +++ b/net/atm/br2684.c @@ -709,17 +709,13 @@ static int br2684_seq_show(struct seq_file *seq, void *v) br2684_devs); const struct net_device *net_dev = brdev->net_dev; const struct br2684_vcc *brvcc; + DECLARE_MAC_BUF(mac); - seq_printf(seq, "dev %.16s: num=%d, mac=%02X:%02X:" - "%02X:%02X:%02X:%02X (%s)\n", net_dev->name, - brdev->number, - net_dev->dev_addr[0], - net_dev->dev_addr[1], - net_dev->dev_addr[2], - net_dev->dev_addr[3], - net_dev->dev_addr[4], - net_dev->dev_addr[5], - brdev->mac_was_set ? "set" : "auto"); + seq_printf(seq, "dev %.16s: num=%d, mac=%s (%s)\n", + net_dev->name, + brdev->number, + print_mac(mac, net_dev->dev_addr), + brdev->mac_was_set ? "set" : "auto"); list_for_each_entry(brvcc, &brdev->brvccs, brvccs) { seq_printf(seq, " vcc %d.%d.%d: encaps=%s" diff --git a/net/atm/lec.c b/net/atm/lec.c index 813a090dcaf4..c909c76223e1 100644 --- a/net/atm/lec.c +++ b/net/atm/lec.c @@ -266,6 +266,7 @@ static int lec_start_xmit(struct sk_buff *skb, struct net_device *dev) char buf[300]; int i = 0; #endif /* DUMP_PACKETS >0 */ + DECLARE_MAC_BUF(mac); pr_debug("lec_start_xmit called\n"); if (!priv->lecd) { @@ -373,19 +374,15 @@ static int lec_start_xmit(struct sk_buff *skb, struct net_device *dev) if (entry && (entry->tx_wait.qlen < LEC_UNRES_QUE_LEN)) { pr_debug("%s:lec_start_xmit: queuing packet, ", dev->name); - pr_debug("MAC address 0x%02x:%02x:%02x:%02x:%02x:%02x\n", - lec_h->h_dest[0], lec_h->h_dest[1], - lec_h->h_dest[2], lec_h->h_dest[3], - lec_h->h_dest[4], lec_h->h_dest[5]); + pr_debug("MAC address %s\n", + print_mac(mac, lec_h->h_dest)); skb_queue_tail(&entry->tx_wait, skb); } else { pr_debug ("%s:lec_start_xmit: tx queue full or no arp entry, dropping, ", dev->name); - pr_debug("MAC address 0x%02x:%02x:%02x:%02x:%02x:%02x\n", - lec_h->h_dest[0], lec_h->h_dest[1], - lec_h->h_dest[2], lec_h->h_dest[3], - lec_h->h_dest[4], lec_h->h_dest[5]); + pr_debug("MAC address %s\n", + print_mac(mac, lec_h->h_dest)); priv->stats.tx_dropped++; dev_kfree_skb(skb); } @@ -397,9 +394,8 @@ static int lec_start_xmit(struct sk_buff *skb, struct net_device *dev) while (entry && (skb2 = skb_dequeue(&entry->tx_wait))) { pr_debug("lec.c: emptying tx queue, "); - pr_debug("MAC address 0x%02x:%02x:%02x:%02x:%02x:%02x\n", - lec_h->h_dest[0], lec_h->h_dest[1], lec_h->h_dest[2], - lec_h->h_dest[3], lec_h->h_dest[4], lec_h->h_dest[5]); + pr_debug("MAC address %s\n", + print_mac(mac, lec_h->h_dest)); lec_send(vcc, skb2, priv); } @@ -453,6 +449,7 @@ static int lec_atm_send(struct atm_vcc *vcc, struct sk_buff *skb) struct lec_arp_table *entry; int i; char *tmp; /* FIXME */ + DECLARE_MAC_BUF(mac); atomic_sub(skb->truesize, &sk_atm(vcc)->sk_wmem_alloc); mesg = (struct atmlec_msg *)skb->data; @@ -539,13 +536,9 @@ static int lec_atm_send(struct atm_vcc *vcc, struct sk_buff *skb) struct net_bridge_fdb_entry *f; pr_debug - ("%s: bridge zeppelin asks about 0x%02x:%02x:%02x:%02x:%02x:%02x\n", - dev->name, mesg->content.proxy.mac_addr[0], - mesg->content.proxy.mac_addr[1], - mesg->content.proxy.mac_addr[2], - mesg->content.proxy.mac_addr[3], - mesg->content.proxy.mac_addr[4], - mesg->content.proxy.mac_addr[5]); + ("%s: bridge zeppelin asks about %s\n", + dev->name, + print_mac(mac, mesg->content.proxy.mac_addr)); if (br_fdb_get_hook == NULL || dev->br_port == NULL) break; diff --git a/net/core/netpoll.c b/net/core/netpoll.c index bb7523a5b408..e13602d8154d 100644 --- a/net/core/netpoll.c +++ b/net/core/netpoll.c @@ -534,6 +534,7 @@ out: void netpoll_print_options(struct netpoll *np) { + DECLARE_MAC_BUF(mac); printk(KERN_INFO "%s: local port %d\n", np->name, np->local_port); printk(KERN_INFO "%s: local IP %d.%d.%d.%d\n", @@ -544,15 +545,8 @@ void netpoll_print_options(struct netpoll *np) np->name, np->remote_port); printk(KERN_INFO "%s: remote IP %d.%d.%d.%d\n", np->name, HIPQUAD(np->remote_ip)); - printk(KERN_INFO "%s: remote ethernet address " - "%02x:%02x:%02x:%02x:%02x:%02x\n", - np->name, - np->remote_mac[0], - np->remote_mac[1], - np->remote_mac[2], - np->remote_mac[3], - np->remote_mac[4], - np->remote_mac[5]); + printk(KERN_INFO "%s: remote ethernet address %s\n", + np->name, print_mac(mac, np->remote_mac)); } int netpoll_parse_options(struct netpoll *np, char *opt) diff --git a/net/core/pktgen.c b/net/core/pktgen.c index 94e42be16daa..f07bd590f8f9 100644 --- a/net/core/pktgen.c +++ b/net/core/pktgen.c @@ -599,11 +599,11 @@ static const struct file_operations pktgen_fops = { static int pktgen_if_show(struct seq_file *seq, void *v) { - int i; struct pktgen_dev *pkt_dev = seq->private; __u64 sa; __u64 stopped; __u64 now = getCurUs(); + DECLARE_MAC_BUF(mac); seq_printf(seq, "Params: count %llu min_pkt_size: %u max_pkt_size: %u\n", @@ -648,19 +648,12 @@ static int pktgen_if_show(struct seq_file *seq, void *v) seq_puts(seq, " src_mac: "); - if (is_zero_ether_addr(pkt_dev->src_mac)) - for (i = 0; i < 6; i++) - seq_printf(seq, "%02X%s", pkt_dev->odev->dev_addr[i], - i == 5 ? " " : ":"); - else - for (i = 0; i < 6; i++) - seq_printf(seq, "%02X%s", pkt_dev->src_mac[i], - i == 5 ? " " : ":"); + seq_printf(seq, "%s ", + print_mac(mac, is_zero_ether_addr(pkt_dev->src_mac) ? + pkt_dev->odev->dev_addr : pkt_dev->src_mac)); seq_printf(seq, "dst_mac: "); - for (i = 0; i < 6; i++) - seq_printf(seq, "%02X%s", pkt_dev->dst_mac[i], - i == 5 ? "\n" : ":"); + seq_printf(seq, "%s\n", print_mac(mac, pkt_dev->dst_mac)); seq_printf(seq, " udp_src_min: %d udp_src_max: %d udp_dst_min: %d udp_dst_max: %d\n", diff --git a/net/ethernet/eth.c b/net/ethernet/eth.c index 57c592ed0105..2aaf6faf74ac 100644 --- a/net/ethernet/eth.c +++ b/net/ethernet/eth.c @@ -337,3 +337,11 @@ struct net_device *alloc_etherdev_mq(int sizeof_priv, unsigned int queue_count) return alloc_netdev_mq(sizeof_priv, "eth%d", ether_setup, queue_count); } EXPORT_SYMBOL(alloc_etherdev_mq); + +char *print_mac(char *buf, const u8 *addr) +{ + sprintf(buf, MAC_FMT, + addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]); + return buf; +} +EXPORT_SYMBOL(print_mac); diff --git a/net/ieee80211/ieee80211_crypt_ccmp.c b/net/ieee80211/ieee80211_crypt_ccmp.c index 2e6b099fc84c..0936a3e0210b 100644 --- a/net/ieee80211/ieee80211_crypt_ccmp.c +++ b/net/ieee80211/ieee80211_crypt_ccmp.c @@ -297,6 +297,7 @@ static int ieee80211_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv) int i, blocks, last, len; size_t data_len = skb->len - hdr_len - CCMP_HDR_LEN - CCMP_MIC_LEN; u8 *mic = skb->data + skb->len - CCMP_MIC_LEN; + DECLARE_MAC_BUF(mac); if (skb->len < hdr_len + CCMP_HDR_LEN + CCMP_MIC_LEN) { key->dot11RSNAStatsCCMPFormatErrors++; @@ -309,7 +310,7 @@ static int ieee80211_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv) if (!(keyidx & (1 << 5))) { if (net_ratelimit()) { printk(KERN_DEBUG "CCMP: received packet without ExtIV" - " flag from " MAC_FMT "\n", MAC_ARG(hdr->addr2)); + " flag from %s\n", print_mac(mac, hdr->addr2)); } key->dot11RSNAStatsCCMPFormatErrors++; return -2; @@ -322,9 +323,9 @@ static int ieee80211_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv) } if (!key->key_set) { if (net_ratelimit()) { - printk(KERN_DEBUG "CCMP: received packet from " MAC_FMT + printk(KERN_DEBUG "CCMP: received packet from %s" " with keyid=%d that does not have a configured" - " key\n", MAC_ARG(hdr->addr2), keyidx); + " key\n", print_mac(mac, hdr->addr2), keyidx); } return -3; } @@ -339,11 +340,13 @@ static int ieee80211_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv) if (ccmp_replay_check(pn, key->rx_pn)) { if (net_ratelimit()) { - IEEE80211_DEBUG_DROP("CCMP: replay detected: STA=" MAC_FMT - " previous PN %02x%02x%02x%02x%02x%02x " - "received PN %02x%02x%02x%02x%02x%02x\n", - MAC_ARG(hdr->addr2), MAC_ARG(key->rx_pn), - MAC_ARG(pn)); + IEEE80211_DEBUG_DROP("CCMP: replay detected: STA=%s " + "previous PN %02x%02x%02x%02x%02x%02x " + "received PN %02x%02x%02x%02x%02x%02x\n", + print_mac(mac, hdr->addr2), + key->rx_pn[0], key->rx_pn[1], key->rx_pn[2], + key->rx_pn[3], key->rx_pn[4], key->rx_pn[5], + pn[0], pn[1], pn[2], pn[3], pn[4], pn[5]); } key->dot11RSNAStatsCCMPReplays++; return -4; @@ -371,7 +374,7 @@ static int ieee80211_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv) if (memcmp(mic, a, CCMP_MIC_LEN) != 0) { if (net_ratelimit()) { printk(KERN_DEBUG "CCMP: decrypt failed: STA=" - MAC_FMT "\n", MAC_ARG(hdr->addr2)); + "%s\n", print_mac(mac, hdr->addr2)); } key->dot11RSNAStatsCCMPDecryptErrors++; return -5; @@ -443,12 +446,16 @@ static int ieee80211_ccmp_get_key(void *key, int len, u8 * seq, void *priv) static char *ieee80211_ccmp_print_stats(char *p, void *priv) { struct ieee80211_ccmp_data *ccmp = priv; + p += sprintf(p, "key[%d] alg=CCMP key_set=%d " "tx_pn=%02x%02x%02x%02x%02x%02x " "rx_pn=%02x%02x%02x%02x%02x%02x " "format_errors=%d replays=%d decrypt_errors=%d\n", ccmp->key_idx, ccmp->key_set, - MAC_ARG(ccmp->tx_pn), MAC_ARG(ccmp->rx_pn), + ccmp->tx_pn[0], ccmp->tx_pn[1], ccmp->tx_pn[2], + ccmp->tx_pn[3], ccmp->tx_pn[4], ccmp->tx_pn[5], + ccmp->rx_pn[0], ccmp->rx_pn[1], ccmp->rx_pn[2], + ccmp->rx_pn[3], ccmp->rx_pn[4], ccmp->rx_pn[5], ccmp->dot11RSNAStatsCCMPFormatErrors, ccmp->dot11RSNAStatsCCMPReplays, ccmp->dot11RSNAStatsCCMPDecryptErrors); diff --git a/net/ieee80211/ieee80211_crypt_tkip.c b/net/ieee80211/ieee80211_crypt_tkip.c index 5a48d8e0aec1..6cc54eeca3ed 100644 --- a/net/ieee80211/ieee80211_crypt_tkip.c +++ b/net/ieee80211/ieee80211_crypt_tkip.c @@ -359,14 +359,15 @@ static int ieee80211_tkip_encrypt(struct sk_buff *skb, int hdr_len, void *priv) u8 rc4key[16], *pos, *icv; u32 crc; struct scatterlist sg; + DECLARE_MAC_BUF(mac); if (tkey->flags & IEEE80211_CRYPTO_TKIP_COUNTERMEASURES) { if (net_ratelimit()) { struct ieee80211_hdr_4addr *hdr = (struct ieee80211_hdr_4addr *)skb->data; printk(KERN_DEBUG ": TKIP countermeasures: dropped " - "TX packet to " MAC_FMT "\n", - MAC_ARG(hdr->addr1)); + "TX packet to %s\n", + print_mac(mac, hdr->addr1)); } return -1; } @@ -421,14 +422,15 @@ static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv) u32 crc; struct scatterlist sg; int plen; + DECLARE_MAC_BUF(mac); hdr = (struct ieee80211_hdr_4addr *)skb->data; if (tkey->flags & IEEE80211_CRYPTO_TKIP_COUNTERMEASURES) { if (net_ratelimit()) { printk(KERN_DEBUG ": TKIP countermeasures: dropped " - "received packet from " MAC_FMT "\n", - MAC_ARG(hdr->addr2)); + "received packet from %s\n", + print_mac(mac, hdr->addr2)); } return -1; } @@ -441,7 +443,7 @@ static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv) if (!(keyidx & (1 << 5))) { if (net_ratelimit()) { printk(KERN_DEBUG "TKIP: received packet without ExtIV" - " flag from " MAC_FMT "\n", MAC_ARG(hdr->addr2)); + " flag from %s\n", print_mac(mac, hdr->addr2)); } return -2; } @@ -453,9 +455,9 @@ static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv) } if (!tkey->key_set) { if (net_ratelimit()) { - printk(KERN_DEBUG "TKIP: received packet from " MAC_FMT + printk(KERN_DEBUG "TKIP: received packet from %s" " with keyid=%d that does not have a configured" - " key\n", MAC_ARG(hdr->addr2), keyidx); + " key\n", print_mac(mac, hdr->addr2), keyidx); } return -3; } @@ -465,9 +467,9 @@ static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv) if (tkip_replay_check(iv32, iv16, tkey->rx_iv32, tkey->rx_iv16)) { if (net_ratelimit()) { - IEEE80211_DEBUG_DROP("TKIP: replay detected: STA=" MAC_FMT + IEEE80211_DEBUG_DROP("TKIP: replay detected: STA=%s" " previous TSC %08x%04x received TSC " - "%08x%04x\n", MAC_ARG(hdr->addr2), + "%08x%04x\n", print_mac(mac, hdr->addr2), tkey->rx_iv32, tkey->rx_iv16, iv32, iv16); } tkey->dot11RSNAStatsTKIPReplays++; @@ -489,8 +491,8 @@ static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv) if (crypto_blkcipher_decrypt(&desc, &sg, &sg, plen + 4)) { if (net_ratelimit()) { printk(KERN_DEBUG ": TKIP: failed to decrypt " - "received packet from " MAC_FMT "\n", - MAC_ARG(hdr->addr2)); + "received packet from %s\n", + print_mac(mac, hdr->addr2)); } return -7; } @@ -508,7 +510,7 @@ static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv) } if (net_ratelimit()) { IEEE80211_DEBUG_DROP("TKIP: ICV error detected: STA=" - MAC_FMT "\n", MAC_ARG(hdr->addr2)); + "%s\n", print_mac(mac, hdr->addr2)); } tkey->dot11RSNAStatsTKIPICVErrors++; return -5; @@ -639,6 +641,7 @@ static int ieee80211_michael_mic_verify(struct sk_buff *skb, int keyidx, { struct ieee80211_tkip_data *tkey = priv; u8 mic[8]; + DECLARE_MAC_BUF(mac); if (!tkey->key_set) return -1; @@ -651,8 +654,8 @@ static int ieee80211_michael_mic_verify(struct sk_buff *skb, int keyidx, struct ieee80211_hdr_4addr *hdr; hdr = (struct ieee80211_hdr_4addr *)skb->data; printk(KERN_DEBUG "%s: Michael MIC verification failed for " - "MSDU from " MAC_FMT " keyidx=%d\n", - skb->dev ? skb->dev->name : "N/A", MAC_ARG(hdr->addr2), + "MSDU from %s keyidx=%d\n", + skb->dev ? skb->dev->name : "N/A", print_mac(mac, hdr->addr2), keyidx); if (skb->dev) ieee80211_michael_mic_failure(skb->dev, hdr, keyidx); diff --git a/net/ieee80211/ieee80211_rx.c b/net/ieee80211/ieee80211_rx.c index 6284c99b456e..21c0fadde03b 100644 --- a/net/ieee80211/ieee80211_rx.c +++ b/net/ieee80211/ieee80211_rx.c @@ -271,6 +271,7 @@ ieee80211_rx_frame_decrypt(struct ieee80211_device *ieee, struct sk_buff *skb, { struct ieee80211_hdr_3addr *hdr; int res, hdrlen; + DECLARE_MAC_BUF(mac); if (crypt == NULL || crypt->ops->decrypt_mpdu == NULL) return 0; @@ -282,8 +283,8 @@ ieee80211_rx_frame_decrypt(struct ieee80211_device *ieee, struct sk_buff *skb, res = crypt->ops->decrypt_mpdu(skb, hdrlen, crypt->priv); atomic_dec(&crypt->refcnt); if (res < 0) { - IEEE80211_DEBUG_DROP("decryption failed (SA=" MAC_FMT - ") res=%d\n", MAC_ARG(hdr->addr2), res); + IEEE80211_DEBUG_DROP("decryption failed (SA=%s" + ") res=%d\n", print_mac(mac, hdr->addr2), res); if (res == -2) IEEE80211_DEBUG_DROP("Decryption failed ICV " "mismatch (key %d)\n", @@ -303,6 +304,7 @@ ieee80211_rx_frame_decrypt_msdu(struct ieee80211_device *ieee, { struct ieee80211_hdr_3addr *hdr; int res, hdrlen; + DECLARE_MAC_BUF(mac); if (crypt == NULL || crypt->ops->decrypt_msdu == NULL) return 0; @@ -315,8 +317,8 @@ ieee80211_rx_frame_decrypt_msdu(struct ieee80211_device *ieee, atomic_dec(&crypt->refcnt); if (res < 0) { printk(KERN_DEBUG "%s: MSDU decryption/MIC verification failed" - " (SA=" MAC_FMT " keyidx=%d)\n", - ieee->dev->name, MAC_ARG(hdr->addr2), keyidx); + " (SA=%s keyidx=%d)\n", + ieee->dev->name, print_mac(mac, hdr->addr2), keyidx); return -1; } @@ -350,6 +352,7 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb, struct ieee80211_crypt_data *crypt = NULL; int keyidx = 0; int can_be_decrypted = 0; + DECLARE_MAC_BUF(mac); hdr = (struct ieee80211_hdr_4addr *)skb->data; stats = &ieee->stats; @@ -459,8 +462,8 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb, * frames silently instead of filling system log with * these reports. */ IEEE80211_DEBUG_DROP("Decryption failed (not set)" - " (SA=" MAC_FMT ")\n", - MAC_ARG(hdr->addr2)); + " (SA=%s)\n", + print_mac(mac, hdr->addr2)); ieee->ieee_stats.rx_discards_undecryptable++; goto rx_dropped; } @@ -471,8 +474,8 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb, fc & IEEE80211_FCTL_PROTECTED && ieee->host_decrypt && (keyidx = hostap_rx_frame_decrypt(ieee, skb, crypt)) < 0) { printk(KERN_DEBUG "%s: failed to decrypt mgmt::auth " - "from " MAC_FMT "\n", dev->name, - MAC_ARG(hdr->addr2)); + "from %s\n", dev->name, + print_mac(mac, hdr->addr2)); /* TODO: could inform hostapd about this so that it * could send auth failure report */ goto rx_dropped; @@ -650,8 +653,8 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb, * configured */ } else { IEEE80211_DEBUG_DROP("encryption configured, but RX " - "frame not encrypted (SA=" MAC_FMT - ")\n", MAC_ARG(hdr->addr2)); + "frame not encrypted (SA=%s" + ")\n", print_mac(mac, hdr->addr2)); goto rx_dropped; } } @@ -659,9 +662,9 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb, if (crypt && !(fc & IEEE80211_FCTL_PROTECTED) && !ieee->open_wep && !ieee80211_is_eapol_frame(ieee, skb)) { IEEE80211_DEBUG_DROP("dropped unencrypted RX data " - "frame from " MAC_FMT + "frame from %s" " (drop_unencrypted=1)\n", - MAC_ARG(hdr->addr2)); + print_mac(mac, hdr->addr2)); goto rx_dropped; } @@ -1411,6 +1414,8 @@ static int ieee80211_network_init(struct ieee80211_device *ieee, struct ieee8021 struct ieee80211_network *network, struct ieee80211_rx_stats *stats) { + DECLARE_MAC_BUF(mac); + network->qos_data.active = 0; network->qos_data.supported = 0; network->qos_data.param_count = 0; @@ -1457,11 +1462,11 @@ static int ieee80211_network_init(struct ieee80211_device *ieee, struct ieee8021 } if (network->mode == 0) { - IEEE80211_DEBUG_SCAN("Filtered out '%s (" MAC_FMT ")' " + IEEE80211_DEBUG_SCAN("Filtered out '%s (%s)' " "network.\n", escape_essid(network->ssid, network->ssid_len), - MAC_ARG(network->bssid)); + print_mac(mac, network->bssid)); return 1; } @@ -1490,6 +1495,7 @@ static void update_network(struct ieee80211_network *dst, { int qos_active; u8 old_param; + DECLARE_MAC_BUF(mac); ieee80211_network_reset(dst); dst->ibss_dfs = src->ibss_dfs; @@ -1503,8 +1509,8 @@ static void update_network(struct ieee80211_network *dst, memcpy(&dst->stats, &src->stats, sizeof(struct ieee80211_rx_stats)); else - IEEE80211_DEBUG_SCAN("Network " MAC_FMT " info received " - "off channel (%d vs. %d)\n", MAC_ARG(src->bssid), + IEEE80211_DEBUG_SCAN("Network %s info received " + "off channel (%d vs. %d)\n", print_mac(mac, src->bssid), dst->channel, src->stats.received_channel); dst->capability = src->capability; @@ -1576,12 +1582,13 @@ static void ieee80211_process_probe_response(struct ieee80211_device struct ieee80211_info_element *info_element = beacon->info_element; #endif unsigned long flags; + DECLARE_MAC_BUF(mac); - IEEE80211_DEBUG_SCAN("'%s' (" MAC_FMT + IEEE80211_DEBUG_SCAN("'%s' (%s" "): %c%c%c%c %c%c%c%c-%c%c%c%c %c%c%c%c\n", escape_essid(info_element->data, info_element->len), - MAC_ARG(beacon->header.addr3), + print_mac(mac, beacon->header.addr3), (beacon->capability & (1 << 0xf)) ? '1' : '0', (beacon->capability & (1 << 0xe)) ? '1' : '0', (beacon->capability & (1 << 0xd)) ? '1' : '0', @@ -1600,10 +1607,10 @@ static void ieee80211_process_probe_response(struct ieee80211_device (beacon->capability & (1 << 0x0)) ? '1' : '0'); if (ieee80211_network_init(ieee, beacon, &network, stats)) { - IEEE80211_DEBUG_SCAN("Dropped '%s' (" MAC_FMT ") via %s.\n", + IEEE80211_DEBUG_SCAN("Dropped '%s' (%s) via %s.\n", escape_essid(info_element->data, info_element->len), - MAC_ARG(beacon->header.addr3), + print_mac(mac, beacon->header.addr3), is_beacon(beacon->header.frame_ctl) ? "BEACON" : "PROBE RESPONSE"); return; @@ -1637,11 +1644,11 @@ static void ieee80211_process_probe_response(struct ieee80211_device /* If there are no more slots, expire the oldest */ list_del(&oldest->list); target = oldest; - IEEE80211_DEBUG_SCAN("Expired '%s' (" MAC_FMT ") from " + IEEE80211_DEBUG_SCAN("Expired '%s' (%s) from " "network list.\n", escape_essid(target->ssid, target->ssid_len), - MAC_ARG(target->bssid)); + print_mac(mac, target->bssid)); ieee80211_network_reset(target); } else { /* Otherwise just pull from the free list */ @@ -1651,10 +1658,10 @@ static void ieee80211_process_probe_response(struct ieee80211_device } #ifdef CONFIG_IEEE80211_DEBUG - IEEE80211_DEBUG_SCAN("Adding '%s' (" MAC_FMT ") via %s.\n", + IEEE80211_DEBUG_SCAN("Adding '%s' (%s) via %s.\n", escape_essid(network.ssid, network.ssid_len), - MAC_ARG(network.bssid), + print_mac(mac, network.bssid), is_beacon(beacon->header.frame_ctl) ? "BEACON" : "PROBE RESPONSE"); #endif @@ -1662,10 +1669,10 @@ static void ieee80211_process_probe_response(struct ieee80211_device network.ibss_dfs = NULL; list_add_tail(&target->list, &ieee->network_list); } else { - IEEE80211_DEBUG_SCAN("Updating '%s' (" MAC_FMT ") via %s.\n", + IEEE80211_DEBUG_SCAN("Updating '%s' (%s) via %s.\n", escape_essid(target->ssid, target->ssid_len), - MAC_ARG(target->bssid), + print_mac(mac, target->bssid), is_beacon(beacon->header.frame_ctl) ? "BEACON" : "PROBE RESPONSE"); update_network(target, &network); diff --git a/net/ieee80211/ieee80211_wx.c b/net/ieee80211/ieee80211_wx.c index 465b73d50532..9b58dd67acb6 100644 --- a/net/ieee80211/ieee80211_wx.c +++ b/net/ieee80211/ieee80211_wx.c @@ -257,6 +257,7 @@ int ieee80211_wx_get_scan(struct ieee80211_device *ieee, char *ev = extra; char *stop = ev + wrqu->data.length; int i = 0; + DECLARE_MAC_BUF(mac); IEEE80211_DEBUG_WX("Getting scan\n"); @@ -274,10 +275,10 @@ int ieee80211_wx_get_scan(struct ieee80211_device *ieee, ev = ieee80211_translate_scan(ieee, ev, stop, network); else IEEE80211_DEBUG_SCAN("Not showing network '%s (" - MAC_FMT ")' due to age (%dms).\n", + "%s)' due to age (%dms).\n", escape_essid(network->ssid, network->ssid_len), - MAC_ARG(network->bssid), + print_mac(mac, network->bssid), jiffies_to_msecs(jiffies - network-> last_scanned)); diff --git a/net/ieee80211/softmac/ieee80211softmac_assoc.c b/net/ieee80211/softmac/ieee80211softmac_assoc.c index e475f2e1be13..4c0feb2dacd8 100644 --- a/net/ieee80211/softmac/ieee80211softmac_assoc.c +++ b/net/ieee80211/softmac/ieee80211softmac_assoc.c @@ -372,6 +372,7 @@ ieee80211softmac_handle_assoc_response(struct net_device * dev, u16 status = le16_to_cpup(&resp->status); struct ieee80211softmac_network *network = NULL; unsigned long flags; + DECLARE_MAC_BUF(mac2); if (unlikely(!mac->running)) return -ENODEV; @@ -388,7 +389,8 @@ ieee80211softmac_handle_assoc_response(struct net_device * dev, /* someone sending us things without us knowing him? Ignore. */ if (!network) { - dprintk(KERN_INFO PFX "Received unrequested assocation response from " MAC_FMT "\n", MAC_ARG(resp->header.addr3)); + dprintk(KERN_INFO PFX "Received unrequested assocation response from %s\n", + print_mac(mac2, resp->header.addr3)); spin_unlock_irqrestore(&mac->lock, flags); return 0; } diff --git a/net/ieee80211/softmac/ieee80211softmac_auth.c b/net/ieee80211/softmac/ieee80211softmac_auth.c index 826c32d24461..855fa0fe641b 100644 --- a/net/ieee80211/softmac/ieee80211softmac_auth.c +++ b/net/ieee80211/softmac/ieee80211softmac_auth.c @@ -35,6 +35,7 @@ ieee80211softmac_auth_req(struct ieee80211softmac_device *mac, { struct ieee80211softmac_auth_queue_item *auth; unsigned long flags; + DECLARE_MAC_BUF(mac2); if (net->authenticating || net->authenticated) return 0; @@ -43,7 +44,7 @@ ieee80211softmac_auth_req(struct ieee80211softmac_device *mac, /* Add the network if it's not already added */ ieee80211softmac_add_network(mac, net); - dprintk(KERN_NOTICE PFX "Queueing Authentication Request to "MAC_FMT"\n", MAC_ARG(net->bssid)); + dprintk(KERN_NOTICE PFX "Queueing Authentication Request to %s\n", print_mac(mac2, net->bssid)); /* Queue the auth request */ auth = (struct ieee80211softmac_auth_queue_item *) kmalloc(sizeof(struct ieee80211softmac_auth_queue_item), GFP_KERNEL); @@ -76,6 +77,7 @@ ieee80211softmac_auth_queue(struct work_struct *work) struct ieee80211softmac_auth_queue_item *auth; struct ieee80211softmac_network *net; unsigned long flags; + DECLARE_MAC_BUF(mac2); auth = container_of(work, struct ieee80211softmac_auth_queue_item, work.work); @@ -99,13 +101,14 @@ ieee80211softmac_auth_queue(struct work_struct *work) auth->retry--; spin_unlock_irqrestore(&mac->lock, flags); if (ieee80211softmac_send_mgt_frame(mac, auth->net, IEEE80211_STYPE_AUTH, auth->state)) - dprintk(KERN_NOTICE PFX "Sending Authentication Request to "MAC_FMT" failed (this shouldn't happen, wait for the timeout).\n", MAC_ARG(net->bssid)); + dprintk(KERN_NOTICE PFX "Sending Authentication Request to %s failed (this shouldn't happen, wait for the timeout).\n", + print_mac(mac2, net->bssid)); else - dprintk(KERN_NOTICE PFX "Sent Authentication Request to "MAC_FMT".\n", MAC_ARG(net->bssid)); + dprintk(KERN_NOTICE PFX "Sent Authentication Request to %s.\n", print_mac(mac2, net->bssid)); return; } - printkl(KERN_WARNING PFX "Authentication timed out with "MAC_FMT"\n", MAC_ARG(net->bssid)); + printkl(KERN_WARNING PFX "Authentication timed out with %s\n", print_mac(mac2, net->bssid)); /* Remove this item from the queue */ spin_lock_irqsave(&mac->lock, flags); net->authenticating = 0; @@ -142,6 +145,7 @@ ieee80211softmac_auth_resp(struct net_device *dev, struct ieee80211_auth *auth) struct ieee80211softmac_network *net = NULL; unsigned long flags; u8 * data; + DECLARE_MAC_BUF(mac2); if (unlikely(!mac->running)) return -ENODEV; @@ -161,7 +165,7 @@ ieee80211softmac_auth_resp(struct net_device *dev, struct ieee80211_auth *auth) /* Make sure that we've got an auth queue item for this request */ if(aq == NULL) { - dprintkl(KERN_DEBUG PFX "Authentication response received from "MAC_FMT" but no queue item exists.\n", MAC_ARG(auth->header.addr2)); + dprintkl(KERN_DEBUG PFX "Authentication response received from %s but no queue item exists.\n", print_mac(mac2, auth->header.addr2)); /* Error #? */ return -1; } @@ -169,7 +173,7 @@ ieee80211softmac_auth_resp(struct net_device *dev, struct ieee80211_auth *auth) /* Check for out of order authentication */ if(!net->authenticating) { - dprintkl(KERN_DEBUG PFX "Authentication response received from "MAC_FMT" but did not request authentication.\n",MAC_ARG(auth->header.addr2)); + dprintkl(KERN_DEBUG PFX "Authentication response received from %s but did not request authentication.\n",print_mac(mac2, auth->header.addr2)); return -1; } @@ -187,7 +191,7 @@ ieee80211softmac_auth_resp(struct net_device *dev, struct ieee80211_auth *auth) spin_unlock_irqrestore(&mac->lock, flags); /* Send event */ - printkl(KERN_NOTICE PFX "Open Authentication completed with "MAC_FMT"\n", MAC_ARG(net->bssid)); + printkl(KERN_NOTICE PFX "Open Authentication completed with %s\n", print_mac(mac2, net->bssid)); ieee80211softmac_call_events(mac, IEEE80211SOFTMAC_EVENT_AUTHENTICATED, net); break; default: @@ -197,8 +201,8 @@ ieee80211softmac_auth_resp(struct net_device *dev, struct ieee80211_auth *auth) net->authenticating = 0; spin_unlock_irqrestore(&mac->lock, flags); - printkl(KERN_NOTICE PFX "Open Authentication with "MAC_FMT" failed, error code: %i\n", - MAC_ARG(net->bssid), le16_to_cpup(&auth->status)); + printkl(KERN_NOTICE PFX "Open Authentication with %s failed, error code: %i\n", + print_mac(mac2, net->bssid), le16_to_cpup(&auth->status)); /* Count the error? */ break; } @@ -253,13 +257,13 @@ ieee80211softmac_auth_resp(struct net_device *dev, struct ieee80211_auth *auth) net->authenticating = 0; net->authenticated = 1; spin_unlock_irqrestore(&mac->lock, flags); - printkl(KERN_NOTICE PFX "Shared Key Authentication completed with "MAC_FMT"\n", - MAC_ARG(net->bssid)); + printkl(KERN_NOTICE PFX "Shared Key Authentication completed with %s\n", + print_mac(mac2, net->bssid)); ieee80211softmac_call_events(mac, IEEE80211SOFTMAC_EVENT_AUTHENTICATED, net); break; default: - printkl(KERN_NOTICE PFX "Shared Key Authentication with "MAC_FMT" failed, error code: %i\n", - MAC_ARG(net->bssid), le16_to_cpup(&auth->status)); + printkl(KERN_NOTICE PFX "Shared Key Authentication with %s failed, error code: %i\n", + print_mac(mac2, net->bssid), le16_to_cpup(&auth->status)); /* Lock and reset flags */ spin_lock_irqsave(&mac->lock, flags); net->authenticating = 0; @@ -375,6 +379,7 @@ ieee80211softmac_deauth_resp(struct net_device *dev, struct ieee80211_deauth *de struct ieee80211softmac_network *net = NULL; struct ieee80211softmac_device *mac = ieee80211_priv(dev); + DECLARE_MAC_BUF(mac2); if (unlikely(!mac->running)) return -ENODEV; @@ -387,8 +392,8 @@ ieee80211softmac_deauth_resp(struct net_device *dev, struct ieee80211_deauth *de net = ieee80211softmac_get_network_by_bssid(mac, deauth->header.addr2); if (net == NULL) { - dprintkl(KERN_DEBUG PFX "Received deauthentication packet from "MAC_FMT", but that network is unknown.\n", - MAC_ARG(deauth->header.addr2)); + dprintkl(KERN_DEBUG PFX "Received deauthentication packet from %s, but that network is unknown.\n", + print_mac(mac2, deauth->header.addr2)); return 0; } diff --git a/net/ieee80211/softmac/ieee80211softmac_wx.c b/net/ieee80211/softmac/ieee80211softmac_wx.c index 5742dc803b79..8e8ad08a411c 100644 --- a/net/ieee80211/softmac/ieee80211softmac_wx.c +++ b/net/ieee80211/softmac/ieee80211softmac_wx.c @@ -72,6 +72,7 @@ ieee80211softmac_wx_set_essid(struct net_device *net_dev, struct ieee80211softmac_device *sm = ieee80211_priv(net_dev); struct ieee80211softmac_auth_queue_item *authptr; int length = 0; + DECLARE_MAC_BUF(mac); check_assoc_again: mutex_lock(&sm->associnfo.mutex); diff --git a/net/irda/irlan/irlan_client.c b/net/irda/irlan/irlan_client.c index a4c1c9545827..87039c2fb6a2 100644 --- a/net/irda/irlan/irlan_client.c +++ b/net/irda/irlan/irlan_client.c @@ -436,6 +436,7 @@ static void irlan_check_response_param(struct irlan_cb *self, char *param, __u16 tmp_cpu; /* Temporary value in host order */ __u8 *bytes; int i; + DECLARE_MAC_BUF(mac); IRDA_DEBUG(4, "%s(), parm=%s\n", __FUNCTION__ , param); @@ -520,9 +521,8 @@ static void irlan_check_response_param(struct irlan_cb *self, char *param, /* FILTER_ENTRY, have we got an ethernet address? */ if (strcmp(param, "FILTER_ENTRY") == 0) { bytes = value; - IRDA_DEBUG(4, "Ethernet address = %02x:%02x:%02x:%02x:%02x:%02x\n", - bytes[0], bytes[1], bytes[2], bytes[3], bytes[4], - bytes[5]); + IRDA_DEBUG(4, "Ethernet address = %s\n", + print_mac(mac, bytes)); for (i = 0; i < 6; i++) self->dev->dev_addr[i] = bytes[i]; } diff --git a/net/llc/llc_proc.c b/net/llc/llc_proc.c index 4865d82896b1..cb34bc0518e8 100644 --- a/net/llc/llc_proc.c +++ b/net/llc/llc_proc.c @@ -25,10 +25,10 @@ #include #include -static void llc_ui_format_mac(struct seq_file *seq, unsigned char *mac) +static void llc_ui_format_mac(struct seq_file *seq, u8 *addr) { - seq_printf(seq, "%02X:%02X:%02X:%02X:%02X:%02X", - mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); + DECLARE_MAC_BUF(mac); + seq_printf(seq, "%s", print_mac(mac, addr)); } static struct sock *llc_get_sk_idx(loff_t pos) @@ -128,8 +128,10 @@ static int llc_seq_socket_show(struct seq_file *seq, void *v) if (llc->dev) llc_ui_format_mac(seq, llc->dev->dev_addr); - else - seq_printf(seq, "00:00:00:00:00:00"); + else { + u8 addr[6] = {0,0,0,0,0,0}; + llc_ui_format_mac(seq, addr); + } seq_printf(seq, "@%02X ", llc->sap->laddr.lsap); llc_ui_format_mac(seq, llc->daddr.mac); seq_printf(seq, "@%02X %8d %8d %2d %3d %4d\n", llc->daddr.lsap, diff --git a/net/mac80211/debugfs_key.c b/net/mac80211/debugfs_key.c index 8e4a1bcd16ea..c881524c8725 100644 --- a/net/mac80211/debugfs_key.c +++ b/net/mac80211/debugfs_key.c @@ -262,11 +262,12 @@ void ieee80211_debugfs_key_sta_link(struct ieee80211_key *key, struct sta_info *sta) { char buf[50]; + DECLARE_MAC_BUF(mac); if (!key->debugfs.dir) return; - sprintf(buf, "../../stations/" MAC_FMT, MAC_ARG(sta->addr)); + sprintf(buf, "../../stations/%s", print_mac(mac, sta->addr)); key->debugfs.stalink = debugfs_create_symlink("station", key->debugfs.dir, buf); } diff --git a/net/mac80211/debugfs_netdev.c b/net/mac80211/debugfs_netdev.c index 8ceda33efc12..9efb84c47bb0 100644 --- a/net/mac80211/debugfs_netdev.c +++ b/net/mac80211/debugfs_netdev.c @@ -66,7 +66,8 @@ static ssize_t ieee80211_if_fmt_##name( \ const struct ieee80211_sub_if_data *sdata, char *buf, \ int buflen) \ { \ - return scnprintf(buf, buflen, MAC_FMT "\n", MAC_ARG(sdata->field));\ + DECLARE_MAC_BUF(mac); \ + return scnprintf(buf, buflen, "%s\n", print_mac(mac, sdata->field));\ } #define __IEEE80211_IF_FILE(name) \ diff --git a/net/mac80211/debugfs_sta.c b/net/mac80211/debugfs_sta.c index 2daaa802bbd0..f7c717c906dc 100644 --- a/net/mac80211/debugfs_sta.c +++ b/net/mac80211/debugfs_sta.c @@ -203,15 +203,15 @@ STA_OPS(wme_tx_queue); void ieee80211_sta_debugfs_add(struct sta_info *sta) { - char buf[3*6]; struct dentry *stations_dir = sta->local->debugfs.stations; + DECLARE_MAC_BUF(mac); if (!stations_dir) return; - sprintf(buf, MAC_FMT, MAC_ARG(sta->addr)); + print_mac(mac, sta->addr); - sta->debugfs.dir = debugfs_create_dir(buf, stations_dir); + sta->debugfs.dir = debugfs_create_dir(mac, stations_dir); if (!sta->debugfs.dir) return; diff --git a/net/mac80211/event.c b/net/mac80211/event.c index 68a526cb7623..2280f40b4560 100644 --- a/net/mac80211/event.c +++ b/net/mac80211/event.c @@ -22,13 +22,14 @@ void mac80211_ev_michael_mic_failure(struct net_device *dev, int keyidx, { union iwreq_data wrqu; char *buf = kmalloc(128, GFP_ATOMIC); + DECLARE_MAC_BUF(mac); if (buf) { /* TODO: needed parameters: count, key type, TSC */ sprintf(buf, "MLME-MICHAELMICFAILURE.indication(" - "keyid=%d %scast addr=" MAC_FMT ")", + "keyid=%d %scast addr=%s)", keyidx, hdr->addr1[0] & 0x01 ? "broad" : "uni", - MAC_ARG(hdr->addr2)); + print_mac(mac, hdr->addr2)); memset(&wrqu, 0, sizeof(wrqu)); wrqu.data.length = strlen(buf); wireless_send_event(dev, IWEVCUSTOM, &wrqu, buf); diff --git a/net/mac80211/ieee80211.c b/net/mac80211/ieee80211.c index 0c1f7b2e157c..4229d150e783 100644 --- a/net/mac80211/ieee80211.c +++ b/net/mac80211/ieee80211.c @@ -602,6 +602,7 @@ int ieee80211_if_update_wds(struct net_device *dev, u8 *remote_addr) struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); struct sta_info *sta; + DECLARE_MAC_BUF(mac); if (compare_ether_addr(remote_addr, sdata->u.wds.remote_addr) == 0) return 0; @@ -619,8 +620,8 @@ int ieee80211_if_update_wds(struct net_device *dev, u8 *remote_addr) sta_info_put(sta); } else { printk(KERN_DEBUG "%s: could not find STA entry for WDS link " - "peer " MAC_FMT "\n", - dev->name, MAC_ARG(sdata->u.wds.remote_addr)); + "peer %s\n", + dev->name, print_mac(mac, sdata->u.wds.remote_addr)); } /* Update WDS link data */ diff --git a/net/mac80211/ieee80211_ioctl.c b/net/mac80211/ieee80211_ioctl.c index 51dca21f77c7..6ccdde82bded 100644 --- a/net/mac80211/ieee80211_ioctl.c +++ b/net/mac80211/ieee80211_ioctl.c @@ -98,9 +98,10 @@ static int ieee80211_set_encryption(struct net_device *dev, u8 *sta_addr, sta = sta_info_get(local, sta_addr); if (!sta) { #ifdef CONFIG_MAC80211_VERBOSE_DEBUG + DECLARE_MAC_BUF(mac); printk(KERN_DEBUG "%s: set_encrypt - unknown addr " - MAC_FMT "\n", - dev->name, MAC_ARG(sta_addr)); + "%s\n", + dev->name, print_mac(mac, sta_addr)); #endif /* CONFIG_MAC80211_VERBOSE_DEBUG */ return -ENOENT; diff --git a/net/mac80211/ieee80211_sta.c b/net/mac80211/ieee80211_sta.c index 8fdbd38e02c4..f47cbd294ceb 100644 --- a/net/mac80211/ieee80211_sta.c +++ b/net/mac80211/ieee80211_sta.c @@ -319,14 +319,15 @@ static void ieee80211_handle_erp_ie(struct net_device *dev, u8 erp_value) int use_protection = (erp_value & WLAN_ERP_USE_PROTECTION) != 0; int preamble_mode = (erp_value & WLAN_ERP_BARKER_PREAMBLE) != 0; u8 changes = 0; + DECLARE_MAC_BUF(mac); if (use_protection != !!(sdata->flags & IEEE80211_SDATA_USE_PROTECTION)) { if (net_ratelimit()) { printk(KERN_DEBUG "%s: CTS protection %s (BSSID=" - MAC_FMT ")\n", + "%s)\n", dev->name, use_protection ? "enabled" : "disabled", - MAC_ARG(ifsta->bssid)); + print_mac(mac, ifsta->bssid)); } if (use_protection) sdata->flags |= IEEE80211_SDATA_USE_PROTECTION; @@ -338,11 +339,11 @@ static void ieee80211_handle_erp_ie(struct net_device *dev, u8 erp_value) if (preamble_mode != !(sdata->flags & IEEE80211_SDATA_SHORT_PREAMBLE)) { if (net_ratelimit()) { printk(KERN_DEBUG "%s: switched to %s barker preamble" - " (BSSID=" MAC_FMT ")\n", + " (BSSID=%s)\n", dev->name, (preamble_mode == WLAN_ERP_PREAMBLE_SHORT) ? "short" : "long", - MAC_ARG(ifsta->bssid)); + print_mac(mac, ifsta->bssid)); } if (preamble_mode) sdata->flags &= ~IEEE80211_SDATA_SHORT_PREAMBLE; @@ -524,18 +525,20 @@ static void ieee80211_send_auth(struct net_device *dev, static void ieee80211_authenticate(struct net_device *dev, struct ieee80211_if_sta *ifsta) { + DECLARE_MAC_BUF(mac); + ifsta->auth_tries++; if (ifsta->auth_tries > IEEE80211_AUTH_MAX_TRIES) { - printk(KERN_DEBUG "%s: authentication with AP " MAC_FMT + printk(KERN_DEBUG "%s: authentication with AP %s" " timed out\n", - dev->name, MAC_ARG(ifsta->bssid)); + dev->name, print_mac(mac, ifsta->bssid)); ifsta->state = IEEE80211_DISABLED; return; } ifsta->state = IEEE80211_AUTHENTICATE; - printk(KERN_DEBUG "%s: authenticate with AP " MAC_FMT "\n", - dev->name, MAC_ARG(ifsta->bssid)); + printk(KERN_DEBUG "%s: authenticate with AP %s\n", + dev->name, print_mac(mac, ifsta->bssid)); ieee80211_send_auth(dev, ifsta, 1, NULL, 0, 0); @@ -744,18 +747,20 @@ static int ieee80211_privacy_mismatch(struct net_device *dev, static void ieee80211_associate(struct net_device *dev, struct ieee80211_if_sta *ifsta) { + DECLARE_MAC_BUF(mac); + ifsta->assoc_tries++; if (ifsta->assoc_tries > IEEE80211_ASSOC_MAX_TRIES) { - printk(KERN_DEBUG "%s: association with AP " MAC_FMT + printk(KERN_DEBUG "%s: association with AP %s" " timed out\n", - dev->name, MAC_ARG(ifsta->bssid)); + dev->name, print_mac(mac, ifsta->bssid)); ifsta->state = IEEE80211_DISABLED; return; } ifsta->state = IEEE80211_ASSOCIATE; - printk(KERN_DEBUG "%s: associate with AP " MAC_FMT "\n", - dev->name, MAC_ARG(ifsta->bssid)); + printk(KERN_DEBUG "%s: associate with AP %s\n", + dev->name, print_mac(mac, ifsta->bssid)); if (ieee80211_privacy_mismatch(dev, ifsta)) { printk(KERN_DEBUG "%s: mismatch in privacy configuration and " "mixed-cell disabled - abort association\n", dev->name); @@ -775,6 +780,7 @@ static void ieee80211_associated(struct net_device *dev, struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); struct sta_info *sta; int disassoc; + DECLARE_MAC_BUF(mac); /* TODO: start monitoring current AP signal quality and number of * missed beacons. Scan other channels every now and then and search @@ -785,8 +791,8 @@ static void ieee80211_associated(struct net_device *dev, sta = sta_info_get(local, ifsta->bssid); if (!sta) { - printk(KERN_DEBUG "%s: No STA entry for own AP " MAC_FMT "\n", - dev->name, MAC_ARG(ifsta->bssid)); + printk(KERN_DEBUG "%s: No STA entry for own AP %s\n", + dev->name, print_mac(mac, ifsta->bssid)); disassoc = 1; } else { disassoc = 0; @@ -794,9 +800,9 @@ static void ieee80211_associated(struct net_device *dev, sta->last_rx + IEEE80211_MONITORING_INTERVAL)) { if (ifsta->flags & IEEE80211_STA_PROBEREQ_POLL) { printk(KERN_DEBUG "%s: No ProbeResp from " - "current AP " MAC_FMT " - assume out of " + "current AP %s - assume out of " "range\n", - dev->name, MAC_ARG(ifsta->bssid)); + dev->name, print_mac(mac, ifsta->bssid)); disassoc = 1; sta_info_free(sta); } else @@ -944,37 +950,38 @@ static void ieee80211_rx_mgmt_auth(struct net_device *dev, { struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); u16 auth_alg, auth_transaction, status_code; + DECLARE_MAC_BUF(mac); if (ifsta->state != IEEE80211_AUTHENTICATE && sdata->type != IEEE80211_IF_TYPE_IBSS) { printk(KERN_DEBUG "%s: authentication frame received from " - MAC_FMT ", but not in authenticate state - ignored\n", - dev->name, MAC_ARG(mgmt->sa)); + "%s, but not in authenticate state - ignored\n", + dev->name, print_mac(mac, mgmt->sa)); return; } if (len < 24 + 6) { printk(KERN_DEBUG "%s: too short (%zd) authentication frame " - "received from " MAC_FMT " - ignored\n", - dev->name, len, MAC_ARG(mgmt->sa)); + "received from %s - ignored\n", + dev->name, len, print_mac(mac, mgmt->sa)); return; } if (sdata->type != IEEE80211_IF_TYPE_IBSS && memcmp(ifsta->bssid, mgmt->sa, ETH_ALEN) != 0) { printk(KERN_DEBUG "%s: authentication frame received from " - "unknown AP (SA=" MAC_FMT " BSSID=" MAC_FMT ") - " - "ignored\n", dev->name, MAC_ARG(mgmt->sa), - MAC_ARG(mgmt->bssid)); + "unknown AP (SA=%s BSSID=%s) - " + "ignored\n", dev->name, print_mac(mac, mgmt->sa), + print_mac(mac, mgmt->bssid)); return; } if (sdata->type != IEEE80211_IF_TYPE_IBSS && memcmp(ifsta->bssid, mgmt->bssid, ETH_ALEN) != 0) { printk(KERN_DEBUG "%s: authentication frame received from " - "unknown BSSID (SA=" MAC_FMT " BSSID=" MAC_FMT ") - " - "ignored\n", dev->name, MAC_ARG(mgmt->sa), - MAC_ARG(mgmt->bssid)); + "unknown BSSID (SA=%s BSSID=%s) - " + "ignored\n", dev->name, print_mac(mac, mgmt->sa), + print_mac(mac, mgmt->bssid)); return; } @@ -982,9 +989,9 @@ static void ieee80211_rx_mgmt_auth(struct net_device *dev, auth_transaction = le16_to_cpu(mgmt->u.auth.auth_transaction); status_code = le16_to_cpu(mgmt->u.auth.status_code); - printk(KERN_DEBUG "%s: RX authentication from " MAC_FMT " (alg=%d " + printk(KERN_DEBUG "%s: RX authentication from %s (alg=%d " "transaction=%d status=%d)\n", - dev->name, MAC_ARG(mgmt->sa), auth_alg, + dev->name, print_mac(mac, mgmt->sa), auth_alg, auth_transaction, status_code); if (sdata->type == IEEE80211_IF_TYPE_IBSS) { @@ -1071,27 +1078,28 @@ static void ieee80211_rx_mgmt_deauth(struct net_device *dev, size_t len) { u16 reason_code; + DECLARE_MAC_BUF(mac); if (len < 24 + 2) { printk(KERN_DEBUG "%s: too short (%zd) deauthentication frame " - "received from " MAC_FMT " - ignored\n", - dev->name, len, MAC_ARG(mgmt->sa)); + "received from %s - ignored\n", + dev->name, len, print_mac(mac, mgmt->sa)); return; } if (memcmp(ifsta->bssid, mgmt->sa, ETH_ALEN) != 0) { printk(KERN_DEBUG "%s: deauthentication frame received from " - "unknown AP (SA=" MAC_FMT " BSSID=" MAC_FMT ") - " - "ignored\n", dev->name, MAC_ARG(mgmt->sa), - MAC_ARG(mgmt->bssid)); + "unknown AP (SA=%s BSSID=%s) - " + "ignored\n", dev->name, print_mac(mac, mgmt->sa), + print_mac(mac, mgmt->bssid)); return; } reason_code = le16_to_cpu(mgmt->u.deauth.reason_code); - printk(KERN_DEBUG "%s: RX deauthentication from " MAC_FMT + printk(KERN_DEBUG "%s: RX deauthentication from %s" " (reason=%d)\n", - dev->name, MAC_ARG(mgmt->sa), reason_code); + dev->name, print_mac(mac, mgmt->sa), reason_code); if (ifsta->flags & IEEE80211_STA_AUTHENTICATED) { printk(KERN_DEBUG "%s: deauthenticated\n", dev->name); @@ -1116,27 +1124,28 @@ static void ieee80211_rx_mgmt_disassoc(struct net_device *dev, size_t len) { u16 reason_code; + DECLARE_MAC_BUF(mac); if (len < 24 + 2) { printk(KERN_DEBUG "%s: too short (%zd) disassociation frame " - "received from " MAC_FMT " - ignored\n", - dev->name, len, MAC_ARG(mgmt->sa)); + "received from %s - ignored\n", + dev->name, len, print_mac(mac, mgmt->sa)); return; } if (memcmp(ifsta->bssid, mgmt->sa, ETH_ALEN) != 0) { printk(KERN_DEBUG "%s: disassociation frame received from " - "unknown AP (SA=" MAC_FMT " BSSID=" MAC_FMT ") - " - "ignored\n", dev->name, MAC_ARG(mgmt->sa), - MAC_ARG(mgmt->bssid)); + "unknown AP (SA=%s BSSID=%s) - " + "ignored\n", dev->name, print_mac(mac, mgmt->sa), + print_mac(mac, mgmt->bssid)); return; } reason_code = le16_to_cpu(mgmt->u.disassoc.reason_code); - printk(KERN_DEBUG "%s: RX disassociation from " MAC_FMT + printk(KERN_DEBUG "%s: RX disassociation from %s" " (reason=%d)\n", - dev->name, MAC_ARG(mgmt->sa), reason_code); + dev->name, print_mac(mac, mgmt->sa), reason_code); if (ifsta->flags & IEEE80211_STA_ASSOCIATED) printk(KERN_DEBUG "%s: disassociated\n", dev->name); @@ -1165,29 +1174,30 @@ static void ieee80211_rx_mgmt_assoc_resp(struct net_device *dev, struct ieee802_11_elems elems; u8 *pos; int i, j; + DECLARE_MAC_BUF(mac); /* AssocResp and ReassocResp have identical structure, so process both * of them in this function. */ if (ifsta->state != IEEE80211_ASSOCIATE) { printk(KERN_DEBUG "%s: association frame received from " - MAC_FMT ", but not in associate state - ignored\n", - dev->name, MAC_ARG(mgmt->sa)); + "%s, but not in associate state - ignored\n", + dev->name, print_mac(mac, mgmt->sa)); return; } if (len < 24 + 6) { printk(KERN_DEBUG "%s: too short (%zd) association frame " - "received from " MAC_FMT " - ignored\n", - dev->name, len, MAC_ARG(mgmt->sa)); + "received from %s - ignored\n", + dev->name, len, print_mac(mac, mgmt->sa)); return; } if (memcmp(ifsta->bssid, mgmt->sa, ETH_ALEN) != 0) { printk(KERN_DEBUG "%s: association frame received from " - "unknown AP (SA=" MAC_FMT " BSSID=" MAC_FMT ") - " - "ignored\n", dev->name, MAC_ARG(mgmt->sa), - MAC_ARG(mgmt->bssid)); + "unknown AP (SA=%s BSSID=%s) - " + "ignored\n", dev->name, print_mac(mac, mgmt->sa), + print_mac(mac, mgmt->bssid)); return; } @@ -1199,9 +1209,9 @@ static void ieee80211_rx_mgmt_assoc_resp(struct net_device *dev, "set\n", dev->name, aid); aid &= ~(BIT(15) | BIT(14)); - printk(KERN_DEBUG "%s: RX %sssocResp from " MAC_FMT " (capab=0x%x " + printk(KERN_DEBUG "%s: RX %sssocResp from %s (capab=0x%x " "status=%d aid=%d)\n", - dev->name, reassoc ? "Rea" : "A", MAC_ARG(mgmt->sa), + dev->name, reassoc ? "Rea" : "A", print_mac(mac, mgmt->sa), capab_info, status_code, aid); if (status_code != WLAN_STATUS_SUCCESS) { @@ -1435,14 +1445,16 @@ static void ieee80211_rx_bss_info(struct net_device *dev, struct sta_info *sta; struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); u64 timestamp; + DECLARE_MAC_BUF(mac); + DECLARE_MAC_BUF(mac2); if (!beacon && memcmp(mgmt->da, dev->dev_addr, ETH_ALEN)) return; /* ignore ProbeResp to foreign address */ #if 0 - printk(KERN_DEBUG "%s: RX %s from " MAC_FMT " to " MAC_FMT "\n", + printk(KERN_DEBUG "%s: RX %s from %s to %s\n", dev->name, beacon ? "Beacon" : "Probe Response", - MAC_ARG(mgmt->sa), MAC_ARG(mgmt->da)); + print_mac(mac, mgmt->sa), print_mac(mac2, mgmt->da)); #endif baselen = (u8 *) mgmt->u.beacon.variable - (u8 *) mgmt; @@ -1461,10 +1473,10 @@ static void ieee80211_rx_bss_info(struct net_device *dev, else tsf = -1LLU; if (time_after(jiffies, last_tsf_debug + 5 * HZ)) { - printk(KERN_DEBUG "RX beacon SA=" MAC_FMT " BSSID=" - MAC_FMT " TSF=0x%llx BCN=0x%llx diff=%lld " + printk(KERN_DEBUG "RX beacon SA=%s BSSID=" + "%s TSF=0x%llx BCN=0x%llx diff=%lld " "@%lu\n", - MAC_ARG(mgmt->sa), MAC_ARG(mgmt->bssid), + print_mac(mac, mgmt->sa), print_mac(mac2, mgmt->bssid), (unsigned long long)tsf, (unsigned long long)timestamp, (unsigned long long)(tsf - timestamp), @@ -1518,9 +1530,9 @@ static void ieee80211_rx_bss_info(struct net_device *dev, } if (sta->supp_rates != prev_rates) { printk(KERN_DEBUG "%s: updated supp_rates set for " - MAC_FMT " based on beacon info (0x%x & 0x%x -> " + "%s based on beacon info (0x%x & 0x%x -> " "0x%x)\n", - dev->name, MAC_ARG(sta->addr), prev_rates, + dev->name, print_mac(mac, sta->addr), prev_rates, supp_rates, sta->supp_rates); } sta_info_put(sta); @@ -1722,6 +1734,11 @@ static void ieee80211_rx_mgmt_probe_req(struct net_device *dev, struct sk_buff *skb; struct ieee80211_mgmt *resp; u8 *pos, *end; + DECLARE_MAC_BUF(mac); +#ifdef CONFIG_MAC80211_IBSS_DEBUG + DECLARE_MAC_BUF(mac2); + DECLARE_MAC_BUF(mac3); +#endif if (sdata->type != IEEE80211_IF_TYPE_IBSS || ifsta->state != IEEE80211_IBSS_JOINED || @@ -1734,10 +1751,10 @@ static void ieee80211_rx_mgmt_probe_req(struct net_device *dev, tx_last_beacon = 1; #ifdef CONFIG_MAC80211_IBSS_DEBUG - printk(KERN_DEBUG "%s: RX ProbeReq SA=" MAC_FMT " DA=" MAC_FMT " BSSID=" - MAC_FMT " (tx_last_beacon=%d)\n", - dev->name, MAC_ARG(mgmt->sa), MAC_ARG(mgmt->da), - MAC_ARG(mgmt->bssid), tx_last_beacon); + printk(KERN_DEBUG "%s: RX ProbeReq SA=%s DA=%s BSSID=" + "%s (tx_last_beacon=%d)\n", + dev->name, print_mac(mac, mgmt->sa), print_mac(mac2, mgmt->da), + print_mac(mac3, mgmt->bssid), tx_last_beacon); #endif /* CONFIG_MAC80211_IBSS_DEBUG */ if (!tx_last_beacon) @@ -1753,8 +1770,8 @@ static void ieee80211_rx_mgmt_probe_req(struct net_device *dev, pos + 2 + pos[1] > end) { if (net_ratelimit()) { printk(KERN_DEBUG "%s: Invalid SSID IE in ProbeReq " - "from " MAC_FMT "\n", - dev->name, MAC_ARG(mgmt->sa)); + "from %s\n", + dev->name, print_mac(mac, mgmt->sa)); } return; } @@ -1773,8 +1790,8 @@ static void ieee80211_rx_mgmt_probe_req(struct net_device *dev, resp = (struct ieee80211_mgmt *) skb->data; memcpy(resp->da, mgmt->sa, ETH_ALEN); #ifdef CONFIG_MAC80211_IBSS_DEBUG - printk(KERN_DEBUG "%s: Sending ProbeResp to " MAC_FMT "\n", - dev->name, MAC_ARG(resp->da)); + printk(KERN_DEBUG "%s: Sending ProbeResp to %s\n", + dev->name, print_mac(mac, resp->da)); #endif /* CONFIG_MAC80211_IBSS_DEBUG */ ieee80211_sta_tx(dev, skb, 0); } @@ -1925,13 +1942,14 @@ static void ieee80211_sta_expire(struct net_device *dev) struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); struct sta_info *sta, *tmp; LIST_HEAD(tmp_list); + DECLARE_MAC_BUF(mac); write_lock_bh(&local->sta_lock); list_for_each_entry_safe(sta, tmp, &local->sta_list, list) if (time_after(jiffies, sta->last_rx + IEEE80211_IBSS_INACTIVITY_LIMIT)) { - printk(KERN_DEBUG "%s: expiring inactive STA " MAC_FMT - "\n", dev->name, MAC_ARG(sta->addr)); + printk(KERN_DEBUG "%s: expiring inactive STA %s\n", + dev->name, print_mac(mac, sta->addr)); __sta_info_get(sta); sta_info_remove(sta); list_add(&sta->list, &tmp_list); @@ -2362,6 +2380,7 @@ static int ieee80211_sta_create_ibss(struct net_device *dev, struct ieee80211_hw_mode *mode; u8 bssid[ETH_ALEN], *pos; int i; + DECLARE_MAC_BUF(mac); #if 0 /* Easier testing, use fixed BSSID. */ @@ -2377,8 +2396,8 @@ static int ieee80211_sta_create_ibss(struct net_device *dev, bssid[0] |= 0x02; #endif - printk(KERN_DEBUG "%s: Creating new IBSS network, BSSID " MAC_FMT "\n", - dev->name, MAC_ARG(bssid)); + printk(KERN_DEBUG "%s: Creating new IBSS network, BSSID %s\n", + dev->name, print_mac(mac, bssid)); bss = ieee80211_rx_bss_add(dev, bssid); if (!bss) @@ -2418,6 +2437,8 @@ static int ieee80211_sta_find_ibss(struct net_device *dev, int found = 0; u8 bssid[ETH_ALEN]; int active_ibss; + DECLARE_MAC_BUF(mac); + DECLARE_MAC_BUF(mac2); if (ifsta->ssid_len == 0) return -EINVAL; @@ -2434,8 +2455,8 @@ static int ieee80211_sta_find_ibss(struct net_device *dev, || !(bss->capability & WLAN_CAPABILITY_IBSS)) continue; #ifdef CONFIG_MAC80211_IBSS_DEBUG - printk(KERN_DEBUG " bssid=" MAC_FMT " found\n", - MAC_ARG(bss->bssid)); + printk(KERN_DEBUG " bssid=%s found\n", + print_mac(mac, bss->bssid)); #endif /* CONFIG_MAC80211_IBSS_DEBUG */ memcpy(bssid, bss->bssid, ETH_ALEN); found = 1; @@ -2445,14 +2466,14 @@ static int ieee80211_sta_find_ibss(struct net_device *dev, spin_unlock_bh(&local->sta_bss_lock); #ifdef CONFIG_MAC80211_IBSS_DEBUG - printk(KERN_DEBUG " sta_find_ibss: selected " MAC_FMT " current " - MAC_FMT "\n", MAC_ARG(bssid), MAC_ARG(ifsta->bssid)); + printk(KERN_DEBUG " sta_find_ibss: selected %s current " + "%s\n", print_mac(mac, bssid), print_mac(mac2, ifsta->bssid)); #endif /* CONFIG_MAC80211_IBSS_DEBUG */ if (found && memcmp(ifsta->bssid, bssid, ETH_ALEN) != 0 && (bss = ieee80211_rx_bss_get(dev, bssid))) { - printk(KERN_DEBUG "%s: Selected IBSS BSSID " MAC_FMT + printk(KERN_DEBUG "%s: Selected IBSS BSSID %s" " based on configured SSID\n", - dev->name, MAC_ARG(bssid)); + dev->name, print_mac(mac, bssid)); return ieee80211_sta_join_ibss(dev, ifsta, bss); } #ifdef CONFIG_MAC80211_IBSS_DEBUG @@ -3070,19 +3091,20 @@ struct sta_info * ieee80211_ibss_add_sta(struct net_device *dev, struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); struct sta_info *sta; struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); + DECLARE_MAC_BUF(mac); /* TODO: Could consider removing the least recently used entry and * allow new one to be added. */ if (local->num_sta >= IEEE80211_IBSS_MAX_STA_ENTRIES) { if (net_ratelimit()) { printk(KERN_DEBUG "%s: No room for a new IBSS STA " - "entry " MAC_FMT "\n", dev->name, MAC_ARG(addr)); + "entry %s\n", dev->name, print_mac(mac, addr)); } return NULL; } - printk(KERN_DEBUG "%s: Adding new IBSS station " MAC_FMT " (dev=%s)\n", - local->mdev->name, MAC_ARG(addr), dev->name); + printk(KERN_DEBUG "%s: Adding new IBSS station %s (dev=%s)\n", + local->mdev->name, print_mac(mac, addr), dev->name); sta = sta_info_add(local, dev, addr, GFP_ATOMIC); if (!sta) diff --git a/net/mac80211/key.c b/net/mac80211/key.c index dd6fc4aa3ff5..c10e53afbb4f 100644 --- a/net/mac80211/key.c +++ b/net/mac80211/key.c @@ -63,6 +63,7 @@ static void ieee80211_key_enable_hw_accel(struct ieee80211_key *key) { const u8 *addr; int ret; + DECLARE_MAC_BUF(mac); if (!key->local->ops->set_key) return; @@ -78,15 +79,16 @@ static void ieee80211_key_enable_hw_accel(struct ieee80211_key *key) if (ret && ret != -ENOSPC && ret != -EOPNOTSUPP) printk(KERN_ERR "mac80211-%s: failed to set key " - "(%d, " MAC_FMT ") to hardware (%d)\n", + "(%d, %s) to hardware (%d)\n", wiphy_name(key->local->hw.wiphy), - key->conf.keyidx, MAC_ARG(addr), ret); + key->conf.keyidx, print_mac(mac, addr), ret); } static void ieee80211_key_disable_hw_accel(struct ieee80211_key *key) { const u8 *addr; int ret; + DECLARE_MAC_BUF(mac); if (!key->local->ops->set_key) return; @@ -102,9 +104,9 @@ static void ieee80211_key_disable_hw_accel(struct ieee80211_key *key) if (ret) printk(KERN_ERR "mac80211-%s: failed to remove key " - "(%d, " MAC_FMT ") from hardware (%d)\n", + "(%d, %s) from hardware (%d)\n", wiphy_name(key->local->hw.wiphy), - key->conf.keyidx, MAC_ARG(addr), ret); + key->conf.keyidx, print_mac(mac, addr), ret); key->flags &= ~KEY_FLAG_UPLOADED_TO_HARDWARE; } diff --git a/net/mac80211/rc80211_simple.c b/net/mac80211/rc80211_simple.c index ef91ce428aca..314b8de88862 100644 --- a/net/mac80211/rc80211_simple.c +++ b/net/mac80211/rc80211_simple.c @@ -201,9 +201,10 @@ static void rate_control_simple_tx_status(void *priv, struct net_device *dev, srctrl->avg_rate_update = jiffies; if (srctrl->tx_avg_rate_num > 0) { #ifdef CONFIG_MAC80211_VERBOSE_DEBUG - printk(KERN_DEBUG "%s: STA " MAC_FMT " Average rate: " + DECLARE_MAC_BUF(mac); + printk(KERN_DEBUG "%s: STA %s Average rate: " "%d (%d/%d)\n", - dev->name, MAC_ARG(sta->addr), + dev->name, print_mac(mac, sta->addr), srctrl->tx_avg_rate_sum / srctrl->tx_avg_rate_num, srctrl->tx_avg_rate_sum, diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index c985c7a537db..e9dcc6229c3c 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@ -403,6 +403,8 @@ ieee80211_rx_h_load_key(struct ieee80211_txrx_data *rx) static void ap_sta_ps_start(struct net_device *dev, struct sta_info *sta) { struct ieee80211_sub_if_data *sdata; + DECLARE_MAC_BUF(mac); + sdata = IEEE80211_DEV_TO_SUB_IF(sta->dev); if (sdata->bss) @@ -410,8 +412,8 @@ static void ap_sta_ps_start(struct net_device *dev, struct sta_info *sta) sta->flags |= WLAN_STA_PS; sta->pspoll = 0; #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG - printk(KERN_DEBUG "%s: STA " MAC_FMT " aid %d enters power " - "save mode\n", dev->name, MAC_ARG(sta->addr), sta->aid); + printk(KERN_DEBUG "%s: STA %s aid %d enters power save mode\n", + dev->name, print_mac(mac, sta->addr), sta->aid); #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ } @@ -422,6 +424,7 @@ static int ap_sta_ps_end(struct net_device *dev, struct sta_info *sta) int sent = 0; struct ieee80211_sub_if_data *sdata; struct ieee80211_tx_packet_data *pkt_data; + DECLARE_MAC_BUF(mac); sdata = IEEE80211_DEV_TO_SUB_IF(sta->dev); if (sdata->bss) @@ -435,8 +438,8 @@ static int ap_sta_ps_end(struct net_device *dev, struct sta_info *sta) bss_tim_clear(local, sdata->bss, sta->aid); } #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG - printk(KERN_DEBUG "%s: STA " MAC_FMT " aid %d exits power " - "save mode\n", dev->name, MAC_ARG(sta->addr), sta->aid); + printk(KERN_DEBUG "%s: STA %s aid %d exits power save mode\n", + dev->name, print_mac(mac, sta->addr), sta->aid); #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ /* Send all buffered frames to the station */ while ((skb = skb_dequeue(&sta->tx_filtered)) != NULL) { @@ -450,9 +453,9 @@ static int ap_sta_ps_end(struct net_device *dev, struct sta_info *sta) local->total_ps_buffered--; sent++; #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG - printk(KERN_DEBUG "%s: STA " MAC_FMT " aid %d send PS frame " + printk(KERN_DEBUG "%s: STA %s aid %d send PS frame " "since STA not sleeping anymore\n", dev->name, - MAC_ARG(sta->addr), sta->aid); + print_mac(mac, sta->addr), sta->aid); #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ pkt_data->flags |= IEEE80211_TXPD_REQUEUE; dev_queue_xmit(skb); @@ -590,13 +593,15 @@ ieee80211_reassemble_add(struct ieee80211_sub_if_data *sdata, #ifdef CONFIG_MAC80211_DEBUG struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) entry->skb_list.next->data; + DECLARE_MAC_BUF(mac); + DECLARE_MAC_BUF(mac2); printk(KERN_DEBUG "%s: RX reassembly removed oldest " "fragment entry (idx=%d age=%lu seq=%d last_frag=%d " - "addr1=" MAC_FMT " addr2=" MAC_FMT "\n", + "addr1=%s addr2=%s\n", sdata->dev->name, idx, jiffies - entry->first_frag_time, entry->seq, - entry->last_frag, MAC_ARG(hdr->addr1), - MAC_ARG(hdr->addr2)); + entry->last_frag, print_mac(mac, hdr->addr1), + print_mac(mac2, hdr->addr2)); #endif /* CONFIG_MAC80211_DEBUG */ __skb_queue_purge(&entry->skb_list); } @@ -662,6 +667,7 @@ ieee80211_rx_h_defragment(struct ieee80211_txrx_data *rx) unsigned int frag, seq; struct ieee80211_fragment_entry *entry; struct sk_buff *skb; + DECLARE_MAC_BUF(mac); hdr = (struct ieee80211_hdr *) rx->skb->data; sc = le16_to_cpu(hdr->seq_ctrl); @@ -720,10 +726,10 @@ ieee80211_rx_h_defragment(struct ieee80211_txrx_data *rx) if (memcmp(pn, rpn, CCMP_PN_LEN) != 0) { if (net_ratelimit()) printk(KERN_DEBUG "%s: defrag: CCMP PN not " - "sequential A2=" MAC_FMT + "sequential A2=%s" " PN=%02x%02x%02x%02x%02x%02x " "(expected %02x%02x%02x%02x%02x%02x)\n", - rx->dev->name, MAC_ARG(hdr->addr2), + rx->dev->name, print_mac(mac, hdr->addr2), rpn[0], rpn[1], rpn[2], rpn[3], rpn[4], rpn[5], pn[0], pn[1], pn[2], pn[3], pn[4], pn[5]); @@ -774,6 +780,7 @@ ieee80211_rx_h_ps_poll(struct ieee80211_txrx_data *rx) { struct sk_buff *skb; int no_pending_pkts; + DECLARE_MAC_BUF(mac); if (likely(!rx->sta || (rx->fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_CTL || @@ -799,9 +806,8 @@ ieee80211_rx_h_ps_poll(struct ieee80211_txrx_data *rx) rx->sta->pspoll = 1; #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG - printk(KERN_DEBUG "STA " MAC_FMT " aid %d: PS Poll (entries " - "after %d)\n", - MAC_ARG(rx->sta->addr), rx->sta->aid, + printk(KERN_DEBUG "STA %s aid %d: PS Poll (entries after %d)\n", + print_mac(mac, rx->sta->addr), rx->sta->aid, skb_queue_len(&rx->sta->ps_tx_buf)); #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ @@ -824,9 +830,9 @@ ieee80211_rx_h_ps_poll(struct ieee80211_txrx_data *rx) } #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG } else if (!rx->u.rx.sent_ps_buffered) { - printk(KERN_DEBUG "%s: STA " MAC_FMT " sent PS Poll even " + printk(KERN_DEBUG "%s: STA %s sent PS Poll even " "though there is no buffered frames for it\n", - rx->dev->name, MAC_ARG(rx->sta->addr)); + rx->dev->name, print_mac(mac, rx->sta->addr)); #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ } @@ -881,9 +887,10 @@ ieee80211_rx_h_802_1x_pae(struct ieee80211_txrx_data *rx) #ifdef CONFIG_MAC80211_DEBUG struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) rx->skb->data; - printk(KERN_DEBUG "%s: dropped frame from " MAC_FMT + DECLARE_MAC_BUF(mac); + printk(KERN_DEBUG "%s: dropped frame from %s" " (unauthorized port)\n", rx->dev->name, - MAC_ARG(hdr->addr2)); + print_mac(mac, hdr->addr2)); #endif /* CONFIG_MAC80211_DEBUG */ return TXRX_DROP; } @@ -928,6 +935,10 @@ ieee80211_rx_h_data(struct ieee80211_txrx_data *rx) u8 src[ETH_ALEN]; struct sk_buff *skb = rx->skb, *skb2; struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); + DECLARE_MAC_BUF(mac); + DECLARE_MAC_BUF(mac2); + DECLARE_MAC_BUF(mac3); + DECLARE_MAC_BUF(mac4); fc = rx->fc; if (unlikely((fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA)) @@ -958,13 +969,11 @@ ieee80211_rx_h_data(struct ieee80211_txrx_data *rx) sdata->type != IEEE80211_IF_TYPE_VLAN)) { if (net_ratelimit()) printk(KERN_DEBUG "%s: dropped ToDS frame " - "(BSSID=" MAC_FMT - " SA=" MAC_FMT - " DA=" MAC_FMT ")\n", + "(BSSID=%s SA=%s DA=%s)\n", dev->name, - MAC_ARG(hdr->addr1), - MAC_ARG(hdr->addr2), - MAC_ARG(hdr->addr3)); + print_mac(mac, hdr->addr1), + print_mac(mac2, hdr->addr2), + print_mac(mac3, hdr->addr3)); return TXRX_DROP; } break; @@ -976,14 +985,12 @@ ieee80211_rx_h_data(struct ieee80211_txrx_data *rx) if (unlikely(sdata->type != IEEE80211_IF_TYPE_WDS)) { if (net_ratelimit()) printk(KERN_DEBUG "%s: dropped FromDS&ToDS " - "frame (RA=" MAC_FMT - " TA=" MAC_FMT " DA=" MAC_FMT - " SA=" MAC_FMT ")\n", + "frame (RA=%s TA=%s DA=%s SA=%s)\n", rx->dev->name, - MAC_ARG(hdr->addr1), - MAC_ARG(hdr->addr2), - MAC_ARG(hdr->addr3), - MAC_ARG(hdr->addr4)); + print_mac(mac, hdr->addr1), + print_mac(mac2, hdr->addr2), + print_mac(mac3, hdr->addr3), + print_mac(mac4, hdr->addr4)); return TXRX_DROP; } break; @@ -1004,12 +1011,12 @@ ieee80211_rx_h_data(struct ieee80211_txrx_data *rx) if (sdata->type != IEEE80211_IF_TYPE_IBSS) { if (net_ratelimit()) { - printk(KERN_DEBUG "%s: dropped IBSS frame (DA=" - MAC_FMT " SA=" MAC_FMT " BSSID=" MAC_FMT - ")\n", - dev->name, MAC_ARG(hdr->addr1), - MAC_ARG(hdr->addr2), - MAC_ARG(hdr->addr3)); + printk(KERN_DEBUG "%s: dropped IBSS frame " + "(DA=%s SA=%s BSSID=%s)\n", + dev->name, + print_mac(mac, hdr->addr1), + print_mac(mac2, hdr->addr2), + print_mac(mac3, hdr->addr3)); } return TXRX_DROP; } @@ -1172,6 +1179,8 @@ static void ieee80211_rx_michael_mic_report(struct net_device *dev, struct ieee80211_txrx_data *rx) { int keyidx, hdrlen; + DECLARE_MAC_BUF(mac); + DECLARE_MAC_BUF(mac2); hdrlen = ieee80211_get_hdrlen_from_skb(rx->skb); if (rx->skb->len >= hdrlen + 4) @@ -1181,9 +1190,9 @@ static void ieee80211_rx_michael_mic_report(struct net_device *dev, if (net_ratelimit()) printk(KERN_DEBUG "%s: TKIP hwaccel reported Michael MIC " - "failure from " MAC_FMT " to " MAC_FMT " keyidx=%d\n", - dev->name, MAC_ARG(hdr->addr2), MAC_ARG(hdr->addr1), - keyidx); + "failure from %s to %s keyidx=%d\n", + dev->name, print_mac(mac, hdr->addr2), + print_mac(mac2, hdr->addr1), keyidx); if (!sta) { /* @@ -1192,8 +1201,8 @@ static void ieee80211_rx_michael_mic_report(struct net_device *dev, */ if (net_ratelimit()) printk(KERN_DEBUG "%s: ignored spurious Michael MIC " - "error for unknown address " MAC_FMT "\n", - dev->name, MAC_ARG(hdr->addr2)); + "error for unknown address %s\n", + dev->name, print_mac(mac, hdr->addr2)); goto ignore; } @@ -1201,7 +1210,7 @@ static void ieee80211_rx_michael_mic_report(struct net_device *dev, if (net_ratelimit()) printk(KERN_DEBUG "%s: ignored spurious Michael MIC " "error for a frame with no PROTECTED flag (src " - MAC_FMT ")\n", dev->name, MAC_ARG(hdr->addr2)); + "%s)\n", dev->name, print_mac(mac, hdr->addr2)); goto ignore; } @@ -1215,8 +1224,8 @@ static void ieee80211_rx_michael_mic_report(struct net_device *dev, if (net_ratelimit()) printk(KERN_DEBUG "%s: ignored Michael MIC error for " "a frame with non-zero keyidx (%d)" - " (src " MAC_FMT ")\n", dev->name, keyidx, - MAC_ARG(hdr->addr2)); + " (src %s)\n", dev->name, keyidx, + print_mac(mac, hdr->addr2)); goto ignore; } @@ -1226,8 +1235,8 @@ static void ieee80211_rx_michael_mic_report(struct net_device *dev, if (net_ratelimit()) printk(KERN_DEBUG "%s: ignored spurious Michael MIC " "error for a frame that cannot be encrypted " - "(fc=0x%04x) (src " MAC_FMT ")\n", - dev->name, rx->fc, MAC_ARG(hdr->addr2)); + "(fc=0x%04x) (src %s)\n", + dev->name, rx->fc, print_mac(mac, hdr->addr2)); goto ignore; } diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index c17172abb21c..44d983404952 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c @@ -132,6 +132,7 @@ struct sta_info * sta_info_add(struct ieee80211_local *local, struct net_device *dev, u8 *addr, gfp_t gfp) { struct sta_info *sta; + DECLARE_MAC_BUF(mac); sta = kzalloc(sizeof(*sta), gfp); if (!sta) @@ -164,8 +165,8 @@ struct sta_info * sta_info_add(struct ieee80211_local *local, write_unlock_bh(&local->sta_lock); #ifdef CONFIG_MAC80211_VERBOSE_DEBUG - printk(KERN_DEBUG "%s: Added STA " MAC_FMT "\n", - local->mdev->name, MAC_ARG(addr)); + printk(KERN_DEBUG "%s: Added STA %s\n", + local->mdev->name, print_mac(mac, addr)); #endif /* CONFIG_MAC80211_VERBOSE_DEBUG */ #ifdef CONFIG_MAC80211_DEBUGFS @@ -207,6 +208,7 @@ void sta_info_free(struct sta_info *sta) { struct sk_buff *skb; struct ieee80211_local *local = sta->local; + DECLARE_MAC_BUF(mac); might_sleep(); @@ -223,8 +225,8 @@ void sta_info_free(struct sta_info *sta) } #ifdef CONFIG_MAC80211_VERBOSE_DEBUG - printk(KERN_DEBUG "%s: Removed STA " MAC_FMT "\n", - local->mdev->name, MAC_ARG(sta->addr)); + printk(KERN_DEBUG "%s: Removed STA %s\n", + local->mdev->name, print_mac(mac, sta->addr)); #endif /* CONFIG_MAC80211_VERBOSE_DEBUG */ ieee80211_key_free(sta->key); @@ -263,6 +265,7 @@ static void sta_info_cleanup_expire_buffered(struct ieee80211_local *local, { unsigned long flags; struct sk_buff *skb; + DECLARE_MAC_BUF(mac); if (skb_queue_empty(&sta->ps_tx_buf)) return; @@ -281,7 +284,7 @@ static void sta_info_cleanup_expire_buffered(struct ieee80211_local *local, if (skb) { local->total_ps_buffered--; printk(KERN_DEBUG "Buffered frame expired (STA " - MAC_FMT ")\n", MAC_ARG(sta->addr)); + "%s)\n", print_mac(mac, sta->addr)); dev_kfree_skb(skb); } else break; diff --git a/net/mac80211/tkip.c b/net/mac80211/tkip.c index b9c1d5405180..5b11f14abfba 100644 --- a/net/mac80211/tkip.c +++ b/net/mac80211/tkip.c @@ -275,9 +275,10 @@ int ieee80211_tkip_decrypt_data(struct crypto_blkcipher *tfm, (iv32 == key->u.tkip.iv32_rx[queue] && iv16 <= key->u.tkip.iv16_rx[queue]))) { #ifdef CONFIG_TKIP_DEBUG + DECLARE_MAC_BUF(mac); printk(KERN_DEBUG "TKIP replay detected for RX frame from " - MAC_FMT " (RX IV (%04x,%02x) <= prev. IV (%04x,%02x)\n", - MAC_ARG(ta), + "%s (RX IV (%04x,%02x) <= prev. IV (%04x,%02x)\n", + print_mac(mac, ta), iv32, iv16, key->u.tkip.iv32_rx[queue], key->u.tkip.iv16_rx[queue]); #endif /* CONFIG_TKIP_DEBUG */ @@ -299,8 +300,9 @@ int ieee80211_tkip_decrypt_data(struct crypto_blkcipher *tfm, #ifdef CONFIG_TKIP_DEBUG { int i; - printk(KERN_DEBUG "TKIP decrypt: Phase1 TA=" MAC_FMT - " TK=", MAC_ARG(ta)); + DECLARE_MAC_BUF(mac); + printk(KERN_DEBUG "TKIP decrypt: Phase1 TA=%s" + " TK=", print_mac(mac, ta)); for (i = 0; i < 16; i++) printk("%02x ", key->conf.key[ diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index ca262a99e56f..04b4fa9c69ea 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c @@ -54,6 +54,7 @@ static void ieee80211_dump_frame(const char *ifname, const char *title, const struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; u16 fc; int hdrlen; + DECLARE_MAC_BUF(mac); printk(KERN_DEBUG "%s: %s (len=%d)", ifname, title, skb->len); if (skb->len < 4) { @@ -69,13 +70,13 @@ static void ieee80211_dump_frame(const char *ifname, const char *title, printk(" FC=0x%04x DUR=0x%04x", fc, le16_to_cpu(hdr->duration_id)); if (hdrlen >= 10) - printk(" A1=" MAC_FMT, MAC_ARG(hdr->addr1)); + printk(" A1=%s", print_mac(mac, hdr->addr1)); if (hdrlen >= 16) - printk(" A2=" MAC_FMT, MAC_ARG(hdr->addr2)); + printk(" A2=%s", print_mac(mac, hdr->addr2)); if (hdrlen >= 24) - printk(" A3=" MAC_FMT, MAC_ARG(hdr->addr3)); + printk(" A3=%s", print_mac(mac, hdr->addr3)); if (hdrlen >= 30) - printk(" A4=" MAC_FMT, MAC_ARG(hdr->addr4)); + printk(" A4=%s", print_mac(mac, hdr->addr4)); printk("\n"); } #else /* CONFIG_MAC80211_LOWTX_FRAME_DUMP */ @@ -236,9 +237,10 @@ ieee80211_tx_h_check_assoc(struct ieee80211_txrx_data *tx) tx->sdata->type != IEEE80211_IF_TYPE_IBSS && (tx->fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA)) { #ifdef CONFIG_MAC80211_VERBOSE_DEBUG + DECLARE_MAC_BUF(mac); printk(KERN_DEBUG "%s: dropped data frame to not " - "associated station " MAC_FMT "\n", - tx->dev->name, MAC_ARG(hdr->addr1)); + "associated station %s\n", + tx->dev->name, print_mac(mac, hdr->addr1)); #endif /* CONFIG_MAC80211_VERBOSE_DEBUG */ I802_DEBUG_INC(tx->local->tx_handlers_drop_not_assoc); return TXRX_DROP; @@ -259,9 +261,10 @@ ieee80211_tx_h_check_assoc(struct ieee80211_txrx_data *tx) if (unlikely(!tx->u.tx.mgmt_interface && tx->sdata->ieee802_1x && !(sta_flags & WLAN_STA_AUTHORIZED))) { #ifdef CONFIG_MAC80211_VERBOSE_DEBUG - printk(KERN_DEBUG "%s: dropped frame to " MAC_FMT + DECLARE_MAC_BUF(mac); + printk(KERN_DEBUG "%s: dropped frame to %s" " (unauthorized port)\n", tx->dev->name, - MAC_ARG(hdr->addr1)); + print_mac(mac, hdr->addr1)); #endif I802_DEBUG_INC(tx->local->tx_handlers_drop_unauth_port); return TXRX_DROP; @@ -357,6 +360,7 @@ static inline ieee80211_txrx_result ieee80211_tx_h_unicast_ps_buf(struct ieee80211_txrx_data *tx) { struct sta_info *sta = tx->sta; + DECLARE_MAC_BUF(mac); if (unlikely(!sta || ((tx->fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT && @@ -366,9 +370,9 @@ ieee80211_tx_h_unicast_ps_buf(struct ieee80211_txrx_data *tx) if (unlikely((sta->flags & WLAN_STA_PS) && !sta->pspoll)) { struct ieee80211_tx_packet_data *pkt_data; #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG - printk(KERN_DEBUG "STA " MAC_FMT " aid %d: PS buffer (entries " + printk(KERN_DEBUG "STA %s aid %d: PS buffer (entries " "before %d)\n", - MAC_ARG(sta->addr), sta->aid, + print_mac(mac, sta->addr), sta->aid, skb_queue_len(&sta->ps_tx_buf)); #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ sta->flags |= WLAN_STA_TIM; @@ -377,9 +381,9 @@ ieee80211_tx_h_unicast_ps_buf(struct ieee80211_txrx_data *tx) if (skb_queue_len(&sta->ps_tx_buf) >= STA_MAX_TX_BUFFER) { struct sk_buff *old = skb_dequeue(&sta->ps_tx_buf); if (net_ratelimit()) { - printk(KERN_DEBUG "%s: STA " MAC_FMT " TX " + printk(KERN_DEBUG "%s: STA %s TX " "buffer full - dropping oldest frame\n", - tx->dev->name, MAC_ARG(sta->addr)); + tx->dev->name, print_mac(mac, sta->addr)); } dev_kfree_skb(old); } else @@ -399,9 +403,9 @@ ieee80211_tx_h_unicast_ps_buf(struct ieee80211_txrx_data *tx) } #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG else if (unlikely(sta->flags & WLAN_STA_PS)) { - printk(KERN_DEBUG "%s: STA " MAC_FMT " in PS mode, but pspoll " + printk(KERN_DEBUG "%s: STA %s in PS mode, but pspoll " "set -> send frame\n", tx->dev->name, - MAC_ARG(sta->addr)); + print_mac(mac, sta->addr)); } #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ sta->pspoll = 0; diff --git a/net/mac80211/wpa.c b/net/mac80211/wpa.c index 6e12638054aa..360d11e9de15 100644 --- a/net/mac80211/wpa.c +++ b/net/mac80211/wpa.c @@ -132,6 +132,7 @@ ieee80211_rx_h_michael_mic_verify(struct ieee80211_txrx_data *rx) u8 mic[MICHAEL_MIC_LEN]; struct sk_buff *skb = rx->skb; int authenticator = 1, wpa_test = 0; + DECLARE_MAC_BUF(mac); fc = rx->fc; @@ -164,7 +165,7 @@ ieee80211_rx_h_michael_mic_verify(struct ieee80211_txrx_data *rx) return TXRX_DROP; printk(KERN_DEBUG "%s: invalid Michael MIC in data frame from " - MAC_FMT "\n", rx->dev->name, MAC_ARG(sa)); + "%s\n", rx->dev->name, print_mac(mac, sa)); mac80211_ev_michael_mic_failure(rx->dev, rx->key->conf.keyidx, (void *) skb->data); @@ -287,6 +288,7 @@ ieee80211_rx_h_tkip_decrypt(struct ieee80211_txrx_data *rx) int hdrlen, res, hwaccel = 0, wpa_test = 0; struct ieee80211_key *key = rx->key; struct sk_buff *skb = rx->skb; + DECLARE_MAC_BUF(mac); fc = le16_to_cpu(hdr->frame_control); hdrlen = ieee80211_get_hdrlen(fc); @@ -319,8 +321,8 @@ ieee80211_rx_h_tkip_decrypt(struct ieee80211_txrx_data *rx) hwaccel, rx->u.rx.queue); if (res != TKIP_DECRYPT_OK || wpa_test) { printk(KERN_DEBUG "%s: TKIP decrypt failed for RX frame from " - MAC_FMT " (res=%d)\n", - rx->dev->name, MAC_ARG(rx->sta->addr), res); + "%s (res=%d)\n", + rx->dev->name, print_mac(mac, rx->sta->addr), res); return TXRX_DROP; } @@ -542,6 +544,7 @@ ieee80211_rx_h_ccmp_decrypt(struct ieee80211_txrx_data *rx) struct sk_buff *skb = rx->skb; u8 pn[CCMP_PN_LEN]; int data_len; + DECLARE_MAC_BUF(mac); fc = le16_to_cpu(hdr->frame_control); hdrlen = ieee80211_get_hdrlen(fc); @@ -564,10 +567,11 @@ ieee80211_rx_h_ccmp_decrypt(struct ieee80211_txrx_data *rx) if (memcmp(pn, key->u.ccmp.rx_pn[rx->u.rx.queue], CCMP_PN_LEN) <= 0) { #ifdef CONFIG_MAC80211_DEBUG u8 *ppn = key->u.ccmp.rx_pn[rx->u.rx.queue]; + printk(KERN_DEBUG "%s: CCMP replay detected for RX frame from " - MAC_FMT " (RX PN %02x%02x%02x%02x%02x%02x <= prev. PN " + "%s (RX PN %02x%02x%02x%02x%02x%02x <= prev. PN " "%02x%02x%02x%02x%02x%02x)\n", rx->dev->name, - MAC_ARG(rx->sta->addr), + print_mac(mac, rx->sta->addr), pn[0], pn[1], pn[2], pn[3], pn[4], pn[5], ppn[0], ppn[1], ppn[2], ppn[3], ppn[4], ppn[5]); #endif /* CONFIG_MAC80211_DEBUG */ @@ -591,8 +595,8 @@ ieee80211_rx_h_ccmp_decrypt(struct ieee80211_txrx_data *rx) skb->data + skb->len - CCMP_MIC_LEN, skb->data + hdrlen + CCMP_HDR_LEN)) { printk(KERN_DEBUG "%s: CCMP decrypt failed for RX " - "frame from " MAC_FMT "\n", rx->dev->name, - MAC_ARG(rx->sta->addr)); + "frame from %s\n", rx->dev->name, + print_mac(mac, rx->sta->addr)); return TXRX_DROP; } } @@ -606,4 +610,3 @@ ieee80211_rx_h_ccmp_decrypt(struct ieee80211_txrx_data *rx) return TXRX_CONTINUE; } - diff --git a/net/tipc/eth_media.c b/net/tipc/eth_media.c index d6fc0575816b..1a99e2947145 100644 --- a/net/tipc/eth_media.c +++ b/net/tipc/eth_media.c @@ -243,12 +243,12 @@ static int recv_notification(struct notifier_block *nb, unsigned long evt, static char *eth_addr2str(struct tipc_media_addr *a, char *str_buf, int str_size) { unchar *addr = (unchar *)&a->dev_addr; + DECLARE_MAC_BUF(mac); if (str_size < 18) *str_buf = '\0'; else - sprintf(str_buf, "%02x:%02x:%02x:%02x:%02x:%02x", - addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]); + sprintf(str_buf, "%s", print_mac(mac, addr)); return str_buf; } -- cgit v1.2.3 From 701181ac1d9ac465a3614061cb60ded4033c4d07 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Wed, 22 Aug 2007 22:59:11 -0400 Subject: arcnet endianness annotations Signed-off-by: Al Viro Signed-off-by: Jeff Garzik --- drivers/net/arcnet/rfc1051.c | 4 ++-- drivers/net/arcnet/rfc1201.c | 6 +++--- include/linux/arcdevice.h | 4 ++-- include/linux/if_arcnet.h | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) (limited to 'include/linux') diff --git a/drivers/net/arcnet/rfc1051.c b/drivers/net/arcnet/rfc1051.c index 2de8877ece29..dab185bc51f1 100644 --- a/drivers/net/arcnet/rfc1051.c +++ b/drivers/net/arcnet/rfc1051.c @@ -34,7 +34,7 @@ #define VERSION "arcnet: RFC1051 \"simple standard\" (`s') encapsulation support loaded.\n" -static unsigned short type_trans(struct sk_buff *skb, struct net_device *dev); +static __be16 type_trans(struct sk_buff *skb, struct net_device *dev); static void rx(struct net_device *dev, int bufnum, struct archdr *pkthdr, int length); static int build_header(struct sk_buff *skb, struct net_device *dev, @@ -86,7 +86,7 @@ MODULE_LICENSE("GPL"); * * With ARCnet we have to convert everything to Ethernet-style stuff. */ -static unsigned short type_trans(struct sk_buff *skb, struct net_device *dev) +static __be16 type_trans(struct sk_buff *skb, struct net_device *dev) { struct arcnet_local *lp = dev->priv; struct archdr *pkt = (struct archdr *) skb->data; diff --git a/drivers/net/arcnet/rfc1201.c b/drivers/net/arcnet/rfc1201.c index 460a095000c2..6d6d95cc4404 100644 --- a/drivers/net/arcnet/rfc1201.c +++ b/drivers/net/arcnet/rfc1201.c @@ -34,7 +34,7 @@ MODULE_LICENSE("GPL"); #define VERSION "arcnet: RFC1201 \"standard\" (`a') encapsulation support loaded.\n" -static unsigned short type_trans(struct sk_buff *skb, struct net_device *dev); +static __be16 type_trans(struct sk_buff *skb, struct net_device *dev); static void rx(struct net_device *dev, int bufnum, struct archdr *pkthdr, int length); static int build_header(struct sk_buff *skb, struct net_device *dev, @@ -88,7 +88,7 @@ module_exit(arcnet_rfc1201_exit); * * With ARCnet we have to convert everything to Ethernet-style stuff. */ -static unsigned short type_trans(struct sk_buff *skb, struct net_device *dev) +static __be16 type_trans(struct sk_buff *skb, struct net_device *dev) { struct archdr *pkt = (struct archdr *) skb->data; struct arc_rfc1201 *soft = &pkt->soft.rfc1201; @@ -456,7 +456,7 @@ static void load_pkt(struct net_device *dev, struct arc_hardware *hard, excsoft.proto = soft->proto; excsoft.split_flag = 0xff; - excsoft.sequence = 0xffff; + excsoft.sequence = htons(0xffff); hard->offset[0] = 0; ofs = 512 - softlen; diff --git a/include/linux/arcdevice.h b/include/linux/arcdevice.h index 2f85049cfb3d..fde675872c56 100644 --- a/include/linux/arcdevice.h +++ b/include/linux/arcdevice.h @@ -214,7 +214,7 @@ extern struct ArcProto *arc_proto_map[256], *arc_proto_default, */ struct Incoming { struct sk_buff *skb; /* packet data buffer */ - uint16_t sequence; /* sequence number of assembly */ + __be16 sequence; /* sequence number of assembly */ uint8_t lastpacket, /* number of last packet (from 1) */ numpackets; /* number of packets in split */ }; @@ -292,7 +292,7 @@ struct arcnet_local { struct { uint16_t sequence; /* sequence number (incs with each packet) */ - uint16_t aborted_seq; + __be16 aborted_seq; struct Incoming incoming[256]; /* one from each address */ } rfc1201; diff --git a/include/linux/if_arcnet.h b/include/linux/if_arcnet.h index af380cb876a0..27ea2ac445ad 100644 --- a/include/linux/if_arcnet.h +++ b/include/linux/if_arcnet.h @@ -59,7 +59,7 @@ struct arc_rfc1201 { uint8_t proto; /* protocol ID field - varies */ uint8_t split_flag; /* for use with split packets */ - uint16_t sequence; /* sequence number */ + __be16 sequence; /* sequence number */ uint8_t payload[0]; /* space remaining in packet (504 bytes)*/ }; #define RFC1201_HDR_SIZE 4 -- cgit v1.2.3 From b963dc1df78399a2166c2e6e3eb726a2dc98cf11 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 23 Aug 2007 02:55:33 -0400 Subject: pppoe: endianness Signed-off-by: Al Viro Signed-off-by: Jeff Garzik --- drivers/net/pppoe.c | 18 +++++++++--------- include/linux/if_pppox.h | 12 ++++++------ 2 files changed, 15 insertions(+), 15 deletions(-) (limited to 'include/linux') diff --git a/drivers/net/pppoe.c b/drivers/net/pppoe.c index ba2eb04aac9f..d48b7b73d896 100644 --- a/drivers/net/pppoe.c +++ b/drivers/net/pppoe.c @@ -103,7 +103,7 @@ static inline int cmp_2_addr(struct pppoe_addr *a, struct pppoe_addr *b) (memcmp(a->remote, b->remote, ETH_ALEN) == 0)); } -static inline int cmp_addr(struct pppoe_addr *a, unsigned long sid, char *addr) +static inline int cmp_addr(struct pppoe_addr *a, __be16 sid, char *addr) { return (a->sid == sid && (memcmp(a->remote,addr,ETH_ALEN) == 0)); @@ -113,7 +113,7 @@ static inline int cmp_addr(struct pppoe_addr *a, unsigned long sid, char *addr) #error 8 must be a multiple of PPPOE_HASH_BITS #endif -static int hash_item(unsigned int sid, unsigned char *addr) +static int hash_item(__be16 sid, unsigned char *addr) { unsigned char hash = 0; unsigned int i; @@ -122,7 +122,7 @@ static int hash_item(unsigned int sid, unsigned char *addr) hash ^= addr[i]; } for (i = 0 ; i < sizeof(sid_t)*8 ; i += 8 ){ - hash ^= sid>>i; + hash ^= (__force __u32)sid>>i; } for (i = 8 ; (i>>=1) >= PPPOE_HASH_BITS ; ) { hash ^= hash>>i; @@ -139,7 +139,7 @@ static struct pppox_sock *item_hash_table[PPPOE_HASH_SIZE]; * Set/get/delete/rehash items (internal versions) * **********************************************************************/ -static struct pppox_sock *__get_item(unsigned long sid, unsigned char *addr, int ifindex) +static struct pppox_sock *__get_item(__be16 sid, unsigned char *addr, int ifindex) { int hash = hash_item(sid, addr); struct pppox_sock *ret; @@ -171,7 +171,7 @@ static int __set_item(struct pppox_sock *po) return 0; } -static struct pppox_sock *__delete_item(unsigned long sid, char *addr, int ifindex) +static struct pppox_sock *__delete_item(__be16 sid, char *addr, int ifindex) { int hash = hash_item(sid, addr); struct pppox_sock *ret, **src; @@ -197,7 +197,7 @@ static struct pppox_sock *__delete_item(unsigned long sid, char *addr, int ifind * Set/get/delete/rehash items * **********************************************************************/ -static inline struct pppox_sock *get_item(unsigned long sid, +static inline struct pppox_sock *get_item(__be16 sid, unsigned char *addr, int ifindex) { struct pppox_sock *po; @@ -224,7 +224,7 @@ static inline struct pppox_sock *get_item_by_addr(struct sockaddr_pppox *sp) return get_item(sp->sa_addr.pppoe.sid, sp->sa_addr.pppoe.remote, ifindex); } -static inline struct pppox_sock *delete_item(unsigned long sid, char *addr, int ifindex) +static inline struct pppox_sock *delete_item(__be16 sid, char *addr, int ifindex) { struct pppox_sock *ret; @@ -400,7 +400,7 @@ static int pppoe_rcv(struct sk_buff *skb, ph = pppoe_hdr(skb); - po = get_item((unsigned long) ph->sid, eth_hdr(skb)->h_source, dev->ifindex); + po = get_item(ph->sid, eth_hdr(skb)->h_source, dev->ifindex); if (po != NULL) return sk_receive_skb(sk_pppox(po), skb, 0); drop: @@ -437,7 +437,7 @@ static int pppoe_disc_rcv(struct sk_buff *skb, if (ph->code != PADT_CODE) goto abort; - po = get_item((unsigned long) ph->sid, eth_hdr(skb)->h_source, dev->ifindex); + po = get_item(ph->sid, eth_hdr(skb)->h_source, dev->ifindex); if (po) { struct sock *sk = sk_pppox(po); diff --git a/include/linux/if_pppox.h b/include/linux/if_pppox.h index 43cfc9f0c078..40743e032845 100644 --- a/include/linux/if_pppox.h +++ b/include/linux/if_pppox.h @@ -40,7 +40,7 @@ /************************************************************************ * PPPoE addressing definition */ -typedef __u16 sid_t; +typedef __be16 sid_t; struct pppoe_addr{ sid_t sid; /* Session identifier */ unsigned char remote[ETH_ALEN]; /* Remote address */ @@ -90,8 +90,8 @@ struct sockaddr_pppol2tp { #define PADS_CODE 0x65 #define PADT_CODE 0xa7 struct pppoe_tag { - __u16 tag_type; - __u16 tag_len; + __be16 tag_type; + __be16 tag_len; char tag_data[0]; } __attribute ((packed)); @@ -118,8 +118,8 @@ struct pppoe_hdr { #error "Please fix " #endif __u8 code; - __u16 sid; - __u16 length; + __be16 sid; + __be16 length; struct pppoe_tag tag[0]; } __attribute__ ((packed)); @@ -152,7 +152,7 @@ struct pppox_sock { union { struct pppoe_opt pppoe; } proto; - unsigned short num; + __be16 num; }; #define pppoe_dev proto.pppoe.dev #define pppoe_ifindex proto.pppoe.ifindex -- cgit v1.2.3 From 556829657397b9b05baec6691ead4e22ee8d1567 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Thu, 20 Sep 2007 13:09:35 -0400 Subject: [NL80211]: add netlink interface to cfg80211 Signed-off-by: Johannes Berg Signed-off-by: John W. Linville Signed-off-by: David S. Miller --- include/linux/nl80211.h | 97 +++++++++- include/net/cfg80211.h | 11 +- include/net/iw_handler.h | 8 +- net/mac80211/ieee80211_cfg.c | 2 +- net/wireless/Kconfig | 17 +- net/wireless/Makefile | 1 + net/wireless/core.c | 148 +++++++++++++++ net/wireless/core.h | 32 ++++ net/wireless/nl80211.c | 431 +++++++++++++++++++++++++++++++++++++++++++ net/wireless/nl80211.h | 24 +++ 10 files changed, 762 insertions(+), 9 deletions(-) create mode 100644 net/wireless/nl80211.c create mode 100644 net/wireless/nl80211.h (limited to 'include/linux') diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h index 9a30ba2ca75e..538ee1dd3d0a 100644 --- a/include/linux/nl80211.h +++ b/include/linux/nl80211.h @@ -6,8 +6,98 @@ * Copyright 2006, 2007 Johannes Berg */ +/** + * enum nl80211_commands - supported nl80211 commands + * + * @NL80211_CMD_UNSPEC: unspecified command to catch errors + * + * @NL80211_CMD_GET_WIPHY: request information about a wiphy or dump request + * to get a list of all present wiphys. + * @NL80211_CMD_SET_WIPHY: set wiphy name, needs %NL80211_ATTR_WIPHY and + * %NL80211_ATTR_WIPHY_NAME. + * @NL80211_CMD_NEW_WIPHY: Newly created wiphy, response to get request + * or rename notification. Has attributes %NL80211_ATTR_WIPHY and + * %NL80211_ATTR_WIPHY_NAME. + * @NL80211_CMD_DEL_WIPHY: Wiphy deleted. Has attributes + * %NL80211_ATTR_WIPHY and %NL80211_ATTR_WIPHY_NAME. + * + * @NL80211_CMD_GET_INTERFACE: Request an interface's configuration; + * either a dump request on a %NL80211_ATTR_WIPHY or a specific get + * on an %NL80211_ATTR_IFINDEX is supported. + * @NL80211_CMD_SET_INTERFACE: Set type of a virtual interface, requires + * %NL80211_ATTR_IFINDEX and %NL80211_ATTR_IFTYPE. + * @NL80211_CMD_NEW_INTERFACE: Newly created virtual interface or response + * to %NL80211_CMD_GET_INTERFACE. Has %NL80211_ATTR_IFINDEX, + * %NL80211_ATTR_WIPHY and %NL80211_ATTR_IFTYPE attributes. Can also + * be sent from userspace to request creation of a new virtual interface, + * then requires attributes %NL80211_ATTR_WIPHY, %NL80211_ATTR_IFTYPE and + * %NL80211_ATTR_IFNAME. + * @NL80211_CMD_DEL_INTERFACE: Virtual interface was deleted, has attributes + * %NL80211_ATTR_IFINDEX and %NL80211_ATTR_WIPHY. Can also be sent from + * userspace to request deletion of a virtual interface, then requires + * attribute %NL80211_ATTR_IFINDEX. + * + * @NL80211_CMD_MAX: highest used command number + * @__NL80211_CMD_AFTER_LAST: internal use + */ +enum nl80211_commands { +/* don't change the order or add anything inbetween, this is ABI! */ + NL80211_CMD_UNSPEC, + + NL80211_CMD_GET_WIPHY, /* can dump */ + NL80211_CMD_SET_WIPHY, + NL80211_CMD_NEW_WIPHY, + NL80211_CMD_DEL_WIPHY, + + NL80211_CMD_GET_INTERFACE, /* can dump */ + NL80211_CMD_SET_INTERFACE, + NL80211_CMD_NEW_INTERFACE, + NL80211_CMD_DEL_INTERFACE, + + /* add commands here */ + + /* used to define NL80211_CMD_MAX below */ + __NL80211_CMD_AFTER_LAST, + NL80211_CMD_MAX = __NL80211_CMD_AFTER_LAST - 1 +}; + + +/** + * enum nl80211_attrs - nl80211 netlink attributes + * + * @NL80211_ATTR_UNSPEC: unspecified attribute to catch errors + * + * @NL80211_ATTR_WIPHY: index of wiphy to operate on, cf. + * /sys/class/ieee80211//index + * @NL80211_ATTR_WIPHY_NAME: wiphy name (used for renaming) + * + * @NL80211_ATTR_IFINDEX: network interface index of the device to operate on + * @NL80211_ATTR_IFNAME: network interface name + * @NL80211_ATTR_IFTYPE: type of virtual interface, see &enum nl80211_iftype + * + * @NL80211_ATTR_MAX: highest attribute number currently defined + * @__NL80211_ATTR_AFTER_LAST: internal use + */ +enum nl80211_attrs { +/* don't change the order or add anything inbetween, this is ABI! */ + NL80211_ATTR_UNSPEC, + + NL80211_ATTR_WIPHY, + NL80211_ATTR_WIPHY_NAME, + + NL80211_ATTR_IFINDEX, + NL80211_ATTR_IFNAME, + NL80211_ATTR_IFTYPE, + + /* add attributes here, update the policy in nl80211.c */ + + __NL80211_ATTR_AFTER_LAST, + NL80211_ATTR_MAX = __NL80211_ATTR_AFTER_LAST - 1 +}; + /** * enum nl80211_iftype - (virtual) interface types + * * @NL80211_IFTYPE_UNSPECIFIED: unspecified type, driver decides * @NL80211_IFTYPE_ADHOC: independent BSS member * @NL80211_IFTYPE_STATION: managed BSS member @@ -15,9 +105,10 @@ * @NL80211_IFTYPE_AP_VLAN: VLAN interface for access points * @NL80211_IFTYPE_WDS: wireless distribution interface * @NL80211_IFTYPE_MONITOR: monitor interface receiving all frames + * @NL80211_IFTYPE_MAX: highest interface type number currently defined * @__NL80211_IFTYPE_AFTER_LAST: internal use * - * These values are used with the NL80211_ATTR_IFTYPE + * These values are used with the %NL80211_ATTR_IFTYPE * to set the type of an interface. * */ @@ -31,8 +122,8 @@ enum nl80211_iftype { NL80211_IFTYPE_MONITOR, /* keep last */ - __NL80211_IFTYPE_AFTER_LAST + __NL80211_IFTYPE_AFTER_LAST, + NL80211_IFTYPE_MAX = __NL80211_IFTYPE_AFTER_LAST - 1 }; -#define NL80211_IFTYPE_MAX (__NL80211_IFTYPE_AFTER_LAST - 1) #endif /* __LINUX_NL80211_H */ diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 7edaef6b29d6..d30960e1755c 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -3,15 +3,15 @@ #include #include +#include #include /* * 802.11 configuration in-kernel interface * - * Copyright 2006 Johannes Berg + * Copyright 2006, 2007 Johannes Berg */ - /* Radiotap header iteration * implemented in net/wireless/radiotap.c * docs in Documentation/networking/radiotap-headers.txt @@ -68,11 +68,16 @@ struct wiphy; * @add_virtual_intf: create a new virtual interface with the given name * * @del_virtual_intf: remove the virtual interface determined by ifindex. + * + * @change_virtual_intf: change type of virtual interface + * */ struct cfg80211_ops { int (*add_virtual_intf)(struct wiphy *wiphy, char *name, - unsigned int type); + enum nl80211_iftype type); int (*del_virtual_intf)(struct wiphy *wiphy, int ifindex); + int (*change_virtual_intf)(struct wiphy *wiphy, int ifindex, + enum nl80211_iftype type); }; #endif /* __NET_CFG80211_H */ diff --git a/include/net/iw_handler.h b/include/net/iw_handler.h index f23d07ca7c59..369d50e08b99 100644 --- a/include/net/iw_handler.h +++ b/include/net/iw_handler.h @@ -431,7 +431,13 @@ struct iw_public_data { * Those may be called only within the kernel. */ -/* functions that may be called by driver modules */ +/* First : function strictly used inside the kernel */ + +/* Handle /proc/net/wireless, called in net/code/dev.c */ +extern int dev_get_wireless_info(char * buffer, char **start, off_t offset, + int length); + +/* Second : functions that may be called by driver modules */ /* Send a single event to user space */ extern void wireless_send_event(struct net_device * dev, diff --git a/net/mac80211/ieee80211_cfg.c b/net/mac80211/ieee80211_cfg.c index b1c13bc9c3ca..d6fc55cc8ad4 100644 --- a/net/mac80211/ieee80211_cfg.c +++ b/net/mac80211/ieee80211_cfg.c @@ -14,7 +14,7 @@ #include "ieee80211_cfg.h" static int ieee80211_add_iface(struct wiphy *wiphy, char *name, - unsigned int type) + enum nl80211_iftype type) { struct ieee80211_local *local = wiphy_priv(wiphy); int itype; diff --git a/net/wireless/Kconfig b/net/wireless/Kconfig index a228d56a91b8..6291f13bba09 100644 --- a/net/wireless/Kconfig +++ b/net/wireless/Kconfig @@ -1,6 +1,19 @@ config CFG80211 tristate "Improved wireless configuration API" +config NL80211 + bool "nl80211 new netlink interface support" + depends CFG80211 + default y + ---help--- + This option turns on the new netlink interface + (nl80211) support in cfg80211. + + If =n, drivers using mac80211 will be configured via + wireless extension support provided by that subsystem. + + If unsure, say Y. + config WIRELESS_EXT bool "Wireless extensions" default n @@ -10,7 +23,9 @@ config WIRELESS_EXT Wireless extensions will be replaced by cfg80211 and will be required only by legacy drivers that implement - wireless extension handlers. + wireless extension handlers. This option does not + affect the wireless-extension backward compatibility + code in cfg80211. Say N (if you can) unless you know you need wireless extensions for external modules. diff --git a/net/wireless/Makefile b/net/wireless/Makefile index 092116e390b6..65710a42e5a7 100644 --- a/net/wireless/Makefile +++ b/net/wireless/Makefile @@ -2,3 +2,4 @@ obj-$(CONFIG_WIRELESS_EXT) += wext.o obj-$(CONFIG_CFG80211) += cfg80211.o cfg80211-y += core.o sysfs.o radiotap.o +cfg80211-$(CONFIG_NL80211) += nl80211.o diff --git a/net/wireless/core.c b/net/wireless/core.c index 9771451eae21..febc33bc9c09 100644 --- a/net/wireless/core.c +++ b/net/wireless/core.c @@ -16,6 +16,7 @@ #include #include #include +#include "nl80211.h" #include "core.h" #include "sysfs.h" @@ -36,6 +37,146 @@ static int wiphy_counter; /* for debugfs */ static struct dentry *ieee80211_debugfs_dir; +/* requires cfg80211_drv_mutex to be held! */ +static struct cfg80211_registered_device *cfg80211_drv_by_wiphy(int wiphy) +{ + struct cfg80211_registered_device *result = NULL, *drv; + + list_for_each_entry(drv, &cfg80211_drv_list, list) { + if (drv->idx == wiphy) { + result = drv; + break; + } + } + + return result; +} + +/* requires cfg80211_drv_mutex to be held! */ +static struct cfg80211_registered_device * +__cfg80211_drv_from_info(struct genl_info *info) +{ + int ifindex; + struct cfg80211_registered_device *bywiphy = NULL, *byifidx = NULL; + struct net_device *dev; + int err = -EINVAL; + + if (info->attrs[NL80211_ATTR_WIPHY]) { + bywiphy = cfg80211_drv_by_wiphy( + nla_get_u32(info->attrs[NL80211_ATTR_WIPHY])); + err = -ENODEV; + } + + if (info->attrs[NL80211_ATTR_IFINDEX]) { + ifindex = nla_get_u32(info->attrs[NL80211_ATTR_IFINDEX]); + dev = dev_get_by_index(&init_net, ifindex); + if (dev) { + if (dev->ieee80211_ptr) + byifidx = + wiphy_to_dev(dev->ieee80211_ptr->wiphy); + dev_put(dev); + } + err = -ENODEV; + } + + if (bywiphy && byifidx) { + if (bywiphy != byifidx) + return ERR_PTR(-EINVAL); + else + return bywiphy; /* == byifidx */ + } + if (bywiphy) + return bywiphy; + + if (byifidx) + return byifidx; + + return ERR_PTR(err); +} + +struct cfg80211_registered_device * +cfg80211_get_dev_from_info(struct genl_info *info) +{ + struct cfg80211_registered_device *drv; + + mutex_lock(&cfg80211_drv_mutex); + drv = __cfg80211_drv_from_info(info); + + /* if it is not an error we grab the lock on + * it to assure it won't be going away while + * we operate on it */ + if (!IS_ERR(drv)) + mutex_lock(&drv->mtx); + + mutex_unlock(&cfg80211_drv_mutex); + + return drv; +} + +struct cfg80211_registered_device * +cfg80211_get_dev_from_ifindex(int ifindex) +{ + struct cfg80211_registered_device *drv = ERR_PTR(-ENODEV); + struct net_device *dev; + + mutex_lock(&cfg80211_drv_mutex); + dev = dev_get_by_index(&init_net, ifindex); + if (!dev) + goto out; + if (dev->ieee80211_ptr) { + drv = wiphy_to_dev(dev->ieee80211_ptr->wiphy); + mutex_lock(&drv->mtx); + } else + drv = ERR_PTR(-ENODEV); + dev_put(dev); + out: + mutex_unlock(&cfg80211_drv_mutex); + return drv; +} + +void cfg80211_put_dev(struct cfg80211_registered_device *drv) +{ + BUG_ON(IS_ERR(drv)); + mutex_unlock(&drv->mtx); +} + +int cfg80211_dev_rename(struct cfg80211_registered_device *rdev, + char *newname) +{ + int idx, taken = -1, result, digits; + + /* prohibit calling the thing phy%d when %d is not its number */ + sscanf(newname, PHY_NAME "%d%n", &idx, &taken); + if (taken == strlen(newname) && idx != rdev->idx) { + /* count number of places needed to print idx */ + digits = 1; + while (idx /= 10) + digits++; + /* + * deny the name if it is phy where is printed + * without leading zeroes. taken == strlen(newname) here + */ + if (taken == strlen(PHY_NAME) + digits) + return -EINVAL; + } + + /* this will check for collisions */ + result = device_rename(&rdev->wiphy.dev, newname); + if (result) + return result; + + if (!debugfs_rename(rdev->wiphy.debugfsdir->d_parent, + rdev->wiphy.debugfsdir, + rdev->wiphy.debugfsdir->d_parent, + newname)) + printk(KERN_ERR "cfg80211: failed to rename debugfs dir to %s!\n", + newname); + + nl80211_notify_dev_rename(rdev); + + return 0; +} + /* exported functions */ struct wiphy *wiphy_new(struct cfg80211_ops *ops, int sizeof_priv) @@ -204,10 +345,16 @@ static int cfg80211_init(void) if (err) goto out_fail_notifier; + err = nl80211_init(); + if (err) + goto out_fail_nl80211; + ieee80211_debugfs_dir = debugfs_create_dir("ieee80211", NULL); return 0; +out_fail_nl80211: + unregister_netdevice_notifier(&cfg80211_netdev_notifier); out_fail_notifier: wiphy_sysfs_exit(); out_fail_sysfs: @@ -218,6 +365,7 @@ subsys_initcall(cfg80211_init); static void cfg80211_exit(void) { debugfs_remove(ieee80211_debugfs_dir); + nl80211_exit(); unregister_netdevice_notifier(&cfg80211_netdev_notifier); wiphy_sysfs_exit(); } diff --git a/net/wireless/core.h b/net/wireless/core.h index 158db1edb92a..eb0f846b40df 100644 --- a/net/wireless/core.h +++ b/net/wireless/core.h @@ -43,7 +43,39 @@ struct cfg80211_registered_device *wiphy_to_dev(struct wiphy *wiphy) extern struct mutex cfg80211_drv_mutex; extern struct list_head cfg80211_drv_list; +/* + * This function returns a pointer to the driver + * that the genl_info item that is passed refers to. + * If successful, it returns non-NULL and also locks + * the driver's mutex! + * + * This means that you need to call cfg80211_put_dev() + * before being allowed to acquire &cfg80211_drv_mutex! + * + * This is necessary because we need to lock the global + * mutex to get an item off the list safely, and then + * we lock the drv mutex so it doesn't go away under us. + * + * We don't want to keep cfg80211_drv_mutex locked + * for all the time in order to allow requests on + * other interfaces to go through at the same time. + * + * The result of this can be a PTR_ERR and hence must + * be checked with IS_ERR() for errors. + */ +extern struct cfg80211_registered_device * +cfg80211_get_dev_from_info(struct genl_info *info); + +/* identical to cfg80211_get_dev_from_info but only operate on ifindex */ +extern struct cfg80211_registered_device * +cfg80211_get_dev_from_ifindex(int ifindex); + +extern void cfg80211_put_dev(struct cfg80211_registered_device *drv); + /* free object */ extern void cfg80211_dev_free(struct cfg80211_registered_device *drv); +extern int cfg80211_dev_rename(struct cfg80211_registered_device *drv, + char *newname); + #endif /* __NET_WIRELESS_CORE_H */ diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c new file mode 100644 index 000000000000..48b0d453e4e1 --- /dev/null +++ b/net/wireless/nl80211.c @@ -0,0 +1,431 @@ +/* + * This is the new netlink-based wireless configuration interface. + * + * Copyright 2006, 2007 Johannes Berg + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "core.h" +#include "nl80211.h" + +/* the netlink family */ +static struct genl_family nl80211_fam = { + .id = GENL_ID_GENERATE, /* don't bother with a hardcoded ID */ + .name = "nl80211", /* have users key off the name instead */ + .hdrsize = 0, /* no private header */ + .version = 1, /* no particular meaning now */ + .maxattr = NL80211_ATTR_MAX, +}; + +/* internal helper: get drv and dev */ +static int get_drv_dev_by_info_ifindex(struct genl_info *info, + struct cfg80211_registered_device **drv, + struct net_device **dev) +{ + int ifindex; + + if (!info->attrs[NL80211_ATTR_IFINDEX]) + return -EINVAL; + + ifindex = nla_get_u32(info->attrs[NL80211_ATTR_IFINDEX]); + *dev = dev_get_by_index(&init_net, ifindex); + if (!*dev) + return -ENODEV; + + *drv = cfg80211_get_dev_from_ifindex(ifindex); + if (IS_ERR(*drv)) { + dev_put(*dev); + return PTR_ERR(*drv); + } + + return 0; +} + +/* policy for the attributes */ +static struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] __read_mostly = { + [NL80211_ATTR_WIPHY] = { .type = NLA_U32 }, + [NL80211_ATTR_WIPHY_NAME] = { .type = NLA_NUL_STRING, + .len = BUS_ID_SIZE-1 }, + + [NL80211_ATTR_IFTYPE] = { .type = NLA_U32 }, + [NL80211_ATTR_IFINDEX] = { .type = NLA_U32 }, + [NL80211_ATTR_IFNAME] = { .type = NLA_NUL_STRING, .len = IFNAMSIZ-1 }, +}; + +/* message building helper */ +static inline void *nl80211hdr_put(struct sk_buff *skb, u32 pid, u32 seq, + int flags, u8 cmd) +{ + /* since there is no private header just add the generic one */ + return genlmsg_put(skb, pid, seq, &nl80211_fam, flags, cmd); +} + +/* netlink command implementations */ + +static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags, + struct cfg80211_registered_device *dev) +{ + void *hdr; + + hdr = nl80211hdr_put(msg, pid, seq, flags, NL80211_CMD_NEW_WIPHY); + if (!hdr) + return -1; + + NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, dev->idx); + NLA_PUT_STRING(msg, NL80211_ATTR_WIPHY_NAME, wiphy_name(&dev->wiphy)); + return genlmsg_end(msg, hdr); + + nla_put_failure: + return genlmsg_cancel(msg, hdr); +} + +static int nl80211_dump_wiphy(struct sk_buff *skb, struct netlink_callback *cb) +{ + int idx = 0; + int start = cb->args[0]; + struct cfg80211_registered_device *dev; + + mutex_lock(&cfg80211_drv_mutex); + list_for_each_entry(dev, &cfg80211_drv_list, list) { + if (++idx < start) + continue; + if (nl80211_send_wiphy(skb, NETLINK_CB(cb->skb).pid, + cb->nlh->nlmsg_seq, NLM_F_MULTI, + dev) < 0) + break; + } + mutex_unlock(&cfg80211_drv_mutex); + + cb->args[0] = idx; + + return skb->len; +} + +static int nl80211_get_wiphy(struct sk_buff *skb, struct genl_info *info) +{ + struct sk_buff *msg; + struct cfg80211_registered_device *dev; + + dev = cfg80211_get_dev_from_info(info); + if (IS_ERR(dev)) + return PTR_ERR(dev); + + msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL); + if (!msg) + goto out_err; + + if (nl80211_send_wiphy(msg, info->snd_pid, info->snd_seq, 0, dev) < 0) + goto out_free; + + cfg80211_put_dev(dev); + + return genlmsg_unicast(msg, info->snd_pid); + + out_free: + nlmsg_free(msg); + out_err: + cfg80211_put_dev(dev); + return -ENOBUFS; +} + +static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info) +{ + struct cfg80211_registered_device *rdev; + int result; + + if (!info->attrs[NL80211_ATTR_WIPHY_NAME]) + return -EINVAL; + + rdev = cfg80211_get_dev_from_info(info); + if (IS_ERR(rdev)) + return PTR_ERR(rdev); + + result = cfg80211_dev_rename(rdev, nla_data(info->attrs[NL80211_ATTR_WIPHY_NAME])); + + cfg80211_put_dev(rdev); + return result; +} + + +static int nl80211_send_iface(struct sk_buff *msg, u32 pid, u32 seq, int flags, + struct net_device *dev) +{ + void *hdr; + + hdr = nl80211hdr_put(msg, pid, seq, flags, NL80211_CMD_NEW_INTERFACE); + if (!hdr) + return -1; + + NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, dev->ifindex); + NLA_PUT_STRING(msg, NL80211_ATTR_IFNAME, dev->name); + /* TODO: interface type */ + return genlmsg_end(msg, hdr); + + nla_put_failure: + return genlmsg_cancel(msg, hdr); +} + +static int nl80211_dump_interface(struct sk_buff *skb, struct netlink_callback *cb) +{ + int wp_idx = 0; + int if_idx = 0; + int wp_start = cb->args[0]; + int if_start = cb->args[1]; + struct cfg80211_registered_device *dev; + struct wireless_dev *wdev; + + mutex_lock(&cfg80211_drv_mutex); + list_for_each_entry(dev, &cfg80211_drv_list, list) { + if (++wp_idx < wp_start) + continue; + if_idx = 0; + + mutex_lock(&dev->devlist_mtx); + list_for_each_entry(wdev, &dev->netdev_list, list) { + if (++if_idx < if_start) + continue; + if (nl80211_send_iface(skb, NETLINK_CB(cb->skb).pid, + cb->nlh->nlmsg_seq, NLM_F_MULTI, + wdev->netdev) < 0) + break; + } + mutex_unlock(&dev->devlist_mtx); + } + mutex_unlock(&cfg80211_drv_mutex); + + cb->args[0] = wp_idx; + cb->args[1] = if_idx; + + return skb->len; +} + +static int nl80211_get_interface(struct sk_buff *skb, struct genl_info *info) +{ + struct sk_buff *msg; + struct cfg80211_registered_device *dev; + struct net_device *netdev; + int err; + + err = get_drv_dev_by_info_ifindex(info, &dev, &netdev); + if (err) + return err; + + msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL); + if (!msg) + goto out_err; + + if (nl80211_send_iface(msg, info->snd_pid, info->snd_seq, 0, netdev) < 0) + goto out_free; + + dev_put(netdev); + cfg80211_put_dev(dev); + + return genlmsg_unicast(msg, info->snd_pid); + + out_free: + nlmsg_free(msg); + out_err: + dev_put(netdev); + cfg80211_put_dev(dev); + return -ENOBUFS; +} + +static int nl80211_set_interface(struct sk_buff *skb, struct genl_info *info) +{ + struct cfg80211_registered_device *drv; + int err, ifindex; + enum nl80211_iftype type; + struct net_device *dev; + + if (info->attrs[NL80211_ATTR_IFTYPE]) { + type = nla_get_u32(info->attrs[NL80211_ATTR_IFTYPE]); + if (type > NL80211_IFTYPE_MAX) + return -EINVAL; + } else + return -EINVAL; + + err = get_drv_dev_by_info_ifindex(info, &drv, &dev); + if (err) + return err; + ifindex = dev->ifindex; + dev_put(dev); + + if (!drv->ops->change_virtual_intf) { + err = -EOPNOTSUPP; + goto unlock; + } + + rtnl_lock(); + err = drv->ops->change_virtual_intf(&drv->wiphy, ifindex, type); + rtnl_unlock(); + + unlock: + cfg80211_put_dev(drv); + return err; +} + +static int nl80211_new_interface(struct sk_buff *skb, struct genl_info *info) +{ + struct cfg80211_registered_device *drv; + int err; + enum nl80211_iftype type = NL80211_IFTYPE_UNSPECIFIED; + + if (!info->attrs[NL80211_ATTR_IFNAME]) + return -EINVAL; + + if (info->attrs[NL80211_ATTR_IFTYPE]) { + type = nla_get_u32(info->attrs[NL80211_ATTR_IFTYPE]); + if (type > NL80211_IFTYPE_MAX) + return -EINVAL; + } + + drv = cfg80211_get_dev_from_info(info); + if (IS_ERR(drv)) + return PTR_ERR(drv); + + if (!drv->ops->add_virtual_intf) { + err = -EOPNOTSUPP; + goto unlock; + } + + rtnl_lock(); + err = drv->ops->add_virtual_intf(&drv->wiphy, + nla_data(info->attrs[NL80211_ATTR_IFNAME]), type); + rtnl_unlock(); + + unlock: + cfg80211_put_dev(drv); + return err; +} + +static int nl80211_del_interface(struct sk_buff *skb, struct genl_info *info) +{ + struct cfg80211_registered_device *drv; + int ifindex, err; + struct net_device *dev; + + err = get_drv_dev_by_info_ifindex(info, &drv, &dev); + if (err) + return err; + ifindex = dev->ifindex; + dev_put(dev); + + if (!drv->ops->del_virtual_intf) { + err = -EOPNOTSUPP; + goto out; + } + + rtnl_lock(); + err = drv->ops->del_virtual_intf(&drv->wiphy, ifindex); + rtnl_unlock(); + + out: + cfg80211_put_dev(drv); + return err; +} + +static struct genl_ops nl80211_ops[] = { + { + .cmd = NL80211_CMD_GET_WIPHY, + .doit = nl80211_get_wiphy, + .dumpit = nl80211_dump_wiphy, + .policy = nl80211_policy, + /* can be retrieved by unprivileged users */ + }, + { + .cmd = NL80211_CMD_SET_WIPHY, + .doit = nl80211_set_wiphy, + .policy = nl80211_policy, + .flags = GENL_ADMIN_PERM, + }, + { + .cmd = NL80211_CMD_GET_INTERFACE, + .doit = nl80211_get_interface, + .dumpit = nl80211_dump_interface, + .policy = nl80211_policy, + /* can be retrieved by unprivileged users */ + }, + { + .cmd = NL80211_CMD_SET_INTERFACE, + .doit = nl80211_set_interface, + .policy = nl80211_policy, + .flags = GENL_ADMIN_PERM, + }, + { + .cmd = NL80211_CMD_NEW_INTERFACE, + .doit = nl80211_new_interface, + .policy = nl80211_policy, + .flags = GENL_ADMIN_PERM, + }, + { + .cmd = NL80211_CMD_DEL_INTERFACE, + .doit = nl80211_del_interface, + .policy = nl80211_policy, + .flags = GENL_ADMIN_PERM, + }, +}; + +/* multicast groups */ +static struct genl_multicast_group nl80211_config_mcgrp = { + .name = "config", +}; + +/* notification functions */ + +void nl80211_notify_dev_rename(struct cfg80211_registered_device *rdev) +{ + struct sk_buff *msg; + + msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL); + if (!msg) + return; + + if (nl80211_send_wiphy(msg, 0, 0, 0, rdev) < 0) { + nlmsg_free(msg); + return; + } + + genlmsg_multicast(msg, 0, nl80211_config_mcgrp.id, GFP_KERNEL); +} + +/* initialisation/exit functions */ + +int nl80211_init(void) +{ + int err, i; + + err = genl_register_family(&nl80211_fam); + if (err) + return err; + + for (i = 0; i < ARRAY_SIZE(nl80211_ops); i++) { + err = genl_register_ops(&nl80211_fam, &nl80211_ops[i]); + if (err) + goto err_out; + } + + err = genl_register_mc_group(&nl80211_fam, &nl80211_config_mcgrp); + if (err) + goto err_out; + + return 0; + err_out: + genl_unregister_family(&nl80211_fam); + return err; +} + +void nl80211_exit(void) +{ + genl_unregister_family(&nl80211_fam); +} diff --git a/net/wireless/nl80211.h b/net/wireless/nl80211.h new file mode 100644 index 000000000000..f3ea5c029aee --- /dev/null +++ b/net/wireless/nl80211.h @@ -0,0 +1,24 @@ +#ifndef __NET_WIRELESS_NL80211_H +#define __NET_WIRELESS_NL80211_H + +#include "core.h" + +#ifdef CONFIG_NL80211 +extern int nl80211_init(void); +extern void nl80211_exit(void); +extern void nl80211_notify_dev_rename(struct cfg80211_registered_device *rdev); +#else +static inline int nl80211_init(void) +{ + return 0; +} +static inline void nl80211_exit(void) +{ +} +static inline void nl80211_notify_dev_rename( + struct cfg80211_registered_device *rdev) +{ +} +#endif /* CONFIG_NL80211 */ + +#endif /* __NET_WIRELESS_NL80211_H */ -- cgit v1.2.3 From de3cb747ffac5f2a4a6bb156e7e2fd5229e688e5 Mon Sep 17 00:00:00 2001 From: Daniel Lezcano Date: Tue, 25 Sep 2007 19:16:28 -0700 Subject: [NET]: Dynamically allocate the loopback device, part 1. This patch replaces all occurences to the static variable loopback_dev to a pointer loopback_dev. That provides the mindless, trivial, uninteressting change part for the dynamic allocation for the loopback. Signed-off-by: Eric W. Biederman Signed-off-by: Daniel Lezcano Acked-By: Kirill Korotaev Acked-by: Benjamin Thery Signed-off-by: David S. Miller --- drivers/net/loopback.c | 6 ++++-- include/linux/netdevice.h | 2 +- net/core/dst.c | 8 ++++---- net/decnet/dn_dev.c | 4 ++-- net/decnet/dn_route.c | 14 +++++++------- net/ipv4/devinet.c | 6 +++--- net/ipv4/ipconfig.c | 6 +++--- net/ipv4/ipvs/ip_vs_core.c | 2 +- net/ipv4/route.c | 18 +++++++++--------- net/ipv4/xfrm4_policy.c | 2 +- net/ipv6/addrconf.c | 15 +++++++++------ net/ipv6/ip6_input.c | 2 +- net/ipv6/netfilter/ip6t_REJECT.c | 2 +- net/ipv6/route.c | 15 ++++++--------- net/ipv6/xfrm6_policy.c | 2 +- net/xfrm/xfrm_policy.c | 4 ++-- 16 files changed, 55 insertions(+), 53 deletions(-) (limited to 'include/linux') diff --git a/drivers/net/loopback.c b/drivers/net/loopback.c index 0e2252fd71ab..588092e13186 100644 --- a/drivers/net/loopback.c +++ b/drivers/net/loopback.c @@ -202,7 +202,7 @@ static const struct ethtool_ops loopback_ethtool_ops = { * The loopback device is special. There is only one instance and * it is statically allocated. Don't do this for other devices. */ -struct net_device loopback_dev = { +struct net_device __loopback_dev = { .name = "lo", .get_stats = &get_stats, .mtu = (16 * 1024) + 20 + 20 + 12, @@ -227,10 +227,12 @@ struct net_device loopback_dev = { .nd_net = &init_net, }; +struct net_device *loopback_dev = &__loopback_dev; + /* Setup and register the loopback device. */ static int __init loopback_init(void) { - int err = register_netdev(&loopback_dev); + int err = register_netdev(loopback_dev); if (err) panic("loopback: Failed to register netdevice: %d\n", err); diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index cf89ce677e41..baa915f0d285 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -741,7 +741,7 @@ struct packet_type { #include #include -extern struct net_device loopback_dev; /* The loopback */ +extern struct net_device *loopback_dev; /* The loopback */ extern rwlock_t dev_base_lock; /* Device list lock */ diff --git a/net/core/dst.c b/net/core/dst.c index 38c741ac5d08..ad5ffa19d809 100644 --- a/net/core/dst.c +++ b/net/core/dst.c @@ -278,13 +278,13 @@ static inline void dst_ifdown(struct dst_entry *dst, struct net_device *dev, if (!unregister) { dst->input = dst->output = dst_discard; } else { - dst->dev = &loopback_dev; - dev_hold(&loopback_dev); + dst->dev = loopback_dev; + dev_hold(dst->dev); dev_put(dev); if (dst->neighbour && dst->neighbour->dev == dev) { - dst->neighbour->dev = &loopback_dev; + dst->neighbour->dev = loopback_dev; dev_put(dev); - dev_hold(&loopback_dev); + dev_hold(dst->neighbour->dev); } } } diff --git a/net/decnet/dn_dev.c b/net/decnet/dn_dev.c index fa24614b5a37..bcaf4c5aa68e 100644 --- a/net/decnet/dn_dev.c +++ b/net/decnet/dn_dev.c @@ -869,10 +869,10 @@ last_chance: rv = dn_dev_get_first(dev, addr); read_unlock(&dev_base_lock); dev_put(dev); - if (rv == 0 || dev == &loopback_dev) + if (rv == 0 || dev == loopback_dev) return rv; } - dev = &loopback_dev; + dev = loopback_dev; dev_hold(dev); goto last_chance; } diff --git a/net/decnet/dn_route.c b/net/decnet/dn_route.c index 70b1c3fa00f3..96fe0aa1638e 100644 --- a/net/decnet/dn_route.c +++ b/net/decnet/dn_route.c @@ -887,7 +887,7 @@ static int dn_route_output_slow(struct dst_entry **pprt, const struct flowi *old .scope = RT_SCOPE_UNIVERSE, } }, .mark = oldflp->mark, - .iif = loopback_dev.ifindex, + .iif = loopback_dev->ifindex, .oif = oldflp->oif }; struct dn_route *rt = NULL; struct net_device *dev_out = NULL, *dev; @@ -904,7 +904,7 @@ static int dn_route_output_slow(struct dst_entry **pprt, const struct flowi *old "dn_route_output_slow: dst=%04x src=%04x mark=%d" " iif=%d oif=%d\n", dn_ntohs(oldflp->fld_dst), dn_ntohs(oldflp->fld_src), - oldflp->mark, loopback_dev.ifindex, oldflp->oif); + oldflp->mark, loopback_dev->ifindex, oldflp->oif); /* If we have an output interface, verify its a DECnet device */ if (oldflp->oif) { @@ -957,7 +957,7 @@ source_ok: err = -EADDRNOTAVAIL; if (dev_out) dev_put(dev_out); - dev_out = &loopback_dev; + dev_out = loopback_dev; dev_hold(dev_out); if (!fl.fld_dst) { fl.fld_dst = @@ -966,7 +966,7 @@ source_ok: if (!fl.fld_dst) goto out; } - fl.oif = loopback_dev.ifindex; + fl.oif = loopback_dev->ifindex; res.type = RTN_LOCAL; goto make_route; } @@ -1012,7 +1012,7 @@ source_ok: if (dev_out) dev_put(dev_out); if (dn_dev_islocal(neigh->dev, fl.fld_dst)) { - dev_out = &loopback_dev; + dev_out = loopback_dev; res.type = RTN_LOCAL; } else { dev_out = neigh->dev; @@ -1033,7 +1033,7 @@ source_ok: /* Possible improvement - check all devices for local addr */ if (dn_dev_islocal(dev_out, fl.fld_dst)) { dev_put(dev_out); - dev_out = &loopback_dev; + dev_out = loopback_dev; dev_hold(dev_out); res.type = RTN_LOCAL; goto select_source; @@ -1069,7 +1069,7 @@ select_source: fl.fld_src = fl.fld_dst; if (dev_out) dev_put(dev_out); - dev_out = &loopback_dev; + dev_out = loopback_dev; dev_hold(dev_out); fl.oif = dev_out->ifindex; if (res.fi) diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c index 721b89b60963..affea9b121fc 100644 --- a/net/ipv4/devinet.c +++ b/net/ipv4/devinet.c @@ -203,7 +203,7 @@ static void inetdev_destroy(struct in_device *in_dev) ASSERT_RTNL(); dev = in_dev->dev; - if (dev == &loopback_dev) + if (dev == loopback_dev) return; in_dev->dead = 1; @@ -1061,7 +1061,7 @@ static int inetdev_event(struct notifier_block *this, unsigned long event, in_dev = inetdev_init(dev); if (!in_dev) return notifier_from_errno(-ENOMEM); - if (dev == &loopback_dev) { + if (dev == loopback_dev) { IN_DEV_CONF_SET(in_dev, NOXFRM, 1); IN_DEV_CONF_SET(in_dev, NOPOLICY, 1); } @@ -1077,7 +1077,7 @@ static int inetdev_event(struct notifier_block *this, unsigned long event, case NETDEV_UP: if (dev->mtu < 68) break; - if (dev == &loopback_dev) { + if (dev == loopback_dev) { struct in_ifaddr *ifa; if ((ifa = inet_alloc_ifa()) != NULL) { ifa->ifa_local = diff --git a/net/ipv4/ipconfig.c b/net/ipv4/ipconfig.c index 4303851749f6..2d2e0cda0470 100644 --- a/net/ipv4/ipconfig.c +++ b/net/ipv4/ipconfig.c @@ -190,11 +190,11 @@ static int __init ic_open_devs(void) rtnl_lock(); /* bring loopback device up first */ - if (dev_change_flags(&loopback_dev, loopback_dev.flags | IFF_UP) < 0) - printk(KERN_ERR "IP-Config: Failed to open %s\n", loopback_dev.name); + if (dev_change_flags(loopback_dev, loopback_dev->flags | IFF_UP) < 0) + printk(KERN_ERR "IP-Config: Failed to open %s\n", loopback_dev->name); for_each_netdev(&init_net, dev) { - if (dev == &loopback_dev) + if (dev == loopback_dev) continue; if (user_dev_name[0] ? !strcmp(dev->name, user_dev_name) : (!(dev->flags & IFF_LOOPBACK) && diff --git a/net/ipv4/ipvs/ip_vs_core.c b/net/ipv4/ipvs/ip_vs_core.c index f005a2f929f4..74503267e5d4 100644 --- a/net/ipv4/ipvs/ip_vs_core.c +++ b/net/ipv4/ipvs/ip_vs_core.c @@ -961,7 +961,7 @@ ip_vs_in(unsigned int hooknum, struct sk_buff **pskb, * ... don't know why 1st test DOES NOT include 2nd (?) */ if (unlikely(skb->pkt_type != PACKET_HOST - || skb->dev == &loopback_dev || skb->sk)) { + || skb->dev == loopback_dev || skb->sk)) { IP_VS_DBG(12, "packet type=%d proto=%d daddr=%d.%d.%d.%d ignored\n", skb->pkt_type, ip_hdr(skb)->protocol, diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 006d6058a806..ca2878dc6188 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -1402,8 +1402,8 @@ static void ipv4_dst_ifdown(struct dst_entry *dst, struct net_device *dev, { struct rtable *rt = (struct rtable *) dst; struct in_device *idev = rt->idev; - if (dev != &loopback_dev && idev && idev->dev == dev) { - struct in_device *loopback_idev = in_dev_get(&loopback_dev); + if (dev != loopback_dev && idev && idev->dev == dev) { + struct in_device *loopback_idev = in_dev_get(loopback_dev); if (loopback_idev) { rt->idev = loopback_idev; in_dev_put(idev); @@ -1555,7 +1555,7 @@ static int ip_route_input_mc(struct sk_buff *skb, __be32 daddr, __be32 saddr, #endif rth->rt_iif = rth->fl.iif = dev->ifindex; - rth->u.dst.dev = &loopback_dev; + rth->u.dst.dev = loopback_dev; dev_hold(rth->u.dst.dev); rth->idev = in_dev_get(rth->u.dst.dev); rth->fl.oif = 0; @@ -1812,7 +1812,7 @@ static int ip_route_input_slow(struct sk_buff *skb, __be32 daddr, __be32 saddr, if (res.type == RTN_LOCAL) { int result; result = fib_validate_source(saddr, daddr, tos, - loopback_dev.ifindex, + loopback_dev->ifindex, dev, &spec_dst, &itag); if (result < 0) goto martian_source; @@ -1879,7 +1879,7 @@ local_input: #endif rth->rt_iif = rth->fl.iif = dev->ifindex; - rth->u.dst.dev = &loopback_dev; + rth->u.dst.dev = loopback_dev; dev_hold(rth->u.dst.dev); rth->idev = in_dev_get(rth->u.dst.dev); rth->rt_gateway = daddr; @@ -2149,7 +2149,7 @@ static int ip_route_output_slow(struct rtable **rp, const struct flowi *oldflp) RT_SCOPE_UNIVERSE), } }, .mark = oldflp->mark, - .iif = loopback_dev.ifindex, + .iif = loopback_dev->ifindex, .oif = oldflp->oif }; struct fib_result res; unsigned flags = 0; @@ -2243,9 +2243,9 @@ static int ip_route_output_slow(struct rtable **rp, const struct flowi *oldflp) fl.fl4_dst = fl.fl4_src = htonl(INADDR_LOOPBACK); if (dev_out) dev_put(dev_out); - dev_out = &loopback_dev; + dev_out = loopback_dev; dev_hold(dev_out); - fl.oif = loopback_dev.ifindex; + fl.oif = loopback_dev->ifindex; res.type = RTN_LOCAL; flags |= RTCF_LOCAL; goto make_route; @@ -2290,7 +2290,7 @@ static int ip_route_output_slow(struct rtable **rp, const struct flowi *oldflp) fl.fl4_src = fl.fl4_dst; if (dev_out) dev_put(dev_out); - dev_out = &loopback_dev; + dev_out = loopback_dev; dev_hold(dev_out); fl.oif = dev_out->ifindex; if (res.fi) diff --git a/net/ipv4/xfrm4_policy.c b/net/ipv4/xfrm4_policy.c index 4ff8ed30024f..29ab3de8c47f 100644 --- a/net/ipv4/xfrm4_policy.c +++ b/net/ipv4/xfrm4_policy.c @@ -306,7 +306,7 @@ static void xfrm4_dst_ifdown(struct dst_entry *dst, struct net_device *dev, xdst = (struct xfrm_dst *)dst; if (xdst->u.rt.idev->dev == dev) { - struct in_device *loopback_idev = in_dev_get(&loopback_dev); + struct in_device *loopback_idev = in_dev_get(loopback_dev); BUG_ON(!loopback_idev); do { diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 9c2e94f1c637..b43574f73375 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -2410,7 +2410,7 @@ static int addrconf_ifdown(struct net_device *dev, int how) ASSERT_RTNL(); - if (dev == &loopback_dev && how == 1) + if (dev == loopback_dev && how == 1) how = 0; rt6_ifdown(dev); @@ -4212,16 +4212,19 @@ int __init addrconf_init(void) * device and it being up should be removed. */ rtnl_lock(); - if (!ipv6_add_dev(&loopback_dev)) + if (!ipv6_add_dev(loopback_dev)) err = -ENOMEM; rtnl_unlock(); if (err) return err; - ip6_null_entry.rt6i_idev = in6_dev_get(&loopback_dev); + ip6_null_entry.u.dst.dev = loopback_dev; + ip6_null_entry.rt6i_idev = in6_dev_get(loopback_dev); #ifdef CONFIG_IPV6_MULTIPLE_TABLES - ip6_prohibit_entry.rt6i_idev = in6_dev_get(&loopback_dev); - ip6_blk_hole_entry.rt6i_idev = in6_dev_get(&loopback_dev); + ip6_prohibit_entry.u.dst.dev = loopback_dev; + ip6_prohibit_entry.rt6i_idev = in6_dev_get(loopback_dev); + ip6_blk_hole_entry.u.dst.dev = loopback_dev; + ip6_blk_hole_entry.rt6i_idev = in6_dev_get(loopback_dev); #endif register_netdevice_notifier(&ipv6_dev_notf); @@ -4276,7 +4279,7 @@ void __exit addrconf_cleanup(void) continue; addrconf_ifdown(dev, 1); } - addrconf_ifdown(&loopback_dev, 2); + addrconf_ifdown(loopback_dev, 2); /* * Check hash table. diff --git a/net/ipv6/ip6_input.c b/net/ipv6/ip6_input.c index 7d18cac3f110..9149fc239759 100644 --- a/net/ipv6/ip6_input.c +++ b/net/ipv6/ip6_input.c @@ -91,7 +91,7 @@ int ipv6_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt * * BTW, when we send a packet for our own local address on a * non-loopback interface (e.g. ethX), it is being delivered - * via the loopback interface (lo) here; skb->dev = &loopback_dev. + * via the loopback interface (lo) here; skb->dev = loopback_dev. * It, however, should be considered as if it is being * arrived via the sending interface (ethX), because of the * nature of scoping architecture. --yoshfuji diff --git a/net/ipv6/netfilter/ip6t_REJECT.c b/net/ipv6/netfilter/ip6t_REJECT.c index 2f487cda3b6b..50860531cd3c 100644 --- a/net/ipv6/netfilter/ip6t_REJECT.c +++ b/net/ipv6/netfilter/ip6t_REJECT.c @@ -167,7 +167,7 @@ static inline void send_unreach(struct sk_buff *skb_in, unsigned char code, unsigned int hooknum) { if (hooknum == NF_IP6_LOCAL_OUT && skb_in->dev == NULL) - skb_in->dev = &loopback_dev; + skb_in->dev = loopback_dev; icmpv6_send(skb_in, ICMPV6_DEST_UNREACH, code, 0, NULL); } diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 104070e92cea..a7a21a7ba790 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c @@ -138,7 +138,6 @@ struct rt6_info ip6_null_entry = { .dst = { .__refcnt = ATOMIC_INIT(1), .__use = 1, - .dev = &loopback_dev, .obsolete = -1, .error = -ENETUNREACH, .metrics = { [RTAX_HOPLIMIT - 1] = 255, }, @@ -164,7 +163,6 @@ struct rt6_info ip6_prohibit_entry = { .dst = { .__refcnt = ATOMIC_INIT(1), .__use = 1, - .dev = &loopback_dev, .obsolete = -1, .error = -EACCES, .metrics = { [RTAX_HOPLIMIT - 1] = 255, }, @@ -184,7 +182,6 @@ struct rt6_info ip6_blk_hole_entry = { .dst = { .__refcnt = ATOMIC_INIT(1), .__use = 1, - .dev = &loopback_dev, .obsolete = -1, .error = -EINVAL, .metrics = { [RTAX_HOPLIMIT - 1] = 255, }, @@ -224,8 +221,8 @@ static void ip6_dst_ifdown(struct dst_entry *dst, struct net_device *dev, struct rt6_info *rt = (struct rt6_info *)dst; struct inet6_dev *idev = rt->rt6i_idev; - if (dev != &loopback_dev && idev != NULL && idev->dev == dev) { - struct inet6_dev *loopback_idev = in6_dev_get(&loopback_dev); + if (dev != loopback_dev && idev != NULL && idev->dev == dev) { + struct inet6_dev *loopback_idev = in6_dev_get(loopback_dev); if (loopback_idev != NULL) { rt->rt6i_idev = loopback_idev; in6_dev_put(idev); @@ -1188,12 +1185,12 @@ int ip6_route_add(struct fib6_config *cfg) if ((cfg->fc_flags & RTF_REJECT) || (dev && (dev->flags&IFF_LOOPBACK) && !(addr_type&IPV6_ADDR_LOOPBACK))) { /* hold loopback dev/idev if we haven't done so. */ - if (dev != &loopback_dev) { + if (dev != loopback_dev) { if (dev) { dev_put(dev); in6_dev_put(idev); } - dev = &loopback_dev; + dev = loopback_dev; dev_hold(dev); idev = in6_dev_get(dev); if (!idev) { @@ -1897,13 +1894,13 @@ struct rt6_info *addrconf_dst_alloc(struct inet6_dev *idev, if (rt == NULL) return ERR_PTR(-ENOMEM); - dev_hold(&loopback_dev); + dev_hold(loopback_dev); in6_dev_hold(idev); rt->u.dst.flags = DST_HOST; rt->u.dst.input = ip6_input; rt->u.dst.output = ip6_output; - rt->rt6i_dev = &loopback_dev; + rt->rt6i_dev = loopback_dev; rt->rt6i_idev = idev; rt->u.dst.metrics[RTAX_MTU-1] = ipv6_get_mtu(rt->rt6i_dev); rt->u.dst.metrics[RTAX_ADVMSS-1] = ipv6_advmss(dst_mtu(&rt->u.dst)); diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c index 3ec0c4770ee3..cc07216cfd59 100644 --- a/net/ipv6/xfrm6_policy.c +++ b/net/ipv6/xfrm6_policy.c @@ -375,7 +375,7 @@ static void xfrm6_dst_ifdown(struct dst_entry *dst, struct net_device *dev, xdst = (struct xfrm_dst *)dst; if (xdst->u.rt6.rt6i_idev->dev == dev) { - struct inet6_dev *loopback_idev = in6_dev_get(&loopback_dev); + struct inet6_dev *loopback_idev = in6_dev_get(loopback_dev); BUG_ON(!loopback_idev); do { diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index 50682d3cd7a9..d6dfd7d1948f 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c @@ -1949,8 +1949,8 @@ static int stale_bundle(struct dst_entry *dst) void xfrm_dst_ifdown(struct dst_entry *dst, struct net_device *dev) { while ((dst = dst->child) && dst->xfrm && dst->dev == dev) { - dst->dev = &loopback_dev; - dev_hold(&loopback_dev); + dst->dev = loopback_dev; + dev_hold(dst->dev); dev_put(dev); } } -- cgit v1.2.3 From e24eb521fbf2a350ce879dfc1d8e56d4ffa2aa22 Mon Sep 17 00:00:00 2001 From: Christian Borntraeger Date: Tue, 25 Sep 2007 19:42:02 -0700 Subject: [NET]: note that NETIF_F_LLTX is deprecated Am Freitag, 21. September 2007 schrieb Herbert Xu: > Please don't use LLTX in new drivers. We're trying to get rid > of it since it's > > 1) unnecessary; > 2) causes problems with AF_PACKET seeing things twice. I suggest to document that LLTX is deprecated. Signed-off-by: Christian Borntraeger Acked-by: Herbert Xu Signed-off-by: David S. Miller --- Documentation/networking/netdevices.txt | 3 ++- include/linux/netdevice.h | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/Documentation/networking/netdevices.txt b/Documentation/networking/netdevices.txt index 9f7be9b7785e..d0f71fc7f782 100644 --- a/Documentation/networking/netdevices.txt +++ b/Documentation/networking/netdevices.txt @@ -73,7 +73,8 @@ dev->hard_start_xmit: has to lock by itself when needed. It is recommended to use a try lock for this and return NETDEV_TX_LOCKED when the spin lock fails. The locking there should also properly protect against - set_multicast_list. + set_multicast_list. Note that the use of NETIF_F_LLTX is deprecated. + Dont use it for new drivers. Context: Process with BHs disabled or BH (timer), will be called with interrupts disabled by netconsole. diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index baa915f0d285..2088097663b5 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -449,7 +449,8 @@ struct net_device #define NETIF_F_HW_VLAN_FILTER 512 /* Receive filtering on VLAN */ #define NETIF_F_VLAN_CHALLENGED 1024 /* Device cannot handle VLAN packets */ #define NETIF_F_GSO 2048 /* Enable software GSO. */ -#define NETIF_F_LLTX 4096 /* LockLess TX */ +#define NETIF_F_LLTX 4096 /* LockLess TX - deprecated. Please */ + /* do not use LLTX in new drivers */ #define NETIF_F_NETNS_LOCAL 8192 /* Does not change network namespaces */ #define NETIF_F_MULTI_QUEUE 16384 /* Has multiple TX/RX queues */ #define NETIF_F_LRO 32768 /* large receive offload */ -- cgit v1.2.3 From 912d8f0b1f17b7e851ebbfeb17a16de9f9c7cb88 Mon Sep 17 00:00:00 2001 From: Ilpo Järvinen Date: Tue, 25 Sep 2007 22:47:31 -0700 Subject: [TCP] MIB: Count FRTO's successfully detected spurious RTOs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Ilpo Järvinen Signed-off-by: David S. Miller --- include/linux/snmp.h | 1 + net/ipv4/proc.c | 1 + net/ipv4/tcp_input.c | 1 + 3 files changed, 3 insertions(+) (limited to 'include/linux') diff --git a/include/linux/snmp.h b/include/linux/snmp.h index d8fd3ec4148a..89f0c2b5f405 100644 --- a/include/linux/snmp.h +++ b/include/linux/snmp.h @@ -213,6 +213,7 @@ enum LINUX_MIB_TCPSACKDISCARD, /* TCPSACKDiscard */ LINUX_MIB_TCPDSACKIGNOREDOLD, /* TCPSACKIgnoredOld */ LINUX_MIB_TCPDSACKIGNOREDNOUNDO, /* TCPSACKIgnoredNoUndo */ + LINUX_MIB_TCPSPURIOUSRTOS, /* TCPSpuriousRTOs */ __LINUX_MIB_MAX }; diff --git a/net/ipv4/proc.c b/net/ipv4/proc.c index 2015148b41a8..9dee70e1cf0d 100644 --- a/net/ipv4/proc.c +++ b/net/ipv4/proc.c @@ -245,6 +245,7 @@ static const struct snmp_mib snmp4_net_list[] = { SNMP_MIB_ITEM("TCPSACKDiscard", LINUX_MIB_TCPSACKDISCARD), SNMP_MIB_ITEM("TCPDSACKIgnoredOld", LINUX_MIB_TCPDSACKIGNOREDOLD), SNMP_MIB_ITEM("TCPDSACKIgnoredNoUndo", LINUX_MIB_TCPDSACKIGNOREDNOUNDO), + SNMP_MIB_ITEM("TCPSpuriousRTOs", LINUX_MIB_TCPSPURIOUSRTOS), SNMP_MIB_SENTINEL }; diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index 4866e75e98e0..4b27739031fb 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c @@ -2935,6 +2935,7 @@ static int tcp_process_frto(struct sock *sk, int flag) } tp->frto_counter = 0; tp->undo_marker = 0; + NET_INC_STATS_BH(LINUX_MIB_TCPSPURIOUSRTOS); } return 0; } -- cgit v1.2.3 From 0430ee3451f4589b68f522552b1896825f2043b3 Mon Sep 17 00:00:00 2001 From: Gerrit Renker Date: Wed, 26 Sep 2007 11:27:56 -0300 Subject: [DCCP]: Add Support for Data 1 .. 3 fields of Reset packets This adds fields to support the informational Data 1..3 fields of the DCCP-Reset packets (RFC 4340, 5.6), and makes minor cosmetic changes to documentation. Code which fills in these fields follows in subsequent patches, it is primarily used for reporting option-processing and feature-negotiation errors. Signed-off-by: Gerrit Renker Signed-off-by: Arnaldo Carvalho de Melo --- include/linux/dccp.h | 14 ++++++-------- net/dccp/dccp.h | 14 +++++++++++++- 2 files changed, 19 insertions(+), 9 deletions(-) (limited to 'include/linux') diff --git a/include/linux/dccp.h b/include/linux/dccp.h index a0441190dc71..20e0717aa8e1 100644 --- a/include/linux/dccp.h +++ b/include/linux/dccp.h @@ -56,10 +56,9 @@ struct dccp_hdr_ext { }; /** - * struct dccp_hdr_request - Conection initiation request header + * struct dccp_hdr_request - Connection initiation request header * * @dccph_req_service - Service to which the client app wants to connect - * @dccph_req_options - list of options (must be a multiple of 32 bits */ struct dccp_hdr_request { __be32 dccph_req_service; @@ -76,12 +75,10 @@ struct dccp_hdr_ack_bits { __be32 dccph_ack_nr_low; }; /** - * struct dccp_hdr_response - Conection initiation response header + * struct dccp_hdr_response - Connection initiation response header * - * @dccph_resp_ack_nr_high - 48 bit ack number high order bits, contains GSR - * @dccph_resp_ack_nr_low - 48 bit ack number low order bits, contains GSR + * @dccph_resp_ack - 48 bit Acknowledgment Number Subheader (5.3) * @dccph_resp_service - Echoes the Service Code on a received DCCP-Request - * @dccph_resp_options - list of options (must be a multiple of 32 bits */ struct dccp_hdr_response { struct dccp_hdr_ack_bits dccph_resp_ack; @@ -91,8 +88,9 @@ struct dccp_hdr_response { /** * struct dccp_hdr_reset - Unconditionally shut down a connection * - * @dccph_reset_service - Echoes the Service Code on a received DCCP-Request - * @dccph_reset_options - list of options (must be a multiple of 32 bits + * @dccph_reset_ack - 48 bit Acknowledgment Number Subheader (5.6) + * @dccph_reset_code - one of %dccp_reset_codes + * @dccph_reset_data - the Data 1 ... Data 3 fields from 5.6 */ struct dccp_hdr_reset { struct dccp_hdr_ack_bits dccph_reset_ack; diff --git a/net/dccp/dccp.h b/net/dccp/dccp.h index f62eeb374931..e28220183208 100644 --- a/net/dccp/dccp.h +++ b/net/dccp/dccp.h @@ -308,10 +308,22 @@ static inline int dccp_bad_service_code(const struct sock *sk, return !dccp_list_has_service(dp->dccps_service_list, service); } +/** + * dccp_skb_cb - DCCP per-packet control information + * @dccpd_type: one of %dccp_pkt_type (or unknown) + * @dccpd_ccval: CCVal field (5.1), see e.g. RFC 4342, 8.1 + * @dccpd_reset_code: one of %dccp_reset_codes + * @dccpd_reset_data: Data1..3 fields (depend on @dccpd_reset_code) + * @dccpd_opt_len: total length of all options (5.8) in the packet + * @dccpd_seq: sequence number + * @dccpd_ack_seq: acknowledgment number subheader field value + * This is used for transmission as well as for reception. + */ struct dccp_skb_cb { __u8 dccpd_type:4; __u8 dccpd_ccval:4; - __u8 dccpd_reset_code; + __u8 dccpd_reset_code, + dccpd_reset_data[3]; __u16 dccpd_opt_len; __u64 dccpd_seq; __u64 dccpd_ack_seq; -- cgit v1.2.3 From a94f0f970549e63e54c80c4509db299c514d8c11 Mon Sep 17 00:00:00 2001 From: Gerrit Renker Date: Wed, 26 Sep 2007 11:31:49 -0300 Subject: [DCCP]: Rate-limit DCCP-Syncs This implements a SHOULD from RFC 4340, 7.5.4: "To protect against denial-of-service attacks, DCCP implementations SHOULD impose a rate limit on DCCP-Syncs sent in response to sequence-invalid packets, such as not more than eight DCCP-Syncs per second." The rate-limit is maintained on a per-socket basis. This is a more stringent policy than enforcing the rate-limit on a per-source-address basis and protects against attacks with forged source addresses. Moreover, the mechanism is deliberately kept simple. In contrast to xrlim_allow(), bursts of Sync packets in reply to sequence-invalid packets are not supported. This foils such attacks where the receipt of a Sync triggers further sequence-invalid packets. (I have tested this mechanism against xrlim_allow algorithm for Syncs, permitting bursts just increases the problems.) In order to keep flexibility, the timeout parameter can be set via sysctl; and the whole mechanism can even be disabled (which is however not recommended). The algorithm in this patch has been improved with regard to wrapping issues thanks to a suggestion by Arnaldo. Commiter note: Rate limited the step 6 DCCP_WARN too, as it says we're sending a sync. Signed-off-by: Gerrit Renker Signed-off-by: Ian McDonald Signed-off-by: Arnaldo Carvalho de Melo --- Documentation/networking/dccp.txt | 5 +++++ include/linux/dccp.h | 2 ++ net/dccp/dccp.h | 1 + net/dccp/input.c | 29 ++++++++++++++++++++--------- net/dccp/proto.c | 1 + net/dccp/sysctl.c | 10 ++++++++++ 6 files changed, 39 insertions(+), 9 deletions(-) (limited to 'include/linux') diff --git a/Documentation/networking/dccp.txt b/Documentation/networking/dccp.txt index 4504cc59e405..477026ae0ffb 100644 --- a/Documentation/networking/dccp.txt +++ b/Documentation/networking/dccp.txt @@ -112,6 +112,11 @@ tx_qlen = 5 The size of the transmit buffer in packets. A value of 0 corresponds to an unbounded transmit buffer. +sync_ratelimit = 125 ms + The timeout between subsequent DCCP-Sync packets sent in response to + sequence-invalid packets on the same socket (RFC 4340, 7.5.4). The unit + of this parameter is milliseconds; a value of 0 disables rate-limiting. + Notes ===== diff --git a/include/linux/dccp.h b/include/linux/dccp.h index 20e0717aa8e1..4ed82e2c9f65 100644 --- a/include/linux/dccp.h +++ b/include/linux/dccp.h @@ -470,6 +470,7 @@ struct dccp_ackvec; * @dccps_pcrlen - receiver partial checksum coverage (via sockopt) * @dccps_ndp_count - number of Non Data Packets since last data packet * @dccps_mss_cache - current value of MSS (path MTU minus header sizes) + * @dccps_rate_last - timestamp for rate-limiting DCCP-Sync (RFC 4340, 7.5.4) * @dccps_minisock - associated minisock (accessed via dccp_msk) * @dccps_hc_rx_ackvec - rx half connection ack vector * @dccps_hc_rx_ccid - CCID used for the receiver (or receiving half-connection) @@ -505,6 +506,7 @@ struct dccp_sock { __u16 dccps_pcrlen; unsigned long dccps_ndp_count; __u32 dccps_mss_cache; + unsigned long dccps_rate_last; struct dccp_minisock dccps_minisock; struct dccp_ackvec *dccps_hc_rx_ackvec; struct ccid *dccps_hc_rx_ccid; diff --git a/net/dccp/dccp.h b/net/dccp/dccp.h index e28220183208..a602d9212c64 100644 --- a/net/dccp/dccp.h +++ b/net/dccp/dccp.h @@ -92,6 +92,7 @@ extern int sysctl_dccp_feat_ack_ratio; extern int sysctl_dccp_feat_send_ack_vector; extern int sysctl_dccp_feat_send_ndp_count; extern int sysctl_dccp_tx_qlen; +extern int sysctl_dccp_sync_ratelimit; /* * 48-bit sequence number arithmetic (signed and unsigned) diff --git a/net/dccp/input.c b/net/dccp/input.c index 86ad3ba0649a..19d7e1dbd87e 100644 --- a/net/dccp/input.c +++ b/net/dccp/input.c @@ -122,6 +122,23 @@ static int dccp_check_seqno(struct sock *sk, struct sk_buff *skb) (ackno != DCCP_PKT_WITHOUT_ACK_SEQ)) dp->dccps_gar = ackno; } else { + unsigned long now = jiffies; + /* + * Step 6: Check sequence numbers + * Otherwise, + * If P.type == Reset, + * Send Sync packet acknowledging S.GSR + * Otherwise, + * Send Sync packet acknowledging P.seqno + * Drop packet and return + * + * These Syncs are rate-limited as per RFC 4340, 7.5.4: + * at most 1 / (dccp_sync_rate_limit * HZ) Syncs per second. + */ + if (time_before(now, (dp->dccps_rate_last + + sysctl_dccp_sync_ratelimit))) + return 0; + DCCP_WARN("DCCP: Step 6 failed for %s packet, " "(LSWL(%llu) <= P.seqno(%llu) <= S.SWH(%llu)) and " "(P.ackno %s or LAWL(%llu) <= P.ackno(%llu) <= S.AWH(%llu), " @@ -132,15 +149,9 @@ static int dccp_check_seqno(struct sock *sk, struct sk_buff *skb) : "exists", (unsigned long long) lawl, (unsigned long long) ackno, (unsigned long long) dp->dccps_awh); - /* - * Step 6: Check sequence numbers - * Otherwise, - * If P.type == Reset, - * Send Sync packet acknowledging S.GSR - * Otherwise, - * Send Sync packet acknowledging P.seqno - * Drop packet and return - */ + + dp->dccps_rate_last = now; + if (dh->dccph_type == DCCP_PKT_RESET) seqno = dp->dccps_gsr; dccp_send_sync(sk, seqno, DCCP_PKT_SYNC); diff --git a/net/dccp/proto.c b/net/dccp/proto.c index 14ec1d21452c..604de8bfa068 100644 --- a/net/dccp/proto.c +++ b/net/dccp/proto.c @@ -219,6 +219,7 @@ int dccp_init_sock(struct sock *sk, const __u8 ctl_sock_initialized) sk->sk_write_space = dccp_write_space; icsk->icsk_sync_mss = dccp_sync_mss; dp->dccps_mss_cache = 536; + dp->dccps_rate_last = jiffies; dp->dccps_role = DCCP_ROLE_UNDEFINED; dp->dccps_service = DCCP_SERVICE_CODE_IS_ABSENT; dp->dccps_l_ack_ratio = dp->dccps_r_ack_ratio = 1; diff --git a/net/dccp/sysctl.c b/net/dccp/sysctl.c index 1260aabac5e1..9364b2fb4dbd 100644 --- a/net/dccp/sysctl.c +++ b/net/dccp/sysctl.c @@ -18,6 +18,9 @@ #error This file should not be compiled without CONFIG_SYSCTL defined #endif +/* rate-limit for syncs in reply to sequence-invalid packets; RFC 4340, 7.5.4 */ +int sysctl_dccp_sync_ratelimit __read_mostly = HZ / 8; + static struct ctl_table dccp_default_table[] = { { .procname = "seq_window", @@ -89,6 +92,13 @@ static struct ctl_table dccp_default_table[] = { .mode = 0644, .proc_handler = proc_dointvec, }, + { + .procname = "sync_ratelimit", + .data = &sysctl_dccp_sync_ratelimit, + .maxlen = sizeof(sysctl_dccp_sync_ratelimit), + .mode = 0644, + .proc_handler = proc_dointvec_ms_jiffies, + }, { .ctl_name = 0, } }; -- cgit v1.2.3 From 9dd776b6d7b0b85966b6ddd03e2b2aae59012ab1 Mon Sep 17 00:00:00 2001 From: "Eric W. Biederman" Date: Wed, 26 Sep 2007 22:04:26 -0700 Subject: [NET]: Add network namespace clone & unshare support. This patch allows you to create a new network namespace using sys_clone, or sys_unshare. As the network namespace is still experimental and under development clone and unshare support is only made available when CONFIG_NET_NS is selected at compile time. As this patch introduces network namespace support into code paths that exist when the CONFIG_NET is not selected there are a few additions made to net_namespace.h to allow a few more functions to be used when the networking stack is not compiled in. Signed-off-by: Eric W. Biederman Signed-off-by: David S. Miller --- include/linux/sched.h | 1 + include/net/net_namespace.h | 18 ++++++++++++++++++ kernel/fork.c | 3 ++- kernel/nsproxy.c | 15 +++++++++++++-- net/Kconfig | 8 ++++++++ net/core/net_namespace.c | 43 +++++++++++++++++++++++++++++++++++++++++-- 6 files changed, 83 insertions(+), 5 deletions(-) (limited to 'include/linux') diff --git a/include/linux/sched.h b/include/linux/sched.h index 313c6b6e774f..a4a141055c44 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -27,6 +27,7 @@ #define CLONE_NEWUTS 0x04000000 /* New utsname group? */ #define CLONE_NEWIPC 0x08000000 /* New ipcs */ #define CLONE_NEWUSER 0x10000000 /* New user namespace */ +#define CLONE_NEWNET 0x20000000 /* New network namespace */ /* * Scheduling policies diff --git a/include/net/net_namespace.h b/include/net/net_namespace.h index ac8f8304094e..3ea4194613ed 100644 --- a/include/net/net_namespace.h +++ b/include/net/net_namespace.h @@ -38,11 +38,23 @@ extern struct net init_net; extern struct list_head net_namespace_list; +#ifdef CONFIG_NET +extern struct net *copy_net_ns(unsigned long flags, struct net *net_ns); +#else +static inline struct net *copy_net_ns(unsigned long flags, struct net *net_ns) +{ + /* There is nothing to copy so this is a noop */ + return net_ns; +} +#endif + extern void __put_net(struct net *net); static inline struct net *get_net(struct net *net) { +#ifdef CONFIG_NET atomic_inc(&net->count); +#endif return net; } @@ -60,19 +72,25 @@ static inline struct net *maybe_get_net(struct net *net) static inline void put_net(struct net *net) { +#ifdef CONFIG_NET if (atomic_dec_and_test(&net->count)) __put_net(net); +#endif } static inline struct net *hold_net(struct net *net) { +#ifdef CONFIG_NET atomic_inc(&net->use_count); +#endif return net; } static inline void release_net(struct net *net) { +#ifdef CONFIG_NET atomic_dec(&net->use_count); +#endif } extern void net_lock(void); diff --git a/kernel/fork.c b/kernel/fork.c index 33f12f48684a..5e67f90a1694 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -1608,7 +1608,8 @@ asmlinkage long sys_unshare(unsigned long unshare_flags) err = -EINVAL; if (unshare_flags & ~(CLONE_THREAD|CLONE_FS|CLONE_NEWNS|CLONE_SIGHAND| CLONE_VM|CLONE_FILES|CLONE_SYSVSEM| - CLONE_NEWUTS|CLONE_NEWIPC|CLONE_NEWUSER)) + CLONE_NEWUTS|CLONE_NEWIPC|CLONE_NEWUSER| + CLONE_NEWNET)) goto bad_unshare_out; if ((err = unshare_thread(unshare_flags))) diff --git a/kernel/nsproxy.c b/kernel/nsproxy.c index a4fb7d46971f..f1decd21a534 100644 --- a/kernel/nsproxy.c +++ b/kernel/nsproxy.c @@ -20,6 +20,7 @@ #include #include #include +#include static struct kmem_cache *nsproxy_cachep; @@ -98,8 +99,17 @@ static struct nsproxy *create_new_namespaces(unsigned long flags, goto out_user; } + new_nsp->net_ns = copy_net_ns(flags, tsk->nsproxy->net_ns); + if (IS_ERR(new_nsp->net_ns)) { + err = PTR_ERR(new_nsp->net_ns); + goto out_net; + } + return new_nsp; +out_net: + if (new_nsp->user_ns) + put_user_ns(new_nsp->user_ns); out_user: if (new_nsp->pid_ns) put_pid_ns(new_nsp->pid_ns); @@ -132,7 +142,7 @@ int copy_namespaces(unsigned long flags, struct task_struct *tsk) get_nsproxy(old_ns); - if (!(flags & (CLONE_NEWNS | CLONE_NEWUTS | CLONE_NEWIPC | CLONE_NEWUSER))) + if (!(flags & (CLONE_NEWNS | CLONE_NEWUTS | CLONE_NEWIPC | CLONE_NEWUSER | CLONE_NEWNET))) return 0; if (!capable(CAP_SYS_ADMIN)) { @@ -164,6 +174,7 @@ void free_nsproxy(struct nsproxy *ns) put_pid_ns(ns->pid_ns); if (ns->user_ns) put_user_ns(ns->user_ns); + put_net(ns->net_ns); kmem_cache_free(nsproxy_cachep, ns); } @@ -177,7 +188,7 @@ int unshare_nsproxy_namespaces(unsigned long unshare_flags, int err = 0; if (!(unshare_flags & (CLONE_NEWNS | CLONE_NEWUTS | CLONE_NEWIPC | - CLONE_NEWUSER))) + CLONE_NEWUSER | CLONE_NEWNET))) return 0; if (!capable(CAP_SYS_ADMIN)) diff --git a/net/Kconfig b/net/Kconfig index cdba08ca2efe..ab4e6da5012f 100644 --- a/net/Kconfig +++ b/net/Kconfig @@ -27,6 +27,14 @@ if NET menu "Networking options" +config NET_NS + bool "Network namespace support" + default n + depends on EXPERIMENTAL && !SYSFS + help + Allow user space to create what appear to be multiple instances + of the network stack. + source "net/packet/Kconfig" source "net/unix/Kconfig" source "net/xfrm/Kconfig" diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c index 0e6cb02d7b77..e478e353ea6b 100644 --- a/net/core/net_namespace.c +++ b/net/core/net_namespace.c @@ -4,6 +4,7 @@ #include #include #include +#include #include /* @@ -32,12 +33,10 @@ void net_unlock(void) mutex_unlock(&net_list_mutex); } -#if 0 static struct net *net_alloc(void) { return kmem_cache_alloc(net_cachep, GFP_KERNEL); } -#endif static void net_free(struct net *net) { @@ -128,6 +127,46 @@ out_undo: goto out; } +struct net *copy_net_ns(unsigned long flags, struct net *old_net) +{ + struct net *new_net = NULL; + int err; + + get_net(old_net); + + if (!(flags & CLONE_NEWNET)) + return old_net; + +#ifndef CONFIG_NET_NS + return ERR_PTR(-EINVAL); +#endif + + err = -ENOMEM; + new_net = net_alloc(); + if (!new_net) + goto out; + + mutex_lock(&net_mutex); + err = setup_net(new_net); + if (err) + goto out_unlock; + + net_lock(); + list_add_tail(&new_net->list, &net_namespace_list); + net_unlock(); + + +out_unlock: + mutex_unlock(&net_mutex); +out: + put_net(old_net); + if (err) { + net_free(new_net); + new_net = ERR_PTR(err); + } + return new_net; +} + static int __init net_ns_init(void) { int err; -- cgit v1.2.3 From 2774c7aba6c97a2535be3309a2209770953780b3 Mon Sep 17 00:00:00 2001 From: "Eric W. Biederman" Date: Wed, 26 Sep 2007 22:10:56 -0700 Subject: [NET]: Make the loopback device per network namespace. This patch makes loopback_dev per network namespace. Adding code to create a different loopback device for each network namespace and adding the code to free a loopback device when a network namespace exits. This patch modifies all users the loopback_dev so they access it as init_net.loopback_dev, keeping all of the code compiling and working. A later pass will be needed to update the users to use something other than the initial network namespace. Signed-off-by: Eric W. Biederman Signed-off-by: David S. Miller --- drivers/net/loopback.c | 26 +++++++++++++++++++++----- include/linux/netdevice.h | 1 - include/net/net_namespace.h | 3 +++ net/core/dst.c | 5 +++-- net/decnet/dn_dev.c | 4 ++-- net/decnet/dn_route.c | 14 +++++++------- net/ipv4/route.c | 18 +++++++++--------- net/ipv4/xfrm4_policy.c | 2 +- net/ipv6/addrconf.c | 18 +++++++++--------- net/ipv6/netfilter/ip6t_REJECT.c | 2 +- net/ipv6/route.c | 12 ++++++------ net/ipv6/xfrm6_policy.c | 2 +- net/xfrm/xfrm_policy.c | 2 +- 13 files changed, 64 insertions(+), 45 deletions(-) (limited to 'include/linux') diff --git a/drivers/net/loopback.c b/drivers/net/loopback.c index f3018bb7570d..0f9d8c60c964 100644 --- a/drivers/net/loopback.c +++ b/drivers/net/loopback.c @@ -57,6 +57,7 @@ #include #include #include +#include struct pcpu_lstats { unsigned long packets; @@ -252,7 +253,7 @@ static void loopback_setup(struct net_device *dev) } /* Setup and register the loopback device. */ -static int __init loopback_init(void) +static int loopback_net_init(struct net *net) { struct net_device *dev; int err; @@ -262,12 +263,13 @@ static int __init loopback_init(void) if (!dev) goto out; + dev->nd_net = net; err = register_netdev(dev); if (err) goto out_free_netdev; err = 0; - loopback_dev = dev; + net->loopback_dev = dev; out: if (err) @@ -279,7 +281,21 @@ out_free_netdev: goto out; } -fs_initcall(loopback_init); +static void loopback_net_exit(struct net *net) +{ + struct net_device *dev = net->loopback_dev; + + unregister_netdev(dev); +} + +static struct pernet_operations loopback_net_ops = { + .init = loopback_net_init, + .exit = loopback_net_exit, +}; + +static int __init loopback_init(void) +{ + return register_pernet_device(&loopback_net_ops); +} -struct net_device *loopback_dev; -EXPORT_SYMBOL(loopback_dev); +fs_initcall(loopback_init); diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 2088097663b5..71cf409ad17e 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -742,7 +742,6 @@ struct packet_type { #include #include -extern struct net_device *loopback_dev; /* The loopback */ extern rwlock_t dev_base_lock; /* Device list lock */ diff --git a/include/net/net_namespace.h b/include/net/net_namespace.h index 3ea4194613ed..13b0e3b547f0 100644 --- a/include/net/net_namespace.h +++ b/include/net/net_namespace.h @@ -9,6 +9,7 @@ #include struct proc_dir_entry; +struct net_device; struct net { atomic_t count; /* To decided when the network * namespace should be freed. @@ -23,6 +24,8 @@ struct net { struct proc_dir_entry *proc_net_stat; struct proc_dir_entry *proc_net_root; + struct net_device *loopback_dev; /* The loopback */ + struct list_head dev_base_head; struct hlist_head *dev_name_head; struct hlist_head *dev_index_head; diff --git a/net/core/dst.c b/net/core/dst.c index ad5ffa19d809..16958e64e577 100644 --- a/net/core/dst.c +++ b/net/core/dst.c @@ -18,6 +18,7 @@ #include #include +#include #include /* @@ -278,11 +279,11 @@ static inline void dst_ifdown(struct dst_entry *dst, struct net_device *dev, if (!unregister) { dst->input = dst->output = dst_discard; } else { - dst->dev = loopback_dev; + dst->dev = init_net.loopback_dev; dev_hold(dst->dev); dev_put(dev); if (dst->neighbour && dst->neighbour->dev == dev) { - dst->neighbour->dev = loopback_dev; + dst->neighbour->dev = init_net.loopback_dev; dev_put(dev); dev_hold(dst->neighbour->dev); } diff --git a/net/decnet/dn_dev.c b/net/decnet/dn_dev.c index bcaf4c5aa68e..26130afd8029 100644 --- a/net/decnet/dn_dev.c +++ b/net/decnet/dn_dev.c @@ -869,10 +869,10 @@ last_chance: rv = dn_dev_get_first(dev, addr); read_unlock(&dev_base_lock); dev_put(dev); - if (rv == 0 || dev == loopback_dev) + if (rv == 0 || dev == init_net.loopback_dev) return rv; } - dev = loopback_dev; + dev = init_net.loopback_dev; dev_hold(dev); goto last_chance; } diff --git a/net/decnet/dn_route.c b/net/decnet/dn_route.c index 96fe0aa1638e..b7ebf9947ebd 100644 --- a/net/decnet/dn_route.c +++ b/net/decnet/dn_route.c @@ -887,7 +887,7 @@ static int dn_route_output_slow(struct dst_entry **pprt, const struct flowi *old .scope = RT_SCOPE_UNIVERSE, } }, .mark = oldflp->mark, - .iif = loopback_dev->ifindex, + .iif = init_net.loopback_dev->ifindex, .oif = oldflp->oif }; struct dn_route *rt = NULL; struct net_device *dev_out = NULL, *dev; @@ -904,7 +904,7 @@ static int dn_route_output_slow(struct dst_entry **pprt, const struct flowi *old "dn_route_output_slow: dst=%04x src=%04x mark=%d" " iif=%d oif=%d\n", dn_ntohs(oldflp->fld_dst), dn_ntohs(oldflp->fld_src), - oldflp->mark, loopback_dev->ifindex, oldflp->oif); + oldflp->mark, init_net.loopback_dev->ifindex, oldflp->oif); /* If we have an output interface, verify its a DECnet device */ if (oldflp->oif) { @@ -957,7 +957,7 @@ source_ok: err = -EADDRNOTAVAIL; if (dev_out) dev_put(dev_out); - dev_out = loopback_dev; + dev_out = init_net.loopback_dev; dev_hold(dev_out); if (!fl.fld_dst) { fl.fld_dst = @@ -966,7 +966,7 @@ source_ok: if (!fl.fld_dst) goto out; } - fl.oif = loopback_dev->ifindex; + fl.oif = init_net.loopback_dev->ifindex; res.type = RTN_LOCAL; goto make_route; } @@ -1012,7 +1012,7 @@ source_ok: if (dev_out) dev_put(dev_out); if (dn_dev_islocal(neigh->dev, fl.fld_dst)) { - dev_out = loopback_dev; + dev_out = init_net.loopback_dev; res.type = RTN_LOCAL; } else { dev_out = neigh->dev; @@ -1033,7 +1033,7 @@ source_ok: /* Possible improvement - check all devices for local addr */ if (dn_dev_islocal(dev_out, fl.fld_dst)) { dev_put(dev_out); - dev_out = loopback_dev; + dev_out = init_net.loopback_dev; dev_hold(dev_out); res.type = RTN_LOCAL; goto select_source; @@ -1069,7 +1069,7 @@ select_source: fl.fld_src = fl.fld_dst; if (dev_out) dev_put(dev_out); - dev_out = loopback_dev; + dev_out = init_net.loopback_dev; dev_hold(dev_out); fl.oif = dev_out->ifindex; if (res.fi) diff --git a/net/ipv4/route.c b/net/ipv4/route.c index ca2878dc6188..2a9b363e820c 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -1402,8 +1402,8 @@ static void ipv4_dst_ifdown(struct dst_entry *dst, struct net_device *dev, { struct rtable *rt = (struct rtable *) dst; struct in_device *idev = rt->idev; - if (dev != loopback_dev && idev && idev->dev == dev) { - struct in_device *loopback_idev = in_dev_get(loopback_dev); + if (dev != init_net.loopback_dev && idev && idev->dev == dev) { + struct in_device *loopback_idev = in_dev_get(init_net.loopback_dev); if (loopback_idev) { rt->idev = loopback_idev; in_dev_put(idev); @@ -1555,7 +1555,7 @@ static int ip_route_input_mc(struct sk_buff *skb, __be32 daddr, __be32 saddr, #endif rth->rt_iif = rth->fl.iif = dev->ifindex; - rth->u.dst.dev = loopback_dev; + rth->u.dst.dev = init_net.loopback_dev; dev_hold(rth->u.dst.dev); rth->idev = in_dev_get(rth->u.dst.dev); rth->fl.oif = 0; @@ -1812,7 +1812,7 @@ static int ip_route_input_slow(struct sk_buff *skb, __be32 daddr, __be32 saddr, if (res.type == RTN_LOCAL) { int result; result = fib_validate_source(saddr, daddr, tos, - loopback_dev->ifindex, + init_net.loopback_dev->ifindex, dev, &spec_dst, &itag); if (result < 0) goto martian_source; @@ -1879,7 +1879,7 @@ local_input: #endif rth->rt_iif = rth->fl.iif = dev->ifindex; - rth->u.dst.dev = loopback_dev; + rth->u.dst.dev = init_net.loopback_dev; dev_hold(rth->u.dst.dev); rth->idev = in_dev_get(rth->u.dst.dev); rth->rt_gateway = daddr; @@ -2149,7 +2149,7 @@ static int ip_route_output_slow(struct rtable **rp, const struct flowi *oldflp) RT_SCOPE_UNIVERSE), } }, .mark = oldflp->mark, - .iif = loopback_dev->ifindex, + .iif = init_net.loopback_dev->ifindex, .oif = oldflp->oif }; struct fib_result res; unsigned flags = 0; @@ -2243,9 +2243,9 @@ static int ip_route_output_slow(struct rtable **rp, const struct flowi *oldflp) fl.fl4_dst = fl.fl4_src = htonl(INADDR_LOOPBACK); if (dev_out) dev_put(dev_out); - dev_out = loopback_dev; + dev_out = init_net.loopback_dev; dev_hold(dev_out); - fl.oif = loopback_dev->ifindex; + fl.oif = init_net.loopback_dev->ifindex; res.type = RTN_LOCAL; flags |= RTCF_LOCAL; goto make_route; @@ -2290,7 +2290,7 @@ static int ip_route_output_slow(struct rtable **rp, const struct flowi *oldflp) fl.fl4_src = fl.fl4_dst; if (dev_out) dev_put(dev_out); - dev_out = loopback_dev; + dev_out = init_net.loopback_dev; dev_hold(dev_out); fl.oif = dev_out->ifindex; if (res.fi) diff --git a/net/ipv4/xfrm4_policy.c b/net/ipv4/xfrm4_policy.c index 29ab3de8c47f..329825ca68fe 100644 --- a/net/ipv4/xfrm4_policy.c +++ b/net/ipv4/xfrm4_policy.c @@ -306,7 +306,7 @@ static void xfrm4_dst_ifdown(struct dst_entry *dst, struct net_device *dev, xdst = (struct xfrm_dst *)dst; if (xdst->u.rt.idev->dev == dev) { - struct in_device *loopback_idev = in_dev_get(loopback_dev); + struct in_device *loopback_idev = in_dev_get(init_net.loopback_dev); BUG_ON(!loopback_idev); do { diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index b43574f73375..6d5c3c299148 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -2410,7 +2410,7 @@ static int addrconf_ifdown(struct net_device *dev, int how) ASSERT_RTNL(); - if (dev == loopback_dev && how == 1) + if (dev == init_net.loopback_dev && how == 1) how = 0; rt6_ifdown(dev); @@ -4212,19 +4212,19 @@ int __init addrconf_init(void) * device and it being up should be removed. */ rtnl_lock(); - if (!ipv6_add_dev(loopback_dev)) + if (!ipv6_add_dev(init_net.loopback_dev)) err = -ENOMEM; rtnl_unlock(); if (err) return err; - ip6_null_entry.u.dst.dev = loopback_dev; - ip6_null_entry.rt6i_idev = in6_dev_get(loopback_dev); + ip6_null_entry.u.dst.dev = init_net.loopback_dev; + ip6_null_entry.rt6i_idev = in6_dev_get(init_net.loopback_dev); #ifdef CONFIG_IPV6_MULTIPLE_TABLES - ip6_prohibit_entry.u.dst.dev = loopback_dev; - ip6_prohibit_entry.rt6i_idev = in6_dev_get(loopback_dev); - ip6_blk_hole_entry.u.dst.dev = loopback_dev; - ip6_blk_hole_entry.rt6i_idev = in6_dev_get(loopback_dev); + ip6_prohibit_entry.u.dst.dev = init_net.loopback_dev; + ip6_prohibit_entry.rt6i_idev = in6_dev_get(init_net.loopback_dev); + ip6_blk_hole_entry.u.dst.dev = init_net.loopback_dev; + ip6_blk_hole_entry.rt6i_idev = in6_dev_get(init_net.loopback_dev); #endif register_netdevice_notifier(&ipv6_dev_notf); @@ -4279,7 +4279,7 @@ void __exit addrconf_cleanup(void) continue; addrconf_ifdown(dev, 1); } - addrconf_ifdown(loopback_dev, 2); + addrconf_ifdown(init_net.loopback_dev, 2); /* * Check hash table. diff --git a/net/ipv6/netfilter/ip6t_REJECT.c b/net/ipv6/netfilter/ip6t_REJECT.c index 50860531cd3c..3fd08d5567a6 100644 --- a/net/ipv6/netfilter/ip6t_REJECT.c +++ b/net/ipv6/netfilter/ip6t_REJECT.c @@ -167,7 +167,7 @@ static inline void send_unreach(struct sk_buff *skb_in, unsigned char code, unsigned int hooknum) { if (hooknum == NF_IP6_LOCAL_OUT && skb_in->dev == NULL) - skb_in->dev = loopback_dev; + skb_in->dev = init_net.loopback_dev; icmpv6_send(skb_in, ICMPV6_DEST_UNREACH, code, 0, NULL); } diff --git a/net/ipv6/route.c b/net/ipv6/route.c index a7a21a7ba790..6ff19f9eb9ee 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c @@ -221,8 +221,8 @@ static void ip6_dst_ifdown(struct dst_entry *dst, struct net_device *dev, struct rt6_info *rt = (struct rt6_info *)dst; struct inet6_dev *idev = rt->rt6i_idev; - if (dev != loopback_dev && idev != NULL && idev->dev == dev) { - struct inet6_dev *loopback_idev = in6_dev_get(loopback_dev); + if (dev != init_net.loopback_dev && idev != NULL && idev->dev == dev) { + struct inet6_dev *loopback_idev = in6_dev_get(init_net.loopback_dev); if (loopback_idev != NULL) { rt->rt6i_idev = loopback_idev; in6_dev_put(idev); @@ -1185,12 +1185,12 @@ int ip6_route_add(struct fib6_config *cfg) if ((cfg->fc_flags & RTF_REJECT) || (dev && (dev->flags&IFF_LOOPBACK) && !(addr_type&IPV6_ADDR_LOOPBACK))) { /* hold loopback dev/idev if we haven't done so. */ - if (dev != loopback_dev) { + if (dev != init_net.loopback_dev) { if (dev) { dev_put(dev); in6_dev_put(idev); } - dev = loopback_dev; + dev = init_net.loopback_dev; dev_hold(dev); idev = in6_dev_get(dev); if (!idev) { @@ -1894,13 +1894,13 @@ struct rt6_info *addrconf_dst_alloc(struct inet6_dev *idev, if (rt == NULL) return ERR_PTR(-ENOMEM); - dev_hold(loopback_dev); + dev_hold(init_net.loopback_dev); in6_dev_hold(idev); rt->u.dst.flags = DST_HOST; rt->u.dst.input = ip6_input; rt->u.dst.output = ip6_output; - rt->rt6i_dev = loopback_dev; + rt->rt6i_dev = init_net.loopback_dev; rt->rt6i_idev = idev; rt->u.dst.metrics[RTAX_MTU-1] = ipv6_get_mtu(rt->rt6i_dev); rt->u.dst.metrics[RTAX_ADVMSS-1] = ipv6_advmss(dst_mtu(&rt->u.dst)); diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c index cc07216cfd59..15aa4c58c315 100644 --- a/net/ipv6/xfrm6_policy.c +++ b/net/ipv6/xfrm6_policy.c @@ -375,7 +375,7 @@ static void xfrm6_dst_ifdown(struct dst_entry *dst, struct net_device *dev, xdst = (struct xfrm_dst *)dst; if (xdst->u.rt6.rt6i_idev->dev == dev) { - struct inet6_dev *loopback_idev = in6_dev_get(loopback_dev); + struct inet6_dev *loopback_idev = in6_dev_get(init_net.loopback_dev); BUG_ON(!loopback_idev); do { diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index d6dfd7d1948f..76f172f13f90 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c @@ -1949,7 +1949,7 @@ static int stale_bundle(struct dst_entry *dst) void xfrm_dst_ifdown(struct dst_entry *dst, struct net_device *dev) { while ((dst = dst->child) && dst->xfrm && dst->dev == dev) { - dst->dev = loopback_dev; + dst->dev = init_net.loopback_dev; dev_hold(dst->dev); dev_put(dev); } -- cgit v1.2.3 From 0c4e85813d0a94eeb8bf813397a4907bdd7bb610 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Tue, 9 Oct 2007 01:36:32 -0700 Subject: [NET]: Wrap netdevice hardware header creation. Add inline for common usage of hardware header creation, and fix bug in IPV6 mcast where the assumption about negative return is an errno. Negative return from hard_header means not enough space was available,(ie -N bytes). Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- drivers/net/hamradio/bpqether.c | 2 +- drivers/net/macvlan.c | 4 ++-- drivers/net/pppoe.c | 8 ++++---- drivers/net/wan/lapbether.c | 2 +- include/linux/netdevice.h | 9 +++++++++ include/net/dn_route.h | 3 +-- net/802/p8023.c | 2 +- net/8021q/vlan_dev.c | 14 ++++++-------- net/core/neighbour.c | 17 ++++++++--------- net/core/netpoll.c | 8 +++----- net/decnet/dn_neigh.c | 3 ++- net/econet/af_econet.c | 14 +++++++------- net/ethernet/pe2.c | 4 +--- net/ipv4/arp.c | 3 +-- net/ipv4/ipconfig.c | 4 ++-- net/ipv6/mcast.c | 15 +++++---------- net/packet/af_packet.c | 14 ++++---------- net/sched/sch_teql.c | 5 ++++- net/tipc/eth_media.c | 2 +- 19 files changed, 63 insertions(+), 70 deletions(-) (limited to 'include/linux') diff --git a/drivers/net/hamradio/bpqether.c b/drivers/net/hamradio/bpqether.c index c05bc37df356..4bff23e3b970 100644 --- a/drivers/net/hamradio/bpqether.c +++ b/drivers/net/hamradio/bpqether.c @@ -286,7 +286,7 @@ static int bpq_xmit(struct sk_buff *skb, struct net_device *dev) skb->protocol = ax25_type_trans(skb, dev); skb_reset_network_header(skb); - dev->hard_header(skb, dev, ETH_P_BPQ, bpq->dest_addr, NULL, 0); + dev_hard_header(skb, dev, ETH_P_BPQ, bpq->dest_addr, NULL, 0); bpq->stats.tx_packets++; bpq->stats.tx_bytes+=skb->len; diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c index 2f6cdaa88729..a22087ca968d 100644 --- a/drivers/net/macvlan.c +++ b/drivers/net/macvlan.c @@ -170,8 +170,8 @@ static int macvlan_hard_header(struct sk_buff *skb, struct net_device *dev, const struct macvlan_dev *vlan = netdev_priv(dev); struct net_device *lowerdev = vlan->lowerdev; - return lowerdev->hard_header(skb, lowerdev, type, daddr, - saddr ? : dev->dev_addr, len); + return dev_hard_header(skb, lowerdev, type, daddr, + saddr ? : dev->dev_addr, len); } static int macvlan_open(struct net_device *dev) diff --git a/drivers/net/pppoe.c b/drivers/net/pppoe.c index d48b7b73d896..8936ed3469cf 100644 --- a/drivers/net/pppoe.c +++ b/drivers/net/pppoe.c @@ -834,8 +834,8 @@ static int pppoe_sendmsg(struct kiocb *iocb, struct socket *sock, } error = total_len; - dev->hard_header(skb, dev, ETH_P_PPP_SES, - po->pppoe_pa.remote, NULL, total_len); + dev_hard_header(skb, dev, ETH_P_PPP_SES, + po->pppoe_pa.remote, NULL, total_len); memcpy(ph, &hdr, sizeof(struct pppoe_hdr)); @@ -886,8 +886,8 @@ static int __pppoe_xmit(struct sock *sk, struct sk_buff *skb) skb->protocol = __constant_htons(ETH_P_PPP_SES); skb->dev = dev; - dev->hard_header(skb, dev, ETH_P_PPP_SES, - po->pppoe_pa.remote, NULL, data_len); + dev_hard_header(skb, dev, ETH_P_PPP_SES, + po->pppoe_pa.remote, NULL, data_len); dev_queue_xmit(skb); diff --git a/drivers/net/wan/lapbether.c b/drivers/net/wan/lapbether.c index 36e683ccae5e..fb37b8095231 100644 --- a/drivers/net/wan/lapbether.c +++ b/drivers/net/wan/lapbether.c @@ -216,7 +216,7 @@ static void lapbeth_data_transmit(struct net_device *ndev, struct sk_buff *skb) skb->dev = dev = lapbeth->ethdev; - dev->hard_header(skb, dev, ETH_P_DEC, bcast_addr, NULL, 0); + dev_hard_header(skb, dev, ETH_P_DEC, bcast_addr, NULL, 0); dev_queue_xmit(skb); } diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 71cf409ad17e..b33d084712fa 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -800,6 +800,15 @@ extern int dev_restart(struct net_device *dev); extern int netpoll_trap(void); #endif +static inline int dev_hard_header(struct sk_buff *skb, struct net_device *dev, + unsigned short type, + void *daddr, void *saddr, unsigned len) +{ + if (!dev->hard_header) + return 0; + return dev->hard_header(skb, dev, type, daddr, saddr, len); +} + typedef int gifconf_func_t(struct net_device * dev, char __user * bufptr, int len); extern int register_gifconf(unsigned int family, gifconf_func_t * gifconf); static inline int unregister_gifconf(unsigned int family) diff --git a/include/net/dn_route.h b/include/net/dn_route.h index c10e8e7e59a7..60c9f22d8694 100644 --- a/include/net/dn_route.h +++ b/include/net/dn_route.h @@ -100,8 +100,7 @@ static inline void dn_rt_finish_output(struct sk_buff *skb, char *dst, char *src if ((dev->type != ARPHRD_ETHER) && (dev->type != ARPHRD_LOOPBACK)) dst = NULL; - if (!dev->hard_header || (dev->hard_header(skb, dev, ETH_P_DNA_RT, - dst, src, skb->len) >= 0)) + if (dev_hard_header(skb, dev, ETH_P_DNA_RT, dst, src, skb->len) >= 0) dn_rt_send(skb); else kfree_skb(skb); diff --git a/net/802/p8023.c b/net/802/p8023.c index 53cf05709283..6ab1835041a7 100644 --- a/net/802/p8023.c +++ b/net/802/p8023.c @@ -31,7 +31,7 @@ static int p8023_request(struct datalink_proto *dl, { struct net_device *dev = skb->dev; - dev->hard_header(skb, dev, ETH_P_802_3, dest_node, NULL, skb->len); + dev_hard_header(skb, dev, ETH_P_802_3, dest_node, NULL, skb->len); return dev_queue_xmit(skb); } diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c index 6644e8f5f199..ca8090fdabbb 100644 --- a/net/8021q/vlan_dev.c +++ b/net/8021q/vlan_dev.c @@ -434,21 +434,19 @@ int vlan_dev_hard_header(struct sk_buff *skb, struct net_device *dev, if (build_vlan_header) { /* Now make the underlying real hard header */ - rc = dev->hard_header(skb, dev, ETH_P_8021Q, daddr, saddr, len + VLAN_HLEN); - - if (rc > 0) { + rc = dev_hard_header(skb, dev, ETH_P_8021Q, daddr, saddr, + len + VLAN_HLEN); + if (rc > 0) rc += VLAN_HLEN; - } else if (rc < 0) { + else if (rc < 0) rc -= VLAN_HLEN; - } - } else { + } else /* If here, then we'll just make a normal looking ethernet frame, * but, the hard_start_xmit method will insert the tag (it has to * be able to do this for bridged and other skbs that don't come * down the protocol stack in an orderly manner. */ - rc = dev->hard_header(skb, dev, type, daddr, saddr, len); - } + rc = dev_hard_header(skb, dev, type, daddr, saddr, len); return rc; } diff --git a/net/core/neighbour.c b/net/core/neighbour.c index 2c6577c1eedd..10bcb9f8da5c 100644 --- a/net/core/neighbour.c +++ b/net/core/neighbour.c @@ -1125,9 +1125,8 @@ int neigh_compat_output(struct sk_buff *skb) __skb_pull(skb, skb_network_offset(skb)); - if (dev->hard_header && - dev->hard_header(skb, dev, ntohs(skb->protocol), NULL, NULL, - skb->len) < 0 && + if (dev_hard_header(skb, dev, ntohs(skb->protocol), NULL, NULL, + skb->len) < 0 && dev->rebuild_header(skb)) return 0; @@ -1154,13 +1153,13 @@ int neigh_resolve_output(struct sk_buff *skb) write_lock_bh(&neigh->lock); if (!dst->hh) neigh_hh_init(neigh, dst, dst->ops->protocol); - err = dev->hard_header(skb, dev, ntohs(skb->protocol), - neigh->ha, NULL, skb->len); + err = dev_hard_header(skb, dev, ntohs(skb->protocol), + neigh->ha, NULL, skb->len); write_unlock_bh(&neigh->lock); } else { read_lock_bh(&neigh->lock); - err = dev->hard_header(skb, dev, ntohs(skb->protocol), - neigh->ha, NULL, skb->len); + err = dev_hard_header(skb, dev, ntohs(skb->protocol), + neigh->ha, NULL, skb->len); read_unlock_bh(&neigh->lock); } if (err >= 0) @@ -1191,8 +1190,8 @@ int neigh_connected_output(struct sk_buff *skb) __skb_pull(skb, skb_network_offset(skb)); read_lock_bh(&neigh->lock); - err = dev->hard_header(skb, dev, ntohs(skb->protocol), - neigh->ha, NULL, skb->len); + err = dev_hard_header(skb, dev, ntohs(skb->protocol), + neigh->ha, NULL, skb->len); read_unlock_bh(&neigh->lock); if (err >= 0) err = neigh->ops->queue_xmit(skb); diff --git a/net/core/netpoll.c b/net/core/netpoll.c index e13602d8154d..95daba624967 100644 --- a/net/core/netpoll.c +++ b/net/core/netpoll.c @@ -415,11 +415,9 @@ static void arp_reply(struct sk_buff *skb) send_skb->protocol = htons(ETH_P_ARP); /* Fill the device header for the ARP frame */ - - if (np->dev->hard_header && - np->dev->hard_header(send_skb, skb->dev, ptype, - sha, np->local_mac, - send_skb->len) < 0) { + if (dev_hard_header(send_skb, skb->dev, ptype, + sha, np->local_mac, + send_skb->len) < 0) { kfree_skb(send_skb); return; } diff --git a/net/decnet/dn_neigh.c b/net/decnet/dn_neigh.c index a424a8ddbaf7..b66e3be3eb84 100644 --- a/net/decnet/dn_neigh.c +++ b/net/decnet/dn_neigh.c @@ -211,7 +211,8 @@ static int dn_neigh_output_packet(struct sk_buff *skb) char mac_addr[ETH_ALEN]; dn_dn2eth(mac_addr, rt->rt_local_src); - if (!dev->hard_header || dev->hard_header(skb, dev, ntohs(skb->protocol), neigh->ha, mac_addr, skb->len) >= 0) + if (dev_hard_header(skb, dev, ntohs(skb->protocol), neigh->ha, + mac_addr, skb->len) >= 0) return neigh->ops->queue_xmit(skb); if (net_ratelimit()) diff --git a/net/econet/af_econet.c b/net/econet/af_econet.c index 9938e76a8ff6..9cae16b4e0b7 100644 --- a/net/econet/af_econet.c +++ b/net/econet/af_econet.c @@ -336,6 +336,7 @@ static int econet_sendmsg(struct kiocb *iocb, struct socket *sock, /* Real hardware Econet. We're not worthy etc. */ #ifdef CONFIG_ECONET_NATIVE unsigned short proto = 0; + int res; dev_hold(dev); @@ -354,12 +355,12 @@ static int econet_sendmsg(struct kiocb *iocb, struct socket *sock, eb->sec = *saddr; eb->sent = ec_tx_done; - if (dev->hard_header) { - int res; + err = -EINVAL; + res = dev_hard_header(skb, dev, ntohs(proto), &addr, NULL, len); + if (res < 0) + goto out_free; + if (res > 0) { struct ec_framehdr *fh; - err = -EINVAL; - res = dev->hard_header(skb, dev, ntohs(proto), - &addr, NULL, len); /* Poke in our control byte and port number. Hack, hack. */ fh = (struct ec_framehdr *)(skb->data); @@ -368,8 +369,7 @@ static int econet_sendmsg(struct kiocb *iocb, struct socket *sock, if (sock->type != SOCK_DGRAM) { skb_reset_tail_pointer(skb); skb->len = 0; - } else if (res < 0) - goto out_free; + } } /* Copy the data. Returns -EFAULT on error */ diff --git a/net/ethernet/pe2.c b/net/ethernet/pe2.c index 9d57b4fb6440..d60e15d9365e 100644 --- a/net/ethernet/pe2.c +++ b/net/ethernet/pe2.c @@ -12,9 +12,7 @@ static int pEII_request(struct datalink_proto *dl, struct net_device *dev = skb->dev; skb->protocol = htons(ETH_P_IPX); - if (dev->hard_header) - dev->hard_header(skb, dev, ETH_P_IPX, - dest_node, NULL, skb->len); + dev_hard_header(skb, dev, ETH_P_IPX, dest_node, NULL, skb->len); return dev_queue_xmit(skb); } diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c index 3a683006d761..5b24c65b13c6 100644 --- a/net/ipv4/arp.c +++ b/net/ipv4/arp.c @@ -591,8 +591,7 @@ struct sk_buff *arp_create(int type, int ptype, __be32 dest_ip, /* * Fill the device header for the ARP frame */ - if (dev->hard_header && - dev->hard_header(skb,dev,ptype,dest_hw,src_hw,skb->len) < 0) + if (dev_hard_header(skb, dev, ptype, dest_hw, src_hw, skb->len) < 0) goto out; /* diff --git a/net/ipv4/ipconfig.c b/net/ipv4/ipconfig.c index af5d5b39fc13..c5c107a01823 100644 --- a/net/ipv4/ipconfig.c +++ b/net/ipv4/ipconfig.c @@ -757,8 +757,8 @@ static void __init ic_bootp_send_if(struct ic_device *d, unsigned long jiffies_d /* Chain packet down the line... */ skb->dev = dev; skb->protocol = htons(ETH_P_IP); - if ((dev->hard_header && - dev->hard_header(skb, dev, ntohs(skb->protocol), dev->broadcast, dev->dev_addr, skb->len) < 0) || + if (dev_hard_header(skb, dev, ntohs(skb->protocol), + dev->broadcast, dev->dev_addr, skb->len) < 0 || dev_queue_xmit(skb) < 0) printk("E"); } diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c index 86d908b1caea..8668ab3af32e 100644 --- a/net/ipv6/mcast.c +++ b/net/ipv6/mcast.c @@ -1438,17 +1438,12 @@ static struct sk_buff *mld_newpack(struct net_device *dev, int size) static inline int mld_dev_queue_xmit2(struct sk_buff *skb) { struct net_device *dev = skb->dev; + unsigned char ha[MAX_ADDR_LEN]; - if (dev->hard_header) { - unsigned char ha[MAX_ADDR_LEN]; - int err; - - ndisc_mc_map(&ipv6_hdr(skb)->daddr, ha, dev, 1); - err = dev->hard_header(skb, dev, ETH_P_IPV6, ha, NULL, skb->len); - if (err < 0) { - kfree_skb(skb); - return err; - } + ndisc_mc_map(&ipv6_hdr(skb)->daddr, ha, dev, 1); + if (dev_hard_header(skb, dev, ETH_P_IPV6, ha, NULL, skb->len) < 0) { + kfree_skb(skb); + return -EINVAL; } return dev_queue_xmit(skb); } diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c index 745e2cb87c96..c5244b309640 100644 --- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c @@ -765,16 +765,10 @@ static int packet_sendmsg(struct kiocb *iocb, struct socket *sock, skb_reserve(skb, LL_RESERVED_SPACE(dev)); skb_reset_network_header(skb); - if (dev->hard_header) { - int res; - err = -EINVAL; - res = dev->hard_header(skb, dev, ntohs(proto), addr, NULL, len); - if (sock->type != SOCK_DGRAM) { - skb_reset_tail_pointer(skb); - skb->len = 0; - } else if (res < 0) - goto out_free; - } + err = -EINVAL; + if (sock->type == SOCK_DGRAM && + dev_hard_header(skb, dev, ntohs(proto), addr, NULL, len) < 0) + goto out_free; /* Returns -EFAULT on error */ err = memcpy_fromiovec(skb_put(skb,len), msg->msg_iov, len); diff --git a/net/sched/sch_teql.c b/net/sched/sch_teql.c index 146f453d7378..d13970f3c7b1 100644 --- a/net/sched/sch_teql.c +++ b/net/sched/sch_teql.c @@ -232,9 +232,12 @@ __teql_resolve(struct sk_buff *skb, struct sk_buff *skb_res, struct net_device * } if (neigh_event_send(n, skb_res) == 0) { int err; + read_lock(&n->lock); - err = dev->hard_header(skb, dev, ntohs(skb->protocol), n->ha, NULL, skb->len); + err = dev_hard_header(skb, dev, ntohs(skb->protocol), + n->ha, NULL, skb->len); read_unlock(&n->lock); + if (err < 0) { neigh_release(n); return -EINVAL; diff --git a/net/tipc/eth_media.c b/net/tipc/eth_media.c index 1a99e2947145..3bbef2ab22ae 100644 --- a/net/tipc/eth_media.c +++ b/net/tipc/eth_media.c @@ -77,7 +77,7 @@ static int send_msg(struct sk_buff *buf, struct tipc_bearer *tb_ptr, skb_reset_network_header(clone); dev = ((struct eth_bearer *)(tb_ptr->usr_handle))->dev; clone->dev = dev; - dev->hard_header(clone, dev, ETH_P_TIPC, + dev_hard_header(clone, dev, ETH_P_TIPC, &dest->dev_addr.eth_addr, dev->dev_addr, clone->len); dev_queue_xmit(clone); -- cgit v1.2.3 From b95cce3576813ac3f86bafa6b5daaaaf7574b0fe Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Wed, 26 Sep 2007 22:13:38 -0700 Subject: [NET]: Wrap hard_header_parse Wrap the hard_header_parse function to simplify next step of header_ops conversion. Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- drivers/ieee1394/eth1394.c | 10 +++++----- drivers/net/wireless/airo.c | 7 +------ drivers/s390/net/qeth_main.c | 6 +++--- include/linux/netdevice.h | 12 +++++++++++- net/ethernet/eth.c | 4 ++-- net/ipv4/netfilter/ip_queue.c | 6 ++---- net/ipv6/netfilter/ip6_queue.c | 5 +---- net/mac80211/ieee80211.c | 2 +- net/netfilter/nfnetlink_log.c | 11 ++++++----- net/netfilter/nfnetlink_queue.c | 13 ++++++------- net/packet/af_packet.c | 8 ++------ 11 files changed, 40 insertions(+), 44 deletions(-) (limited to 'include/linux') diff --git a/drivers/ieee1394/eth1394.c b/drivers/ieee1394/eth1394.c index 33b80817d68c..b31f90082e35 100644 --- a/drivers/ieee1394/eth1394.c +++ b/drivers/ieee1394/eth1394.c @@ -162,7 +162,8 @@ static int ether1394_header(struct sk_buff *skb, struct net_device *dev, unsigned short type, void *daddr, void *saddr, unsigned len); static int ether1394_rebuild_header(struct sk_buff *skb); -static int ether1394_header_parse(struct sk_buff *skb, unsigned char *haddr); +static int ether1394_header_parse(const struct sk_buff *skb, + unsigned char *haddr); static int ether1394_header_cache(struct neighbour *neigh, struct hh_cache *hh); static void ether1394_header_cache_update(struct hh_cache *hh, struct net_device *dev, @@ -751,11 +752,10 @@ static int ether1394_rebuild_header(struct sk_buff *skb) return 0; } -static int ether1394_header_parse(struct sk_buff *skb, unsigned char *haddr) +static int ether1394_header_parse(const struct sk_buff *skb, + unsigned char *haddr) { - struct net_device *dev = skb->dev; - - memcpy(haddr, dev->dev_addr, ETH1394_ALEN); + memcpy(haddr, skb->dev->dev_addr, ETH1394_ALEN); return ETH1394_ALEN; } diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c index 95d3cd1c49a7..cd03a61359aa 100644 --- a/drivers/net/wireless/airo.c +++ b/drivers/net/wireless/airo.c @@ -2481,7 +2481,7 @@ void stop_airo_card( struct net_device *dev, int freeres ) EXPORT_SYMBOL(stop_airo_card); -static int wll_header_parse(struct sk_buff *skb, unsigned char *haddr) +static int wll_header_parse(const struct sk_buff *skb, unsigned char *haddr) { memcpy(haddr, skb_mac_header(skb) + 10, ETH_ALEN); return ETH_ALEN; @@ -2698,11 +2698,6 @@ static int mpi_map_card(struct airo_info *ai, struct pci_dev *pci) static void wifi_setup(struct net_device *dev) { - dev->hard_header = NULL; - dev->rebuild_header = NULL; - dev->hard_header_cache = NULL; - dev->header_cache_update= NULL; - dev->hard_header_parse = wll_header_parse; dev->hard_start_xmit = &airo_start_xmit11; dev->get_stats = &airo_get_stats; diff --git a/drivers/s390/net/qeth_main.c b/drivers/s390/net/qeth_main.c index 8c46978e0afa..65225b3989dd 100644 --- a/drivers/s390/net/qeth_main.c +++ b/drivers/s390/net/qeth_main.c @@ -6561,10 +6561,10 @@ static struct ethtool_ops qeth_ethtool_ops = { }; static int -qeth_hard_header_parse(struct sk_buff *skb, unsigned char *haddr) +qeth_hard_header_parse(const struct sk_buff *skb, unsigned char *haddr) { - struct qeth_card *card; - struct ethhdr *eth; + const struct qeth_card *card; + const struct ethhdr *eth; card = qeth_get_card_from_dev(skb->dev); if (card->options.layer2) diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index b33d084712fa..aae9ec367f5d 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -657,7 +657,7 @@ struct net_device void (*vlan_rx_kill_vid)(struct net_device *dev, unsigned short vid); - int (*hard_header_parse)(struct sk_buff *skb, + int (*hard_header_parse)(const struct sk_buff *skb, unsigned char *haddr); int (*neigh_setup)(struct net_device *dev, struct neigh_parms *); #ifdef CONFIG_NETPOLL @@ -809,6 +809,16 @@ static inline int dev_hard_header(struct sk_buff *skb, struct net_device *dev, return dev->hard_header(skb, dev, type, daddr, saddr, len); } +static inline int dev_parse_header(const struct sk_buff *skb, + unsigned char *haddr) +{ + const struct net_device *dev = skb->dev; + + if (!dev->hard_header_parse) + return 0; + return dev->hard_header_parse(skb, haddr); +} + typedef int gifconf_func_t(struct net_device * dev, char __user * bufptr, int len); extern int register_gifconf(unsigned int family, gifconf_func_t * gifconf); static inline int unregister_gifconf(unsigned int family) diff --git a/net/ethernet/eth.c b/net/ethernet/eth.c index 2aaf6faf74ac..bdeb2f0ace32 100644 --- a/net/ethernet/eth.c +++ b/net/ethernet/eth.c @@ -207,9 +207,9 @@ EXPORT_SYMBOL(eth_type_trans); * @skb: packet to extract header from * @haddr: destination buffer */ -static int eth_header_parse(struct sk_buff *skb, unsigned char *haddr) +static int eth_header_parse(const struct sk_buff *skb, unsigned char *haddr) { - struct ethhdr *eth = eth_hdr(skb); + const struct ethhdr *eth = eth_hdr(skb); memcpy(haddr, eth->h_source, ETH_ALEN); return ETH_ALEN; } diff --git a/net/ipv4/netfilter/ip_queue.c b/net/ipv4/netfilter/ip_queue.c index 82fda92e6b97..aaa3f5c56761 100644 --- a/net/ipv4/netfilter/ip_queue.c +++ b/net/ipv4/netfilter/ip_queue.c @@ -250,10 +250,8 @@ ipq_build_packet_message(struct ipq_queue_entry *entry, int *errp) if (entry->info->indev && entry->skb->dev) { pmsg->hw_type = entry->skb->dev->type; - if (entry->skb->dev->hard_header_parse) - pmsg->hw_addrlen = - entry->skb->dev->hard_header_parse(entry->skb, - pmsg->hw_addr); + pmsg->hw_addrlen = dev_parse_header(entry->skb, + pmsg->hw_addr); } if (data_len) diff --git a/net/ipv6/netfilter/ip6_queue.c b/net/ipv6/netfilter/ip6_queue.c index 2f5a52453834..c75f467a8f51 100644 --- a/net/ipv6/netfilter/ip6_queue.c +++ b/net/ipv6/netfilter/ip6_queue.c @@ -248,10 +248,7 @@ ipq_build_packet_message(struct ipq_queue_entry *entry, int *errp) if (entry->info->indev && entry->skb->dev) { pmsg->hw_type = entry->skb->dev->type; - if (entry->skb->dev->hard_header_parse) - pmsg->hw_addrlen = - entry->skb->dev->hard_header_parse(entry->skb, - pmsg->hw_addr); + pmsg->hw_addrlen = dev_parse_header(entry->skb, pmsg->hw_addr); } if (data_len) diff --git a/net/mac80211/ieee80211.c b/net/mac80211/ieee80211.c index 89be6629cfc0..0cdcf0d0c6ca 100644 --- a/net/mac80211/ieee80211.c +++ b/net/mac80211/ieee80211.c @@ -47,7 +47,7 @@ struct ieee80211_tx_status_rtap_hdr { /* common interface routines */ -static int header_parse_80211(struct sk_buff *skb, unsigned char *haddr) +static int header_parse_80211(const struct sk_buff *skb, unsigned char *haddr) { memcpy(haddr, skb_mac_header(skb) + 10, ETH_ALEN); /* addr2 */ return ETH_ALEN; diff --git a/net/netfilter/nfnetlink_log.c b/net/netfilter/nfnetlink_log.c index 8e4001b8f764..332e0f7f6f9e 100644 --- a/net/netfilter/nfnetlink_log.c +++ b/net/netfilter/nfnetlink_log.c @@ -481,12 +481,13 @@ __build_packet_message(struct nfulnl_instance *inst, NFA_PUT(inst->skb, NFULA_MARK, sizeof(tmp_uint), &tmp_uint); } - if (indev && skb->dev && skb->dev->hard_header_parse) { + if (indev && skb->dev) { struct nfulnl_msg_packet_hw phw; - int len = skb->dev->hard_header_parse((struct sk_buff *)skb, - phw.hw_addr); - phw.hw_addrlen = htons(len); - NFA_PUT(inst->skb, NFULA_HWADDR, sizeof(phw), &phw); + int len = dev_parse_header(skb, phw.hw_addr); + if (len > 0) { + phw.hw_addrlen = htons(len); + NFA_PUT(inst->skb, NFULA_HWADDR, sizeof(phw), &phw); + } } if (skb->tstamp.tv64) { diff --git a/net/netfilter/nfnetlink_queue.c b/net/netfilter/nfnetlink_queue.c index c97369f48db7..a813185c766d 100644 --- a/net/netfilter/nfnetlink_queue.c +++ b/net/netfilter/nfnetlink_queue.c @@ -485,14 +485,13 @@ nfqnl_build_packet_message(struct nfqnl_instance *queue, NFA_PUT(skb, NFQA_MARK, sizeof(u_int32_t), &tmp_uint); } - if (indev && entskb->dev - && entskb->dev->hard_header_parse) { + if (indev && entskb->dev) { struct nfqnl_msg_packet_hw phw; - - int len = entskb->dev->hard_header_parse(entskb, - phw.hw_addr); - phw.hw_addrlen = htons(len); - NFA_PUT(skb, NFQA_HWADDR, sizeof(phw), &phw); + int len = dev_parse_header(entskb, phw.hw_addr); + if (len) { + phw.hw_addrlen = htons(len); + NFA_PUT(skb, NFQA_HWADDR, sizeof(phw), &phw); + } } if (entskb->tstamp.tv64) { diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c index c5244b309640..c9ee343c2a6c 100644 --- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c @@ -519,10 +519,8 @@ static int packet_rcv(struct sk_buff *skb, struct net_device *dev, struct packet sll->sll_ifindex = orig_dev->ifindex; else sll->sll_ifindex = dev->ifindex; - sll->sll_halen = 0; - if (dev->hard_header_parse) - sll->sll_halen = dev->hard_header_parse(skb, sll->sll_addr); + sll->sll_halen = dev_parse_header(skb, sll->sll_addr); PACKET_SKB_CB(skb)->origlen = skb->len; @@ -658,9 +656,7 @@ static int tpacket_rcv(struct sk_buff *skb, struct net_device *dev, struct packe h->tp_usec = tv.tv_usec; sll = (struct sockaddr_ll*)((u8*)h + TPACKET_ALIGN(sizeof(*h))); - sll->sll_halen = 0; - if (dev->hard_header_parse) - sll->sll_halen = dev->hard_header_parse(skb, sll->sll_addr); + sll->sll_halen = dev_parse_header(skb, sll->sll_addr); sll->sll_family = AF_PACKET; sll->sll_hatype = dev->type; sll->sll_protocol = skb->protocol; -- cgit v1.2.3 From 3b04ddde02cf1b6f14f2697da5c20eca5715017f Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Tue, 9 Oct 2007 01:40:57 -0700 Subject: [NET]: Move hardware header operations out of netdevice. Since hardware header operations are part of the protocol class not the device instance, make them into a separate object and save memory. Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- drivers/ieee1394/eth1394.c | 40 ++++++----- drivers/infiniband/ulp/ipoib/ipoib_main.c | 8 ++- drivers/isdn/i4l/isdn_net.c | 105 ++++++++++------------------- drivers/media/dvb/dvb-core/dvb_net.c | 9 ++- drivers/net/appletalk/cops.c | 20 +----- drivers/net/appletalk/ltpc.c | 10 --- drivers/net/arcnet/arcnet.c | 18 +++-- drivers/net/hamradio/6pack.c | 13 +++- drivers/net/hamradio/baycom_epp.c | 3 +- drivers/net/hamradio/bpqether.c | 3 +- drivers/net/hamradio/dmascc.c | 3 +- drivers/net/hamradio/hdlcdrv.c | 3 +- drivers/net/hamradio/mkiss.c | 14 ++-- drivers/net/hamradio/scc.c | 4 +- drivers/net/hamradio/yam.c | 3 +- drivers/net/loopback.c | 8 +-- drivers/net/macvlan.c | 15 ++++- drivers/net/myri_sbus.c | 28 +++++--- drivers/net/plip.c | 50 ++++++-------- drivers/net/shaper.c | 61 +++-------------- drivers/net/skfp/skfddi.c | 1 - drivers/net/wan/cycx_x25.c | 31 ++++++--- drivers/net/wan/dlci.c | 10 ++- drivers/net/wan/hdlc.c | 10 ++- drivers/net/wan/hdlc_cisco.c | 10 +-- drivers/net/wan/hdlc_ppp.c | 2 +- drivers/net/wan/lmc/lmc_proto.c | 2 +- drivers/net/wan/syncppp.c | 19 +++--- drivers/net/wireless/airo.c | 6 +- drivers/net/wireless/hostap/hostap.h | 3 +- drivers/net/wireless/hostap/hostap_hw.c | 3 +- drivers/net/wireless/hostap/hostap_ioctl.c | 5 +- drivers/net/wireless/hostap/hostap_main.c | 47 ++++++++----- drivers/net/wireless/hostap/hostap_wlan.h | 2 - drivers/net/wireless/strip.c | 13 ++-- drivers/s390/net/qeth.h | 3 +- drivers/s390/net/qeth_main.c | 44 +++++++----- include/linux/etherdevice.h | 20 +++--- include/linux/if_ether.h | 2 + include/linux/if_shaper.h | 11 --- include/linux/isdn.h | 7 -- include/linux/netdevice.h | 43 ++++++------ include/net/ax25.h | 5 +- include/net/pkt_sched.h | 5 +- net/802/fc.c | 11 +-- net/802/fddi.c | 10 ++- net/802/hippi.c | 16 +++-- net/802/tr.c | 15 +++-- net/8021q/vlan.c | 14 ++-- net/8021q/vlan.h | 4 +- net/8021q/vlan_dev.c | 4 +- net/appletalk/dev.c | 4 -- net/ax25/ax25_ip.c | 15 ++++- net/core/dev.c | 16 ----- net/core/neighbour.c | 11 +-- net/ethernet/eth.c | 36 ++++++---- net/ipv4/arp.c | 6 +- net/ipv4/ip_gre.c | 13 ++-- net/ipv4/ip_output.c | 2 +- net/ipv6/ndisc.c | 6 +- net/mac80211/ieee80211.c | 12 +++- net/netrom/nr_dev.c | 14 ++-- net/packet/af_packet.c | 6 +- net/rose/rose_dev.c | 13 ++-- net/sched/sch_teql.c | 6 +- 65 files changed, 481 insertions(+), 475 deletions(-) (limited to 'include/linux') diff --git a/drivers/ieee1394/eth1394.c b/drivers/ieee1394/eth1394.c index b31f90082e35..dc9dce22f6a8 100644 --- a/drivers/ieee1394/eth1394.c +++ b/drivers/ieee1394/eth1394.c @@ -159,15 +159,16 @@ MODULE_PARM_DESC(max_partial_datagrams, static int ether1394_header(struct sk_buff *skb, struct net_device *dev, - unsigned short type, void *daddr, void *saddr, - unsigned len); + unsigned short type, const void *daddr, + const void *saddr, unsigned len); static int ether1394_rebuild_header(struct sk_buff *skb); static int ether1394_header_parse(const struct sk_buff *skb, unsigned char *haddr); -static int ether1394_header_cache(struct neighbour *neigh, struct hh_cache *hh); +static int ether1394_header_cache(const struct neighbour *neigh, + struct hh_cache *hh); static void ether1394_header_cache_update(struct hh_cache *hh, - struct net_device *dev, - unsigned char *haddr); + const struct net_device *dev, + const unsigned char *haddr); static int ether1394_tx(struct sk_buff *skb, struct net_device *dev); static void ether1394_iso(struct hpsb_iso *iso); @@ -507,6 +508,14 @@ static void ether1394_reset_priv(struct net_device *dev, int set_mtu) spin_unlock_irqrestore(&priv->lock, flags); } +static const struct header_ops ether1394_header_ops = { + .create = ether1394_header, + .rebuild = ether1394_rebuild_header, + .cache = ether1394_header_cache, + .cache_update = ether1394_header_cache_update, + .parse = ether1394_header_parse, +}; + static void ether1394_init_dev(struct net_device *dev) { dev->open = ether1394_open; @@ -516,11 +525,7 @@ static void ether1394_init_dev(struct net_device *dev) dev->tx_timeout = ether1394_tx_timeout; dev->change_mtu = ether1394_change_mtu; - dev->hard_header = ether1394_header; - dev->rebuild_header = ether1394_rebuild_header; - dev->hard_header_cache = ether1394_header_cache; - dev->header_cache_update= ether1394_header_cache_update; - dev->hard_header_parse = ether1394_header_parse; + dev->header_ops = ðer1394_header_ops; SET_ETHTOOL_OPS(dev, ðtool_ops); @@ -711,8 +716,8 @@ static void ether1394_host_reset(struct hpsb_host *host) * saddr=NULL means use device source address * daddr=NULL means leave destination address (eg unresolved arp). */ static int ether1394_header(struct sk_buff *skb, struct net_device *dev, - unsigned short type, void *daddr, void *saddr, - unsigned len) + unsigned short type, const void *daddr, + const void *saddr, unsigned len) { struct eth1394hdr *eth = (struct eth1394hdr *)skb_push(skb, ETH1394_HLEN); @@ -759,7 +764,8 @@ static int ether1394_header_parse(const struct sk_buff *skb, return ETH1394_ALEN; } -static int ether1394_header_cache(struct neighbour *neigh, struct hh_cache *hh) +static int ether1394_header_cache(const struct neighbour *neigh, + struct hh_cache *hh) { unsigned short type = hh->hh_type; struct net_device *dev = neigh->dev; @@ -778,8 +784,8 @@ static int ether1394_header_cache(struct neighbour *neigh, struct hh_cache *hh) /* Called by Address Resolution module to notify changes in address. */ static void ether1394_header_cache_update(struct hh_cache *hh, - struct net_device *dev, - unsigned char * haddr) + const struct net_device *dev, + const unsigned char * haddr) { memcpy((u8 *)hh->hh_data + 16 - ETH1394_HLEN, haddr, dev->addr_len); } @@ -899,8 +905,8 @@ static u16 ether1394_parse_encap(struct sk_buff *skb, struct net_device *dev, } /* Now add the ethernet header. */ - if (dev->hard_header(skb, dev, ntohs(ether_type), &dest_hw, NULL, - skb->len) >= 0) + if (dev_hard_header(skb, dev, ntohs(ether_type), &dest_hw, NULL, + skb->len) >= 0) ret = ether1394_type_trans(skb, dev); return ret; diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c index b1c3d6cd8eba..2bd76ef57154 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_main.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c @@ -780,7 +780,7 @@ static void ipoib_timeout(struct net_device *dev) static int ipoib_hard_header(struct sk_buff *skb, struct net_device *dev, unsigned short type, - void *daddr, void *saddr, unsigned len) + const void *daddr, const void *saddr, unsigned len) { struct ipoib_header *header; @@ -940,6 +940,10 @@ void ipoib_dev_cleanup(struct net_device *dev) priv->tx_ring = NULL; } +static const struct header_ops ipoib_header_ops = { + .create = ipoib_hard_header, +}; + static void ipoib_setup(struct net_device *dev) { struct ipoib_dev_priv *priv = netdev_priv(dev); @@ -950,7 +954,7 @@ static void ipoib_setup(struct net_device *dev) dev->hard_start_xmit = ipoib_start_xmit; dev->get_stats = ipoib_get_stats; dev->tx_timeout = ipoib_timeout; - dev->hard_header = ipoib_hard_header; + dev->header_ops = &ipoib_header_ops; dev->set_multicast_list = ipoib_set_mcast_list; dev->neigh_setup = ipoib_neigh_setup_dev; diff --git a/drivers/isdn/i4l/isdn_net.c b/drivers/isdn/i4l/isdn_net.c index aa83277aba74..54546604656d 100644 --- a/drivers/isdn/i4l/isdn_net.c +++ b/drivers/isdn/i4l/isdn_net.c @@ -1873,54 +1873,14 @@ isdn_net_rcv_skb(int idx, struct sk_buff *skb) return 0; } -static int -my_eth_header(struct sk_buff *skb, struct net_device *dev, unsigned short type, - void *daddr, void *saddr, unsigned len) -{ - struct ethhdr *eth = (struct ethhdr *) skb_push(skb, ETH_HLEN); - - /* - * Set the protocol type. For a packet of type ETH_P_802_3 we - * put the length here instead. It is up to the 802.2 layer to - * carry protocol information. - */ - - if (type != ETH_P_802_3) - eth->h_proto = htons(type); - else - eth->h_proto = htons(len); - - /* - * Set the source hardware address. - */ - if (saddr) - memcpy(eth->h_source, saddr, dev->addr_len); - else - memcpy(eth->h_source, dev->dev_addr, dev->addr_len); - - /* - * Anyway, the loopback-device should never use this function... - */ - - if (dev->flags & (IFF_LOOPBACK | IFF_NOARP)) { - memset(eth->h_dest, 0, dev->addr_len); - return ETH_HLEN /*(dev->hard_header_len)*/; - } - if (daddr) { - memcpy(eth->h_dest, daddr, dev->addr_len); - return ETH_HLEN /*dev->hard_header_len*/; - } - return -ETH_HLEN /*dev->hard_header_len*/; -} - /* * build an header * depends on encaps that is being used. */ -static int -isdn_net_header(struct sk_buff *skb, struct net_device *dev, unsigned short type, - void *daddr, void *saddr, unsigned plen) +static int isdn_net_header(struct sk_buff *skb, struct net_device *dev, + unsigned short type, + const void *daddr, const void *saddr, unsigned plen) { isdn_net_local *lp = dev->priv; unsigned char *p; @@ -1928,7 +1888,7 @@ isdn_net_header(struct sk_buff *skb, struct net_device *dev, unsigned short type switch (lp->p_encap) { case ISDN_NET_ENCAP_ETHER: - len = my_eth_header(skb, dev, type, daddr, saddr, plen); + len = eth_header(skb, dev, type, daddr, saddr, plen); break; #ifdef CONFIG_ISDN_PPP case ISDN_NET_ENCAP_SYNCPPP: @@ -2005,6 +1965,32 @@ isdn_net_rebuild_header(struct sk_buff *skb) return ret; } +static int isdn_header_cache(const struct neighbour *neigh, struct hh_cache *hh) +{ + const struct net_device *dev = neigh->dev; + isdn_net_local *lp = dev->priv; + + if (lp->p_encap == ISDN_NET_ENCAP_ETHER) + return eth_header_cache(neigh, hh); + return -1; +} + +static void isdn_header_cache_update(struct hh_cache *hh, + const struct net_device *dev, + const unsigned char *haddr) +{ + isdn_net_local *lp = dev->priv; + if (lp->p_encap == ISDN_NET_ENCAP_ETHER) + return eth_header_cache_update(hh, dev, haddr); +} + +static const struct header_ops isdn_header_ops = { + .create = isdn_net_header, + .rebuild = isdn_net_rebuild_header, + .cache = isdn_header_cache, + .cache_update = isdn_header_cache_update, +}; + /* * Interface-setup. (just after registering a new interface) */ @@ -2012,18 +1998,12 @@ static int isdn_net_init(struct net_device *ndev) { ushort max_hlhdr_len = 0; - isdn_net_local *lp = (isdn_net_local *) ndev->priv; - int drvidx, i; + int drvidx; ether_setup(ndev); - lp->org_hhc = ndev->hard_header_cache; - lp->org_hcu = ndev->header_cache_update; + ndev->header_ops = NULL; /* Setup the generic properties */ - - ndev->hard_header = NULL; - ndev->hard_header_cache = NULL; - ndev->header_cache_update = NULL; ndev->mtu = 1500; ndev->flags = IFF_NOARP|IFF_POINTOPOINT; ndev->type = ARPHRD_ETHER; @@ -2032,9 +2012,6 @@ isdn_net_init(struct net_device *ndev) /* for clients with MPPP maybe higher values better */ ndev->tx_queue_len = 30; - for (i = 0; i < ETH_ALEN; i++) - ndev->broadcast[i] = 0xff; - /* The ISDN-specific entries in the device structure. */ ndev->open = &isdn_net_open; ndev->hard_start_xmit = &isdn_net_start_xmit; @@ -2052,7 +2029,6 @@ isdn_net_init(struct net_device *ndev) ndev->hard_header_len = ETH_HLEN + max_hlhdr_len; ndev->stop = &isdn_net_close; ndev->get_stats = &isdn_net_get_stats; - ndev->rebuild_header = &isdn_net_rebuild_header; ndev->do_ioctl = NULL; return 0; } @@ -2861,21 +2837,14 @@ isdn_net_setcfg(isdn_net_ioctl_cfg * cfg) } if (cfg->p_encap != lp->p_encap) { if (cfg->p_encap == ISDN_NET_ENCAP_RAWIP) { - p->dev.hard_header = NULL; - p->dev.hard_header_cache = NULL; - p->dev.header_cache_update = NULL; + p->dev.header_ops = NULL; p->dev.flags = IFF_NOARP|IFF_POINTOPOINT; } else { - p->dev.hard_header = isdn_net_header; - if (cfg->p_encap == ISDN_NET_ENCAP_ETHER) { - p->dev.hard_header_cache = lp->org_hhc; - p->dev.header_cache_update = lp->org_hcu; + p->dev.header_ops = &isdn_header_ops; + if (cfg->p_encap == ISDN_NET_ENCAP_ETHER) p->dev.flags = IFF_BROADCAST | IFF_MULTICAST; - } else { - p->dev.hard_header_cache = NULL; - p->dev.header_cache_update = NULL; + else p->dev.flags = IFF_NOARP|IFF_POINTOPOINT; - } } } lp->p_encap = cfg->p_encap; @@ -3127,8 +3096,6 @@ isdn_net_realrm(isdn_net_dev * p, isdn_net_dev * q) ((isdn_net_local *) (p->local->master->priv))->slave = p->local->slave; } else { /* Unregister only if it's a master-device */ - p->dev.hard_header_cache = p->local->org_hhc; - p->dev.header_cache_update = p->local->org_hcu; unregister_netdev(&p->dev); } /* Unlink device from chain */ diff --git a/drivers/media/dvb/dvb-core/dvb_net.c b/drivers/media/dvb/dvb-core/dvb_net.c index bdd797071cb0..06800e5a0770 100644 --- a/drivers/media/dvb/dvb-core/dvb_net.c +++ b/drivers/media/dvb/dvb-core/dvb_net.c @@ -1225,10 +1225,17 @@ static struct net_device_stats * dvb_net_get_stats(struct net_device *dev) return &((struct dvb_net_priv*) dev->priv)->stats; } +static const struct header_ops dvb_header_ops = { + .create = eth_header, + .parse = eth_header_parse, + .rebuild = eth_rebuild_header, +}; + static void dvb_net_setup(struct net_device *dev) { ether_setup(dev); + dev->header_ops = &dvb_header_ops; dev->open = dvb_net_open; dev->stop = dvb_net_stop; dev->hard_start_xmit = dvb_net_tx; @@ -1237,7 +1244,7 @@ static void dvb_net_setup(struct net_device *dev) dev->set_mac_address = dvb_net_set_mac; dev->mtu = 4096; dev->mc_count = 0; - dev->hard_header_cache = NULL; + dev->flags |= IFF_NOARP; } diff --git a/drivers/net/appletalk/cops.c b/drivers/net/appletalk/cops.c index c4b560d42a67..92c3a4cf0bb1 100644 --- a/drivers/net/appletalk/cops.c +++ b/drivers/net/appletalk/cops.c @@ -194,10 +194,6 @@ static void cops_timeout(struct net_device *dev); static void cops_rx (struct net_device *dev); static int cops_send_packet (struct sk_buff *skb, struct net_device *dev); static void set_multicast_list (struct net_device *dev); -static int cops_hard_header (struct sk_buff *skb, struct net_device *dev, - unsigned short type, void *daddr, void *saddr, - unsigned len); - static int cops_ioctl (struct net_device *dev, struct ifreq *rq, int cmd); static int cops_close (struct net_device *dev); static struct net_device_stats *cops_get_stats (struct net_device *dev); @@ -331,7 +327,6 @@ static int __init cops_probe1(struct net_device *dev, int ioaddr) dev->base_addr = ioaddr; lp = netdev_priv(dev); - memset(lp, 0, sizeof(struct cops_local)); spin_lock_init(&lp->lock); /* Copy local board variable to lp struct. */ @@ -340,7 +335,7 @@ static int __init cops_probe1(struct net_device *dev, int ioaddr) dev->hard_start_xmit = cops_send_packet; dev->tx_timeout = cops_timeout; dev->watchdog_timeo = HZ * 2; - dev->hard_header = cops_hard_header; + dev->get_stats = cops_get_stats; dev->open = cops_open; dev->stop = cops_close; @@ -944,19 +939,6 @@ static void set_multicast_list(struct net_device *dev) printk("%s: set_multicast_list executed\n", dev->name); } -/* - * Another Dummy function to keep the Appletalk layer happy. - */ - -static int cops_hard_header(struct sk_buff *skb, struct net_device *dev, - unsigned short type, void *daddr, void *saddr, - unsigned len) -{ - if(cops_debug >= 3) - printk("%s: cops_hard_header executed. Wow!\n", dev->name); - return 0; -} - /* * System ioctls for the COPS LocalTalk card. */ diff --git a/drivers/net/appletalk/ltpc.c b/drivers/net/appletalk/ltpc.c index cb4744e56905..6ab2c2d4d673 100644 --- a/drivers/net/appletalk/ltpc.c +++ b/drivers/net/appletalk/ltpc.c @@ -870,15 +870,6 @@ static void set_multicast_list(struct net_device *dev) /* Actually netatalk needs fixing! */ } -static int ltpc_hard_header (struct sk_buff *skb, struct net_device *dev, - unsigned short type, void *daddr, void *saddr, unsigned len) -{ - if(debug & DEBUG_VERBOSE) - printk("ltpc_hard_header called for device %s\n", - dev->name); - return 0; -} - static int ltpc_poll_counter; static void ltpc_poll(unsigned long l) @@ -1141,7 +1132,6 @@ struct net_device * __init ltpc_probe(void) /* Fill in the fields of the device structure with ethernet-generic values. */ dev->hard_start_xmit = ltpc_xmit; - dev->hard_header = ltpc_hard_header; dev->get_stats = ltpc_get_stats; /* add the ltpc-specific things */ diff --git a/drivers/net/arcnet/arcnet.c b/drivers/net/arcnet/arcnet.c index 681e20b8466f..c59c8067de99 100644 --- a/drivers/net/arcnet/arcnet.c +++ b/drivers/net/arcnet/arcnet.c @@ -102,8 +102,8 @@ static int arcnet_close(struct net_device *dev); static int arcnet_send_packet(struct sk_buff *skb, struct net_device *dev); static void arcnet_timeout(struct net_device *dev); static int arcnet_header(struct sk_buff *skb, struct net_device *dev, - unsigned short type, void *daddr, void *saddr, - unsigned len); + unsigned short type, const void *daddr, + const void *saddr, unsigned len); static int arcnet_rebuild_header(struct sk_buff *skb); static struct net_device_stats *arcnet_get_stats(struct net_device *dev); static int go_tx(struct net_device *dev); @@ -317,11 +317,17 @@ static int choose_mtu(void) return mtu == 65535 ? XMTU : mtu; } +static const struct header_ops arcnet_header_ops = { + .create = arcnet_header, + .rebuild = arcnet_rebuild_header, +}; + /* Setup a struct device for ARCnet. */ static void arcdev_setup(struct net_device *dev) { dev->type = ARPHRD_ARCNET; + dev->header_ops = &arcnet_header_ops; dev->hard_header_len = sizeof(struct archdr); dev->mtu = choose_mtu(); @@ -342,8 +348,6 @@ static void arcdev_setup(struct net_device *dev) dev->hard_start_xmit = arcnet_send_packet; dev->tx_timeout = arcnet_timeout; dev->get_stats = arcnet_get_stats; - dev->hard_header = arcnet_header; - dev->rebuild_header = arcnet_rebuild_header; } struct net_device *alloc_arcdev(char *name) @@ -488,10 +492,10 @@ static int arcnet_close(struct net_device *dev) static int arcnet_header(struct sk_buff *skb, struct net_device *dev, - unsigned short type, void *daddr, void *saddr, - unsigned len) + unsigned short type, const void *daddr, + const void *saddr, unsigned len) { - struct arcnet_local *lp = dev->priv; + const struct arcnet_local *lp = netdev_priv(dev); uint8_t _daddr, proto_num; struct ArcProto *proto; diff --git a/drivers/net/hamradio/6pack.c b/drivers/net/hamradio/6pack.c index 0a847326a5e4..ecd156def039 100644 --- a/drivers/net/hamradio/6pack.c +++ b/drivers/net/hamradio/6pack.c @@ -288,7 +288,8 @@ static int sp_close(struct net_device *dev) /* Return the frame type ID */ static int sp_header(struct sk_buff *skb, struct net_device *dev, - unsigned short type, void *daddr, void *saddr, unsigned len) + unsigned short type, const void *daddr, + const void *saddr, unsigned len) { #ifdef CONFIG_INET if (type != htons(ETH_P_AX25)) @@ -323,6 +324,11 @@ static int sp_rebuild_header(struct sk_buff *skb) #endif } +static const struct header_ops sp_header_ops = { + .create = sp_header, + .rebuild = sp_rebuild_header, +}; + static void sp_setup(struct net_device *dev) { /* Finish setting up the DEVICE info. */ @@ -331,14 +337,15 @@ static void sp_setup(struct net_device *dev) dev->open = sp_open_dev; dev->destructor = free_netdev; dev->stop = sp_close; - dev->hard_header = sp_header; + dev->get_stats = sp_get_stats; dev->set_mac_address = sp_set_mac_address; dev->hard_header_len = AX25_MAX_HEADER_LEN; + dev->header_ops = &sp_header_ops; + dev->addr_len = AX25_ADDR_LEN; dev->type = ARPHRD_AX25; dev->tx_queue_len = 10; - dev->rebuild_header = sp_rebuild_header; dev->tx_timeout = NULL; /* Only activated in AX.25 mode */ diff --git a/drivers/net/hamradio/baycom_epp.c b/drivers/net/hamradio/baycom_epp.c index 355c6cf3d112..1a5a75acf73e 100644 --- a/drivers/net/hamradio/baycom_epp.c +++ b/drivers/net/hamradio/baycom_epp.c @@ -1159,8 +1159,7 @@ static void baycom_probe(struct net_device *dev) /* Fill in the fields of the device structure */ bc->skb = NULL; - dev->hard_header = ax25_hard_header; - dev->rebuild_header = ax25_rebuild_header; + dev->header_ops = &ax25_header_ops; dev->set_mac_address = baycom_set_mac_address; dev->type = ARPHRD_AX25; /* AF_AX25 device */ diff --git a/drivers/net/hamradio/bpqether.c b/drivers/net/hamradio/bpqether.c index 4bff23e3b970..5ddf8b0c34f9 100644 --- a/drivers/net/hamradio/bpqether.c +++ b/drivers/net/hamradio/bpqether.c @@ -483,8 +483,7 @@ static void bpq_setup(struct net_device *dev) dev->flags = 0; #if defined(CONFIG_AX25) || defined(CONFIG_AX25_MODULE) - dev->hard_header = ax25_hard_header; - dev->rebuild_header = ax25_rebuild_header; + dev->header_ops = &ax25_header_ops; #endif dev->type = ARPHRD_AX25; diff --git a/drivers/net/hamradio/dmascc.c b/drivers/net/hamradio/dmascc.c index 205f09672492..bc02e4694804 100644 --- a/drivers/net/hamradio/dmascc.c +++ b/drivers/net/hamradio/dmascc.c @@ -581,8 +581,7 @@ static int __init setup_adapter(int card_base, int type, int n) dev->do_ioctl = scc_ioctl; dev->hard_start_xmit = scc_send_packet; dev->get_stats = scc_get_stats; - dev->hard_header = ax25_hard_header; - dev->rebuild_header = ax25_rebuild_header; + dev->header_ops = &ax25_header_ops; dev->set_mac_address = scc_set_mac_address; } if (register_netdev(info->dev[0])) { diff --git a/drivers/net/hamradio/hdlcdrv.c b/drivers/net/hamradio/hdlcdrv.c index b33adc6a340b..ae9629fa6882 100644 --- a/drivers/net/hamradio/hdlcdrv.c +++ b/drivers/net/hamradio/hdlcdrv.c @@ -682,8 +682,7 @@ static void hdlcdrv_setup(struct net_device *dev) s->skb = NULL; - dev->hard_header = ax25_hard_header; - dev->rebuild_header = ax25_rebuild_header; + dev->header_ops = &ax25_header_ops; dev->set_mac_address = hdlcdrv_set_mac_address; dev->type = ARPHRD_AX25; /* AF_AX25 device */ diff --git a/drivers/net/hamradio/mkiss.c b/drivers/net/hamradio/mkiss.c index d08fbc396648..9e43c47691ca 100644 --- a/drivers/net/hamradio/mkiss.c +++ b/drivers/net/hamradio/mkiss.c @@ -578,8 +578,9 @@ static int ax_open_dev(struct net_device *dev) #if defined(CONFIG_AX25) || defined(CONFIG_AX25_MODULE) /* Return the frame type ID */ -static int ax_header(struct sk_buff *skb, struct net_device *dev, unsigned short type, - void *daddr, void *saddr, unsigned len) +static int ax_header(struct sk_buff *skb, struct net_device *dev, + unsigned short type, const void *daddr, + const void *saddr, unsigned len) { #ifdef CONFIG_INET if (type != htons(ETH_P_AX25)) @@ -670,6 +671,11 @@ static struct net_device_stats *ax_get_stats(struct net_device *dev) return &ax->stats; } +static const struct header_ops ax_header_ops = { + .create = ax_header, + .rebuild = ax_rebuild_header, +}; + static void ax_setup(struct net_device *dev) { /* Finish setting up the DEVICE info. */ @@ -683,8 +689,8 @@ static void ax_setup(struct net_device *dev) dev->addr_len = 0; dev->type = ARPHRD_AX25; dev->tx_queue_len = 10; - dev->hard_header = ax_header; - dev->rebuild_header = ax_rebuild_header; + dev->header_ops = &ax_header_ops; + memcpy(dev->broadcast, &ax25_bcast, AX25_ADDR_LEN); memcpy(dev->dev_addr, &ax25_defaddr, AX25_ADDR_LEN); diff --git a/drivers/net/hamradio/scc.c b/drivers/net/hamradio/scc.c index 39b3b82aa4a4..353d13e543ce 100644 --- a/drivers/net/hamradio/scc.c +++ b/drivers/net/hamradio/scc.c @@ -1551,8 +1551,8 @@ static void scc_net_setup(struct net_device *dev) dev->stop = scc_net_close; dev->hard_start_xmit = scc_net_tx; - dev->hard_header = ax25_hard_header; - dev->rebuild_header = ax25_rebuild_header; + dev->header_ops = &ax25_header_ops; + dev->set_mac_address = scc_net_set_mac_address; dev->get_stats = scc_net_get_stats; dev->do_ioctl = scc_net_ioctl; diff --git a/drivers/net/hamradio/yam.c b/drivers/net/hamradio/yam.c index 401724ddafcd..1c942862a3f4 100644 --- a/drivers/net/hamradio/yam.c +++ b/drivers/net/hamradio/yam.c @@ -1097,8 +1097,7 @@ static void yam_setup(struct net_device *dev) skb_queue_head_init(&yp->send_queue); - dev->hard_header = ax25_hard_header; - dev->rebuild_header = ax25_rebuild_header; + dev->header_ops = &ax25_header_ops; dev->set_mac_address = yam_set_mac_address; diff --git a/drivers/net/loopback.c b/drivers/net/loopback.c index f11120b7a3b2..b6d4ae3ad506 100644 --- a/drivers/net/loopback.c +++ b/drivers/net/loopback.c @@ -221,22 +221,17 @@ static void loopback_dev_free(struct net_device *dev) } /* - * The loopback device is special. There is only one instance and - * it is statically allocated. Don't do this for other devices. + * The loopback device is special. There is only one instance. */ static void loopback_setup(struct net_device *dev) { dev->get_stats = &get_stats; dev->mtu = (16 * 1024) + 20 + 20 + 12; dev->hard_start_xmit = loopback_xmit; - dev->hard_header = eth_header; - dev->hard_header_cache = eth_header_cache; - dev->header_cache_update = eth_header_cache_update; dev->hard_header_len = ETH_HLEN; /* 14 */ dev->addr_len = ETH_ALEN; /* 6 */ dev->tx_queue_len = 0; dev->type = ARPHRD_LOOPBACK; /* 0x0001*/ - dev->rebuild_header = eth_rebuild_header; dev->flags = IFF_LOOPBACK; dev->features = NETIF_F_SG | NETIF_F_FRAGLIST #ifdef LOOPBACK_TSO @@ -247,6 +242,7 @@ static void loopback_setup(struct net_device *dev) | NETIF_F_LLTX | NETIF_F_NETNS_LOCAL, dev->ethtool_ops = &loopback_ethtool_ops; + dev->header_ops = ð_header_ops; dev->init = loopback_dev_init; dev->destructor = loopback_dev_free; } diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c index a22087ca968d..b7c81c874f7a 100644 --- a/drivers/net/macvlan.c +++ b/drivers/net/macvlan.c @@ -164,8 +164,8 @@ static int macvlan_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) } static int macvlan_hard_header(struct sk_buff *skb, struct net_device *dev, - unsigned short type, void *daddr, void *saddr, - unsigned len) + unsigned short type, const void *daddr, + const void *saddr, unsigned len) { const struct macvlan_dev *vlan = netdev_priv(dev); struct net_device *lowerdev = vlan->lowerdev; @@ -174,6 +174,15 @@ static int macvlan_hard_header(struct sk_buff *skb, struct net_device *dev, saddr ? : dev->dev_addr, len); } +static const struct header_ops macvlan_hard_header_ops = { + .create = macvlan_hard_header, + .rebuild = eth_rebuild_header, + .parse = eth_header_parse, + .rebuild = eth_rebuild_header, + .cache = eth_header_cache, + .cache_update = eth_header_cache_update, +}; + static int macvlan_open(struct net_device *dev) { struct macvlan_dev *vlan = netdev_priv(dev); @@ -295,9 +304,9 @@ static void macvlan_setup(struct net_device *dev) dev->change_mtu = macvlan_change_mtu; dev->change_rx_flags = macvlan_change_rx_flags; dev->set_multicast_list = macvlan_set_multicast_list; - dev->hard_header = macvlan_hard_header; dev->hard_start_xmit = macvlan_hard_start_xmit; dev->destructor = free_netdev; + dev->header_ops = &macvlan_hard_header_ops, dev->ethtool_ops = &macvlan_ethtool_ops; dev->tx_queue_len = 0; } diff --git a/drivers/net/myri_sbus.c b/drivers/net/myri_sbus.c index d68ee51c095f..8d29319cc5cb 100644 --- a/drivers/net/myri_sbus.c +++ b/drivers/net/myri_sbus.c @@ -676,8 +676,9 @@ static int myri_start_xmit(struct sk_buff *skb, struct net_device *dev) * saddr=NULL means use device source address * daddr=NULL means leave destination address (eg unresolved arp) */ -static int myri_header(struct sk_buff *skb, struct net_device *dev, unsigned short type, - void *daddr, void *saddr, unsigned len) +static int myri_header(struct sk_buff *skb, struct net_device *dev, + unsigned short type, const void *daddr, + const void *saddr, unsigned len) { struct ethhdr *eth = (struct ethhdr *) skb_push(skb, ETH_HLEN); unsigned char *pad = (unsigned char *) skb_push(skb, MYRI_PAD_LEN); @@ -759,18 +760,18 @@ static int myri_rebuild_header(struct sk_buff *skb) return 0; } -int myri_header_cache(struct neighbour *neigh, struct hh_cache *hh) +static int myri_header_cache(const struct neighbour *neigh, struct hh_cache *hh) { unsigned short type = hh->hh_type; unsigned char *pad; struct ethhdr *eth; - struct net_device *dev = neigh->dev; + const struct net_device *dev = neigh->dev; pad = ((unsigned char *) hh->hh_data) + HH_DATA_OFF(sizeof(*eth) + MYRI_PAD_LEN); eth = (struct ethhdr *) (pad + MYRI_PAD_LEN); - if (type == __constant_htons(ETH_P_802_3)) + if (type == htons(ETH_P_802_3)) return -1; /* Refill MyriNet padding identifiers, this is just being anal. */ @@ -786,7 +787,9 @@ int myri_header_cache(struct neighbour *neigh, struct hh_cache *hh) /* Called by Address Resolution module to notify changes in address. */ -void myri_header_cache_update(struct hh_cache *hh, struct net_device *dev, unsigned char * haddr) +void myri_header_cache_update(struct hh_cache *hh, + const struct net_device *dev, + const unsigned char * haddr) { memcpy(((u8*)hh->hh_data) + HH_DATA_OFF(sizeof(struct ethhdr)), haddr, dev->addr_len); @@ -881,6 +884,13 @@ static void dump_eeprom(struct myri_eth *mp) } #endif +static const struct header_ops myri_header_ops = { + .create = myri_header, + .rebuild = myri_rebuild_header, + .cache = myri_header_cache, + .cache_update = myri_header_cache_update, +}; + static int __devinit myri_ether_init(struct sbus_dev *sdev) { static int num; @@ -1065,11 +1075,9 @@ static int __devinit myri_ether_init(struct sbus_dev *sdev) dev->mtu = MYRINET_MTU; dev->change_mtu = myri_change_mtu; - dev->hard_header = myri_header; - dev->rebuild_header = myri_rebuild_header; + dev->header_ops = &myri_header_ops; + dev->hard_header_len = (ETH_HLEN + MYRI_PAD_LEN); - dev->hard_header_cache = myri_header_cache; - dev->header_cache_update= myri_header_cache_update; /* Load code onto the LANai. */ DET(("Loading LANAI firmware\n")); diff --git a/drivers/net/plip.c b/drivers/net/plip.c index c17d9ac9ff30..b5e9981d1060 100644 --- a/drivers/net/plip.c +++ b/drivers/net/plip.c @@ -148,9 +148,9 @@ static void plip_interrupt(int irq, void *dev_id); /* Functions for DEV methods */ static int plip_tx_packet(struct sk_buff *skb, struct net_device *dev); static int plip_hard_header(struct sk_buff *skb, struct net_device *dev, - unsigned short type, void *daddr, - void *saddr, unsigned len); -static int plip_hard_header_cache(struct neighbour *neigh, + unsigned short type, const void *daddr, + const void *saddr, unsigned len); +static int plip_hard_header_cache(const struct neighbour *neigh, struct hh_cache *hh); static int plip_open(struct net_device *dev); static int plip_close(struct net_device *dev); @@ -219,11 +219,6 @@ struct net_local { int is_deferred; int port_owner; int should_relinquish; - int (*orig_hard_header)(struct sk_buff *skb, struct net_device *dev, - unsigned short type, void *daddr, - void *saddr, unsigned len); - int (*orig_hard_header_cache)(struct neighbour *neigh, - struct hh_cache *hh); spinlock_t lock; atomic_t kill_timer; struct semaphore killed_timer_sem; @@ -265,6 +260,11 @@ static inline unsigned char read_status (struct net_device *dev) return port->ops->read_status (port); } +static const struct header_ops plip_header_ops = { + .create = plip_hard_header, + .cache = plip_hard_header_cache, +}; + /* Entry point of PLIP driver. Probe the hardware, and register/initialize the driver. @@ -284,17 +284,12 @@ plip_init_netdev(struct net_device *dev) dev->open = plip_open; dev->stop = plip_close; dev->do_ioctl = plip_ioctl; - dev->header_cache_update = NULL; + dev->tx_queue_len = 10; dev->flags = IFF_POINTOPOINT|IFF_NOARP; memset(dev->dev_addr, 0xfc, ETH_ALEN); - /* Set the private structure */ - nl->orig_hard_header = dev->hard_header; - dev->hard_header = plip_hard_header; - - nl->orig_hard_header_cache = dev->hard_header_cache; - dev->hard_header_cache = plip_hard_header_cache; + dev->header_ops = &plip_header_ops; nl->port_owner = 0; @@ -993,14 +988,14 @@ plip_tx_packet(struct sk_buff *skb, struct net_device *dev) } static void -plip_rewrite_address(struct net_device *dev, struct ethhdr *eth) +plip_rewrite_address(const struct net_device *dev, struct ethhdr *eth) { - struct in_device *in_dev; + const struct in_device *in_dev = dev->ip_ptr; - if ((in_dev=dev->ip_ptr) != NULL) { + if (in_dev) { /* Any address will do - we take the first */ - struct in_ifaddr *ifa=in_dev->ifa_list; - if (ifa != NULL) { + const struct in_ifaddr *ifa = in_dev->ifa_list; + if (ifa) { memcpy(eth->h_source, dev->dev_addr, 6); memset(eth->h_dest, 0xfc, 2); memcpy(eth->h_dest+2, &ifa->ifa_address, 4); @@ -1010,26 +1005,25 @@ plip_rewrite_address(struct net_device *dev, struct ethhdr *eth) static int plip_hard_header(struct sk_buff *skb, struct net_device *dev, - unsigned short type, void *daddr, - void *saddr, unsigned len) + unsigned short type, const void *daddr, + const void *saddr, unsigned len) { - struct net_local *nl = netdev_priv(dev); int ret; - if ((ret = nl->orig_hard_header(skb, dev, type, daddr, saddr, len)) >= 0) + ret = eth_header(skb, dev, type, daddr, saddr, len); + if (ret >= 0) plip_rewrite_address (dev, (struct ethhdr *)skb->data); return ret; } -int plip_hard_header_cache(struct neighbour *neigh, +int plip_hard_header_cache(const struct neighbour *neigh, struct hh_cache *hh) { - struct net_local *nl = neigh->dev->priv; int ret; - if ((ret = nl->orig_hard_header_cache(neigh, hh)) == 0) - { + ret = eth_header_cache(neigh, hh); + if (ret == 0) { struct ethhdr *eth; eth = (struct ethhdr*)(((u8*)hh->hh_data) + diff --git a/drivers/net/shaper.c b/drivers/net/shaper.c index 315feba7dacc..228f650250f6 100644 --- a/drivers/net/shaper.c +++ b/drivers/net/shaper.c @@ -331,15 +331,16 @@ static int shaper_close(struct net_device *dev) */ static int shaper_header(struct sk_buff *skb, struct net_device *dev, - unsigned short type, void *daddr, void *saddr, unsigned len) + unsigned short type, + const void *daddr, const void *saddr, unsigned len) { struct shaper *sh=dev->priv; int v; if(sh_debug) printk("Shaper header\n"); - skb->dev=sh->dev; - v=sh->hard_header(skb,sh->dev,type,daddr,saddr,len); - skb->dev=dev; + skb->dev = sh->dev; + v = dev_hard_header(skb, sh->dev, type, daddr, saddr, len); + skb->dev = dev; return v; } @@ -351,7 +352,7 @@ static int shaper_rebuild_header(struct sk_buff *skb) if(sh_debug) printk("Shaper rebuild header\n"); skb->dev=sh->dev; - v=sh->rebuild_header(skb); + v = sh->dev->header_ops->rebuild(skb); skb->dev=dev; return v; } @@ -415,51 +416,17 @@ static int shaper_neigh_setup_dev(struct net_device *dev, struct neigh_parms *p) #endif +static const struct header_ops shaper_ops = { + .create = shaper_header, + .rebuild = shaper_rebuild_header, +}; + static int shaper_attach(struct net_device *shdev, struct shaper *sh, struct net_device *dev) { sh->dev = dev; - sh->hard_start_xmit=dev->hard_start_xmit; sh->get_stats=dev->get_stats; - if(dev->hard_header) - { - sh->hard_header=dev->hard_header; - shdev->hard_header = shaper_header; - } - else - shdev->hard_header = NULL; - if(dev->rebuild_header) - { - sh->rebuild_header = dev->rebuild_header; - shdev->rebuild_header = shaper_rebuild_header; - } - else - shdev->rebuild_header = NULL; - -#if 0 - if(dev->hard_header_cache) - { - sh->hard_header_cache = dev->hard_header_cache; - shdev->hard_header_cache= shaper_cache; - } - else - { - shdev->hard_header_cache= NULL; - } - - if(dev->header_cache_update) - { - sh->header_cache_update = dev->header_cache_update; - shdev->header_cache_update = shaper_cache_update; - } - else - shdev->header_cache_update= NULL; -#else - shdev->header_cache_update = NULL; - shdev->hard_header_cache = NULL; -#endif shdev->neigh_setup = shaper_neigh_setup_dev; - shdev->hard_header_len=dev->hard_header_len; shdev->type=dev->type; shdev->addr_len=dev->addr_len; @@ -542,12 +509,6 @@ static void __init shaper_setup(struct net_device *dev) * Handlers for when we attach to a device. */ - dev->hard_header = shaper_header; - dev->rebuild_header = shaper_rebuild_header; -#if 0 - dev->hard_header_cache = shaper_cache; - dev->header_cache_update= shaper_cache_update; -#endif dev->neigh_setup = shaper_neigh_setup_dev; dev->do_ioctl = shaper_ioctl; dev->hard_header_len = 0; diff --git a/drivers/net/skfp/skfddi.c b/drivers/net/skfp/skfddi.c index ca508708229d..7cf9b9f35dee 100644 --- a/drivers/net/skfp/skfddi.c +++ b/drivers/net/skfp/skfddi.c @@ -260,7 +260,6 @@ static int skfp_init_one(struct pci_dev *pdev, dev->set_multicast_list = &skfp_ctl_set_multicast_list; dev->set_mac_address = &skfp_ctl_set_mac_address; dev->do_ioctl = &skfp_ioctl; - dev->header_cache_update = NULL; /* not supported */ SET_NETDEV_DEV(dev, &pdev->dev); diff --git a/drivers/net/wan/cycx_x25.c b/drivers/net/wan/cycx_x25.c index 46e053106d4d..8a1778cf98d1 100644 --- a/drivers/net/wan/cycx_x25.c +++ b/drivers/net/wan/cycx_x25.c @@ -131,14 +131,15 @@ static int cycx_wan_update(struct wan_device *wandev), cycx_wan_del_if(struct wan_device *wandev, struct net_device *dev); /* Network device interface */ -static int cycx_netdevice_init(struct net_device *dev), - cycx_netdevice_open(struct net_device *dev), - cycx_netdevice_stop(struct net_device *dev), - cycx_netdevice_hard_header(struct sk_buff *skb, - struct net_device *dev, u16 type, - void *daddr, void *saddr, unsigned len), - cycx_netdevice_rebuild_header(struct sk_buff *skb), - cycx_netdevice_hard_start_xmit(struct sk_buff *skb, +static int cycx_netdevice_init(struct net_device *dev); +static int cycx_netdevice_open(struct net_device *dev); +static int cycx_netdevice_stop(struct net_device *dev); +static int cycx_netdevice_hard_header(struct sk_buff *skb, + struct net_device *dev, u16 type, + const void *daddr, const void *saddr, + unsigned len); +static int cycx_netdevice_rebuild_header(struct sk_buff *skb); +static int cycx_netdevice_hard_start_xmit(struct sk_buff *skb, struct net_device *dev); static struct net_device_stats * @@ -468,7 +469,14 @@ static int cycx_wan_del_if(struct wan_device *wandev, struct net_device *dev) return 0; } + /* Network Device Interface */ + +static const struct header_ops cycx_header_ops = { + .create = cycx_netdevice_hard_header, + .rebuild = cycx_netdevice_rebuild_header, +}; + /* Initialize Linux network interface. * * This routine is called only once for each interface, during Linux network @@ -483,8 +491,8 @@ static int cycx_netdevice_init(struct net_device *dev) /* Initialize device driver entry points */ dev->open = cycx_netdevice_open; dev->stop = cycx_netdevice_stop; - dev->hard_header = cycx_netdevice_hard_header; - dev->rebuild_header = cycx_netdevice_rebuild_header; + dev->header_ops = &cycx_header_ops; + dev->hard_start_xmit = cycx_netdevice_hard_start_xmit; dev->get_stats = cycx_netdevice_get_stats; @@ -554,7 +562,8 @@ static int cycx_netdevice_stop(struct net_device *dev) * Return: media header length. */ static int cycx_netdevice_hard_header(struct sk_buff *skb, struct net_device *dev, u16 type, - void *daddr, void *saddr, unsigned len) + const void *daddr, const void *saddr, + unsigned len) { skb->protocol = type; diff --git a/drivers/net/wan/dlci.c b/drivers/net/wan/dlci.c index bc12810157e0..96b232446c0b 100644 --- a/drivers/net/wan/dlci.c +++ b/drivers/net/wan/dlci.c @@ -66,8 +66,8 @@ static void dlci_setup(struct net_device *); */ static int dlci_header(struct sk_buff *skb, struct net_device *dev, - unsigned short type, void *daddr, void *saddr, - unsigned len) + unsigned short type, const void *daddr, + const void *saddr, unsigned len) { struct frhdr hdr; struct dlci_local *dlp; @@ -485,6 +485,10 @@ static int dlci_ioctl(unsigned int cmd, void __user *arg) return(err); } +static const struct header_ops dlci_header_ops = { + .create = dlci_header, +}; + static void dlci_setup(struct net_device *dev) { struct dlci_local *dlp = dev->priv; @@ -494,7 +498,7 @@ static void dlci_setup(struct net_device *dev) dev->stop = dlci_close; dev->do_ioctl = dlci_dev_ioctl; dev->hard_start_xmit = dlci_transmit; - dev->hard_header = dlci_header; + dev->header_ops = &dlci_header_ops; dev->get_stats = dlci_get_stats; dev->change_mtu = dlci_change_mtu; dev->destructor = free_netdev; diff --git a/drivers/net/wan/hdlc.c b/drivers/net/wan/hdlc.c index ee23b91f23d9..d553e6f32851 100644 --- a/drivers/net/wan/hdlc.c +++ b/drivers/net/wan/hdlc.c @@ -232,6 +232,8 @@ int hdlc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) return -EINVAL; } +static const struct header_ops hdlc_null_ops; + static void hdlc_setup_dev(struct net_device *dev) { /* Re-init all variables changed by HDLC protocol drivers, @@ -243,13 +245,9 @@ static void hdlc_setup_dev(struct net_device *dev) dev->type = ARPHRD_RAWHDLC; dev->hard_header_len = 16; dev->addr_len = 0; - dev->hard_header = NULL; - dev->rebuild_header = NULL; - dev->set_mac_address = NULL; - dev->hard_header_cache = NULL; - dev->header_cache_update = NULL; + dev->header_ops = &hdlc_null_ops; + dev->change_mtu = hdlc_change_mtu; - dev->hard_header_parse = NULL; } static void hdlc_setup(struct net_device *dev) diff --git a/drivers/net/wan/hdlc_cisco.c b/drivers/net/wan/hdlc_cisco.c index 9ec6cf2e510e..038a6e748bbf 100644 --- a/drivers/net/wan/hdlc_cisco.c +++ b/drivers/net/wan/hdlc_cisco.c @@ -74,7 +74,7 @@ static inline struct cisco_state * state(hdlc_device *hdlc) static int cisco_hard_header(struct sk_buff *skb, struct net_device *dev, - u16 type, void *daddr, void *saddr, + u16 type, const void *daddr, const void *saddr, unsigned int len) { struct hdlc_header *data; @@ -309,7 +309,6 @@ static void cisco_stop(struct net_device *dev) } - static struct hdlc_proto proto = { .start = cisco_start, .stop = cisco_stop, @@ -317,7 +316,10 @@ static struct hdlc_proto proto = { .ioctl = cisco_ioctl, .module = THIS_MODULE, }; - + +static const struct header_ops cisco_header_ops = { + .create = cisco_hard_header, +}; static int cisco_ioctl(struct net_device *dev, struct ifreq *ifr) { @@ -365,7 +367,7 @@ static int cisco_ioctl(struct net_device *dev, struct ifreq *ifr) memcpy(&state(hdlc)->settings, &new_settings, size); dev->hard_start_xmit = hdlc->xmit; - dev->hard_header = cisco_hard_header; + dev->header_ops = &cisco_header_ops; dev->type = ARPHRD_CISCO; netif_dormant_on(dev); return 0; diff --git a/drivers/net/wan/hdlc_ppp.c b/drivers/net/wan/hdlc_ppp.c index 4591437dd2f3..3caeb528eace 100644 --- a/drivers/net/wan/hdlc_ppp.c +++ b/drivers/net/wan/hdlc_ppp.c @@ -73,7 +73,7 @@ static void ppp_close(struct net_device *dev) sppp_close(dev); sppp_detach(dev); - dev->rebuild_header = NULL; + dev->change_mtu = state(hdlc)->old_change_mtu; dev->mtu = HDLC_MAX_MTU; dev->hard_header_len = 16; diff --git a/drivers/net/wan/lmc/lmc_proto.c b/drivers/net/wan/lmc/lmc_proto.c index 31e1799571ad..426c0678d983 100644 --- a/drivers/net/wan/lmc/lmc_proto.c +++ b/drivers/net/wan/lmc/lmc_proto.c @@ -111,7 +111,7 @@ void lmc_proto_attach(lmc_softc_t *sc) /*FOLD00*/ * They set a few basics because they don't use sync_ppp */ dev->flags |= IFF_POINTOPOINT; - dev->hard_header = NULL; + dev->hard_header_len = 0; dev->addr_len = 0; } diff --git a/drivers/net/wan/syncppp.c b/drivers/net/wan/syncppp.c index 5c71af6ea3a5..232ecba5340f 100644 --- a/drivers/net/wan/syncppp.c +++ b/drivers/net/wan/syncppp.c @@ -359,8 +359,10 @@ done: * Handle transmit packets. */ -static int sppp_hard_header(struct sk_buff *skb, struct net_device *dev, __u16 type, - void *daddr, void *saddr, unsigned int len) +static int sppp_hard_header(struct sk_buff *skb, + struct net_device *dev, __u16 type, + const void *daddr, const void *saddr, + unsigned int len) { struct sppp *sp = (struct sppp *)sppp_of(dev); struct ppp_header *h; @@ -392,10 +394,9 @@ static int sppp_hard_header(struct sk_buff *skb, struct net_device *dev, __u16 t return sizeof(struct ppp_header); } -static int sppp_rebuild_header(struct sk_buff *skb) -{ - return 0; -} +static const struct header_ops sppp_header_ops = { + .create = sppp_hard_header, +}; /* * Send keepalive packets, every 10 seconds. @@ -1098,8 +1099,8 @@ void sppp_attach(struct ppp_device *pd) * hard_start_xmit. */ - dev->hard_header = sppp_hard_header; - dev->rebuild_header = sppp_rebuild_header; + dev->header_ops = &sppp_header_ops; + dev->tx_queue_len = 10; dev->type = ARPHRD_HDLC; dev->addr_len = 0; @@ -1115,8 +1116,6 @@ void sppp_attach(struct ppp_device *pd) dev->stop = sppp_close; #endif dev->change_mtu = sppp_change_mtu; - dev->hard_header_cache = NULL; - dev->header_cache_update = NULL; dev->flags = IFF_MULTICAST|IFF_POINTOPOINT|IFF_NOARP; } diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c index cd03a61359aa..074055e18c5c 100644 --- a/drivers/net/wireless/airo.c +++ b/drivers/net/wireless/airo.c @@ -2696,9 +2696,13 @@ static int mpi_map_card(struct airo_info *ai, struct pci_dev *pci) return rc; } +static const struct header_ops airo_header_ops = { + .parse = wll_header_parse, +}; + static void wifi_setup(struct net_device *dev) { - dev->hard_header_parse = wll_header_parse; + dev->header_ops = &airo_header_ops; dev->hard_start_xmit = &airo_start_xmit11; dev->get_stats = &airo_get_stats; dev->set_mac_address = &airo_set_mac_address; diff --git a/drivers/net/wireless/hostap/hostap.h b/drivers/net/wireless/hostap/hostap.h index ef37a75d550b..951df83702f9 100644 --- a/drivers/net/wireless/hostap/hostap.h +++ b/drivers/net/wireless/hostap/hostap.h @@ -30,8 +30,7 @@ void hostap_dump_rx_header(const char *name, const struct hfa384x_rx_frame *rx); void hostap_dump_tx_header(const char *name, const struct hfa384x_tx_frame *tx); -int hostap_80211_header_parse(struct sk_buff *skb, unsigned char *haddr); -int hostap_80211_prism_header_parse(struct sk_buff *skb, unsigned char *haddr); +extern const struct header_ops hostap_80211_ops; int hostap_80211_get_hdrlen(u16 fc); struct net_device_stats *hostap_get_stats(struct net_device *dev); void hostap_setup_dev(struct net_device *dev, local_info_t *local, diff --git a/drivers/net/wireless/hostap/hostap_hw.c b/drivers/net/wireless/hostap/hostap_hw.c index 7fa7ab0a4b23..b20bb013d57e 100644 --- a/drivers/net/wireless/hostap/hostap_hw.c +++ b/drivers/net/wireless/hostap/hostap_hw.c @@ -3258,11 +3258,10 @@ while (0) INIT_LIST_HEAD(&local->bss_list); hostap_setup_dev(dev, local, 1); - local->saved_eth_header_parse = dev->hard_header_parse; dev->hard_start_xmit = hostap_master_start_xmit; dev->type = ARPHRD_IEEE80211; - dev->hard_header_parse = hostap_80211_header_parse; + dev->header_ops = &hostap_80211_ops; rtnl_lock(); ret = dev_alloc_name(dev, "wifi%d"); diff --git a/drivers/net/wireless/hostap/hostap_ioctl.c b/drivers/net/wireless/hostap/hostap_ioctl.c index 7036ecff5ec1..40f516d42c5e 100644 --- a/drivers/net/wireless/hostap/hostap_ioctl.c +++ b/drivers/net/wireless/hostap/hostap_ioctl.c @@ -897,11 +897,8 @@ static void hostap_monitor_set_type(local_info_t *local) if (local->monitor_type == PRISM2_MONITOR_PRISM || local->monitor_type == PRISM2_MONITOR_CAPHDR) { dev->type = ARPHRD_IEEE80211_PRISM; - dev->hard_header_parse = - hostap_80211_prism_header_parse; } else { dev->type = ARPHRD_IEEE80211; - dev->hard_header_parse = hostap_80211_header_parse; } } @@ -1141,7 +1138,7 @@ static int hostap_monitor_mode_disable(local_info_t *local) printk(KERN_DEBUG "%s: Disabling monitor mode\n", dev->name); dev->type = ARPHRD_ETHER; - dev->hard_header_parse = local->saved_eth_header_parse; + if (local->func->cmd(dev, HFA384X_CMDCODE_TEST | (HFA384X_TEST_STOP << 8), 0, NULL, NULL)) diff --git a/drivers/net/wireless/hostap/hostap_main.c b/drivers/net/wireless/hostap/hostap_main.c index 4cb09d81b404..b75cf9205ce0 100644 --- a/drivers/net/wireless/hostap/hostap_main.c +++ b/drivers/net/wireless/hostap/hostap_main.c @@ -594,24 +594,27 @@ void hostap_dump_tx_header(const char *name, const struct hfa384x_tx_frame *tx) } -int hostap_80211_header_parse(struct sk_buff *skb, unsigned char *haddr) +int hostap_80211_header_parse(const struct sk_buff *skb, unsigned char *haddr) { - memcpy(haddr, skb_mac_header(skb) + 10, ETH_ALEN); /* addr2 */ - return ETH_ALEN; -} - + struct hostap_interface *iface = netdev_priv(skb->dev); + local_info_t *local = iface->local; + + if (local->monitor_type == PRISM2_MONITOR_PRISM || + local->monitor_type == PRISM2_MONITOR_CAPHDR) { + const unsigned char *mac = skb_mac_header(skb); + + if (*(u32 *)mac == LWNG_CAP_DID_BASE) { + memcpy(haddr, + mac + sizeof(struct linux_wlan_ng_prism_hdr) + 10, + ETH_ALEN); /* addr2 */ + } else { /* (*(u32 *)mac == htonl(LWNG_CAPHDR_VERSION)) */ + memcpy(haddr, + mac + sizeof(struct linux_wlan_ng_cap_hdr) + 10, + ETH_ALEN); /* addr2 */ + } + } else + memcpy(haddr, skb_mac_header(skb) + 10, ETH_ALEN); /* addr2 */ -int hostap_80211_prism_header_parse(struct sk_buff *skb, unsigned char *haddr) -{ - const unsigned char *mac = skb_mac_header(skb); - - if (*(u32 *)mac == LWNG_CAP_DID_BASE) { - memcpy(haddr, mac + sizeof(struct linux_wlan_ng_prism_hdr) + 10, - ETH_ALEN); /* addr2 */ - } else { /* (*(u32 *)mac == htonl(LWNG_CAPHDR_VERSION)) */ - memcpy(haddr, mac + sizeof(struct linux_wlan_ng_cap_hdr) + 10, - ETH_ALEN); /* addr2 */ - } return ETH_ALEN; } @@ -843,6 +846,15 @@ static void prism2_tx_timeout(struct net_device *dev) local->func->schedule_reset(local); } +const struct header_ops hostap_80211_ops = { + .create = eth_header, + .rebuild = eth_rebuild_header, + .cache = eth_header_cache, + .cache_update = eth_header_cache_update, + + .parse = hostap_80211_header_parse, +}; +EXPORT_SYMBOL(hostap_80211_ops); void hostap_setup_dev(struct net_device *dev, local_info_t *local, int main_dev) @@ -883,7 +895,6 @@ void hostap_setup_dev(struct net_device *dev, local_info_t *local, netif_stop_queue(dev); } - static int hostap_enable_hostapd(local_info_t *local, int rtnl_locked) { struct net_device *dev = local->dev; @@ -901,7 +912,7 @@ static int hostap_enable_hostapd(local_info_t *local, int rtnl_locked) local->apdev->hard_start_xmit = hostap_mgmt_start_xmit; local->apdev->type = ARPHRD_IEEE80211; - local->apdev->hard_header_parse = hostap_80211_header_parse; + local->apdev->header_ops = &hostap_80211_ops; return 0; } diff --git a/drivers/net/wireless/hostap/hostap_wlan.h b/drivers/net/wireless/hostap/hostap_wlan.h index a42325c145b4..c27b2c1c06af 100644 --- a/drivers/net/wireless/hostap/hostap_wlan.h +++ b/drivers/net/wireless/hostap/hostap_wlan.h @@ -736,8 +736,6 @@ struct local_info { PRISM2_MONITOR_80211 = 0, PRISM2_MONITOR_PRISM = 1, PRISM2_MONITOR_CAPHDR = 2 } monitor_type; - int (*saved_eth_header_parse)(struct sk_buff *skb, - unsigned char *haddr); int monitor_allow_fcserr; int hostapd; /* whether user space daemon, hostapd, is used for AP diff --git a/drivers/net/wireless/strip.c b/drivers/net/wireless/strip.c index 404cd1512312..4bd14b331862 100644 --- a/drivers/net/wireless/strip.c +++ b/drivers/net/wireless/strip.c @@ -1631,8 +1631,8 @@ static void strip_IdleTask(unsigned long parameter) */ static int strip_header(struct sk_buff *skb, struct net_device *dev, - unsigned short type, void *daddr, void *saddr, - unsigned len) + unsigned short type, const void *daddr, + const void *saddr, unsigned len) { struct strip *strip_info = netdev_priv(dev); STRIP_Header *header = (STRIP_Header *) skb_push(skb, sizeof(STRIP_Header)); @@ -2497,6 +2497,11 @@ static int strip_close_low(struct net_device *dev) return 0; } +static const struct header_ops strip_header_ops = { + .create = strip_header, + .rebuild = strip_rebuild_header, +}; + /* * This routine is called by DDI when the * (dynamically assigned) device is registered @@ -2531,8 +2536,8 @@ static void strip_dev_setup(struct net_device *dev) dev->open = strip_open_low; dev->stop = strip_close_low; dev->hard_start_xmit = strip_xmit; - dev->hard_header = strip_header; - dev->rebuild_header = strip_rebuild_header; + dev->header_ops = &strip_header_ops; + dev->set_mac_address = strip_set_mac_address; dev->get_stats = strip_get_stats; dev->change_mtu = strip_change_mtu; diff --git a/drivers/s390/net/qeth.h b/drivers/s390/net/qeth.h index 6d4959807abc..8c6b72d05b1d 100644 --- a/drivers/s390/net/qeth.h +++ b/drivers/s390/net/qeth.h @@ -833,8 +833,7 @@ struct qeth_card { struct qeth_qdio_info qdio; struct qeth_perf_stats perf_stats; int use_hard_stop; - int (*orig_hard_header)(struct sk_buff *,struct net_device *, - unsigned short,void *,void *,unsigned); + const struct header_ops *orig_header_ops; struct qeth_osn_info osn_info; atomic_t force_alloc_skb; }; diff --git a/drivers/s390/net/qeth_main.c b/drivers/s390/net/qeth_main.c index 65225b3989dd..778ddfb99077 100644 --- a/drivers/s390/net/qeth_main.c +++ b/drivers/s390/net/qeth_main.c @@ -160,6 +160,9 @@ qeth_set_multicast_list(struct net_device *); static void qeth_setadp_promisc_mode(struct qeth_card *); +static int +qeth_hard_header_parse(const struct sk_buff *skb, unsigned char *haddr); + static void qeth_notify_processes(void) { @@ -3787,8 +3790,8 @@ qeth_get_netdevice(enum qeth_card_types type, enum qeth_link_types linktype) /*hard_header fake function; used in case fake_ll is set */ static int qeth_fake_header(struct sk_buff *skb, struct net_device *dev, - unsigned short type, void *daddr, void *saddr, - unsigned len) + unsigned short type, const void *daddr, const void *saddr, + unsigned len) { if(dev->type == ARPHRD_IEEE802_TR){ struct trh_hdr *hdr; @@ -3811,6 +3814,11 @@ qeth_fake_header(struct sk_buff *skb, struct net_device *dev, } } +static const struct header_ops qeth_fake_ops = { + .create = qeth_fake_header, + .parse = qeth_hard_header_parse, +}; + static int qeth_send_packet(struct qeth_card *, struct sk_buff *); @@ -4649,7 +4657,7 @@ qeth_send_packet(struct qeth_card *card, struct sk_buff *skb) [qeth_get_priority_queue(card, skb, ipv, cast_type)]; if (!card->options.layer2) { ipv = qeth_get_ip_version(skb); - if ((card->dev->hard_header == qeth_fake_header) && ipv) { + if ((card->dev->header_ops == &qeth_fake_ops) && ipv) { new_skb = qeth_pskb_unshare(skb, GFP_ATOMIC); if (!new_skb) return -ENOMEM; @@ -6566,6 +6574,9 @@ qeth_hard_header_parse(const struct sk_buff *skb, unsigned char *haddr) const struct qeth_card *card; const struct ethhdr *eth; + if (dev->type != ARPHRD_IEEE802_TR) + return 0; + card = qeth_get_card_from_dev(skb->dev); if (card->options.layer2) goto haveheader; @@ -6596,6 +6607,10 @@ haveheader: return ETH_ALEN; } +static const struct header_ops qeth_null_ops = { + .parse = qeth_hard_header_parse, +}; + static int qeth_netdev_init(struct net_device *dev) { @@ -6620,12 +6635,8 @@ qeth_netdev_init(struct net_device *dev) dev->vlan_rx_kill_vid = qeth_vlan_rx_kill_vid; dev->vlan_rx_add_vid = qeth_vlan_rx_add_vid; #endif - if (qeth_get_netdev_flags(card) & IFF_NOARP) { - dev->rebuild_header = NULL; - dev->hard_header = NULL; - dev->header_cache_update = NULL; - dev->hard_header_cache = NULL; - } + dev->header_ops = &qeth_null_ops; + #ifdef CONFIG_QETH_IPV6 /*IPv6 address autoconfiguration stuff*/ if (!(card->info.unique_id & UNIQUE_ID_NOT_BY_CARD)) @@ -6633,11 +6644,8 @@ qeth_netdev_init(struct net_device *dev) #endif if (card->options.fake_ll && (qeth_get_netdev_flags(card) & IFF_NOARP)) - dev->hard_header = qeth_fake_header; - if (dev->type == ARPHRD_IEEE802_TR) - dev->hard_header_parse = NULL; - else - dev->hard_header_parse = qeth_hard_header_parse; + dev->header_ops = &qeth_fake_ops; + dev->set_mac_address = qeth_layer2_set_mac_address; dev->flags |= qeth_get_netdev_flags(card); if ((card->options.fake_broadcast) || @@ -6740,10 +6748,10 @@ retry: } /*network device will be recovered*/ if (card->dev) { - card->dev->hard_header = card->orig_hard_header; + card->dev->header_ops = card->orig_header_ops; if (card->options.fake_ll && (qeth_get_netdev_flags(card) & IFF_NOARP)) - card->dev->hard_header = qeth_fake_header; + card->dev->header_ops = &qeth_fake_ops; return 0; } /* at first set_online allocate netdev */ @@ -6757,7 +6765,7 @@ retry: goto out; } card->dev->priv = card; - card->orig_hard_header = card->dev->hard_header; + card->orig_header_ops = card->dev->header_ops; card->dev->type = qeth_get_arphdr_type(card->info.type, card->info.link_type); card->dev->init = qeth_netdev_init; @@ -8308,7 +8316,7 @@ qeth_arp_constructor(struct neighbour *neigh) if (card == NULL) goto out; if((card->options.layer2) || - (card->dev->hard_header == qeth_fake_header)) + (card->dev->header_ops == &qeth_fake_ops)) goto out; rcu_read_lock(); diff --git a/include/linux/etherdevice.h b/include/linux/etherdevice.h index 6cdb97365e47..b7558ec81ed5 100644 --- a/include/linux/etherdevice.h +++ b/include/linux/etherdevice.h @@ -29,15 +29,19 @@ #include #ifdef __KERNEL__ -extern int eth_header(struct sk_buff *skb, struct net_device *dev, - unsigned short type, void *daddr, - void *saddr, unsigned len); -extern int eth_rebuild_header(struct sk_buff *skb); extern __be16 eth_type_trans(struct sk_buff *skb, struct net_device *dev); -extern void eth_header_cache_update(struct hh_cache *hh, struct net_device *dev, - unsigned char * haddr); -extern int eth_header_cache(struct neighbour *neigh, - struct hh_cache *hh); +extern const struct header_ops eth_header_ops; + +extern int eth_header(struct sk_buff *skb, struct net_device *dev, + unsigned short type, + const void *daddr, const void *saddr, unsigned len); +extern int eth_rebuild_header(struct sk_buff *skb); +extern int eth_header_parse(const struct sk_buff *skb, unsigned char *haddr); +extern int eth_header_cache(const struct neighbour *neigh, struct hh_cache *hh); +extern void eth_header_cache_update(struct hh_cache *hh, + const struct net_device *dev, + const unsigned char *haddr); + extern struct net_device *alloc_etherdev_mq(int sizeof_priv, unsigned int queue_count); #define alloc_etherdev(sizeof_priv) alloc_etherdev_mq(sizeof_priv, 1) diff --git a/include/linux/if_ether.h b/include/linux/if_ether.h index 0e791e2c0c5a..5f9297793661 100644 --- a/include/linux/if_ether.h +++ b/include/linux/if_ether.h @@ -117,6 +117,8 @@ static inline struct ethhdr *eth_hdr(const struct sk_buff *skb) return (struct ethhdr *)skb_mac_header(skb); } +int eth_header_parse(const struct sk_buff *skb, unsigned char *haddr); + #ifdef CONFIG_SYSCTL extern struct ctl_table ether_table[]; #endif diff --git a/include/linux/if_shaper.h b/include/linux/if_shaper.h index 51574743aa1b..3b1b7ba19825 100644 --- a/include/linux/if_shaper.h +++ b/include/linux/if_shaper.h @@ -25,17 +25,6 @@ struct shaper an empty queue */ spinlock_t lock; struct net_device *dev; - int (*hard_start_xmit) (struct sk_buff *skb, - struct net_device *dev); - int (*hard_header) (struct sk_buff *skb, - struct net_device *dev, - unsigned short type, - void *daddr, - void *saddr, - unsigned len); - int (*rebuild_header)(struct sk_buff *skb); - int (*hard_header_cache)(struct neighbour *neigh, struct hh_cache *hh); - void (*header_cache_update)(struct hh_cache *hh, struct net_device *dev, unsigned char * haddr); struct net_device_stats* (*get_stats)(struct net_device *dev); struct timer_list timer; }; diff --git a/include/linux/isdn.h b/include/linux/isdn.h index 3c7875b7ab5b..a6fb366748bb 100644 --- a/include/linux/isdn.h +++ b/include/linux/isdn.h @@ -353,13 +353,6 @@ typedef struct isdn_net_local_s { /* a particular channel (including */ /* the frame_cnt */ - int (*org_hhc)( - struct neighbour *neigh, - struct hh_cache *hh); - /* Ptr to orig. header_cache_update */ - void (*org_hcu)(struct hh_cache *, - struct net_device *, - unsigned char *); int pppbind; /* ippp device for bindings */ int dialtimeout; /* How long shall we try on dialing? (jiffies) */ int dialwait; /* How long shall we wait after failed attempt? (jiffies) */ diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index aae9ec367f5d..91cd3f3db507 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -250,6 +250,19 @@ struct hh_cache #define LL_RESERVED_SPACE_EXTRA(dev,extra) \ ((((dev)->hard_header_len+extra)&~(HH_DATA_MOD - 1)) + HH_DATA_MOD) +struct header_ops { + int (*create) (struct sk_buff *skb, struct net_device *dev, + unsigned short type, const void *daddr, + const void *saddr, unsigned len); + int (*parse)(const struct sk_buff *skb, unsigned char *haddr); + int (*rebuild)(struct sk_buff *skb); +#define HAVE_HEADER_CACHE + int (*cache)(const struct neighbour *neigh, struct hh_cache *hh); + void (*cache_update)(struct hh_cache *hh, + const struct net_device *dev, + const unsigned char *haddr); +}; + /* These flag bits are private to the generic network queueing * layer, they may not be explicitly referenced by any other * code. @@ -492,6 +505,9 @@ struct net_device #endif const struct ethtool_ops *ethtool_ops; + /* Hardware header description */ + const struct header_ops *header_ops; + /* * This marks the end of the "visible" part of the structure. All * fields hereafter are internal to the system, and may change at @@ -615,13 +631,6 @@ struct net_device int (*open)(struct net_device *dev); int (*stop)(struct net_device *dev); #define HAVE_NETDEV_POLL - int (*hard_header) (struct sk_buff *skb, - struct net_device *dev, - unsigned short type, - void *daddr, - void *saddr, - unsigned len); - int (*rebuild_header)(struct sk_buff *skb); #define HAVE_CHANGE_RX_FLAGS void (*change_rx_flags)(struct net_device *dev, int flags); @@ -638,12 +647,6 @@ struct net_device #define HAVE_SET_CONFIG int (*set_config)(struct net_device *dev, struct ifmap *map); -#define HAVE_HEADER_CACHE - int (*hard_header_cache)(struct neighbour *neigh, - struct hh_cache *hh); - void (*header_cache_update)(struct hh_cache *hh, - struct net_device *dev, - unsigned char * haddr); #define HAVE_CHANGE_MTU int (*change_mtu)(struct net_device *dev, int new_mtu); @@ -657,8 +660,6 @@ struct net_device void (*vlan_rx_kill_vid)(struct net_device *dev, unsigned short vid); - int (*hard_header_parse)(const struct sk_buff *skb, - unsigned char *haddr); int (*neigh_setup)(struct net_device *dev, struct neigh_parms *); #ifdef CONFIG_NETPOLL struct netpoll_info *npinfo; @@ -802,11 +803,13 @@ extern int netpoll_trap(void); static inline int dev_hard_header(struct sk_buff *skb, struct net_device *dev, unsigned short type, - void *daddr, void *saddr, unsigned len) + const void *daddr, const void *saddr, + unsigned len) { - if (!dev->hard_header) + if (!dev->header_ops) return 0; - return dev->hard_header(skb, dev, type, daddr, saddr, len); + + return dev->header_ops->create(skb, dev, type, daddr, saddr, len); } static inline int dev_parse_header(const struct sk_buff *skb, @@ -814,9 +817,9 @@ static inline int dev_parse_header(const struct sk_buff *skb, { const struct net_device *dev = skb->dev; - if (!dev->hard_header_parse) + if (!dev->header_ops->parse) return 0; - return dev->hard_header_parse(skb, haddr); + return dev->header_ops->parse(skb, haddr); } typedef int gifconf_func_t(struct net_device * dev, char __user * bufptr, int len); diff --git a/include/net/ax25.h b/include/net/ax25.h index 99a4e364c74a..4e3cd93f81fc 100644 --- a/include/net/ax25.h +++ b/include/net/ax25.h @@ -363,8 +363,11 @@ extern int ax25_rx_iframe(ax25_cb *, struct sk_buff *); extern int ax25_kiss_rcv(struct sk_buff *, struct net_device *, struct packet_type *, struct net_device *); /* ax25_ip.c */ -extern int ax25_hard_header(struct sk_buff *, struct net_device *, unsigned short, void *, void *, unsigned int); +extern int ax25_hard_header(struct sk_buff *, struct net_device *, + unsigned short, const void *, + const void *, unsigned int); extern int ax25_rebuild_header(struct sk_buff *); +extern const struct header_ops ax25_header_ops; /* ax25_out.c */ extern ax25_cb *ax25_send_frame(struct sk_buff *, int, ax25_address *, ax25_address *, ax25_digi *, struct net_device *); diff --git a/include/net/pkt_sched.h b/include/net/pkt_sched.h index 9e22526e80e7..ab61809a9616 100644 --- a/include/net/pkt_sched.h +++ b/include/net/pkt_sched.h @@ -97,10 +97,9 @@ extern int tc_classify(struct sk_buff *skb, struct tcf_proto *tp, /* Calculate maximal size of packet seen by hard_start_xmit routine of this device. */ -static inline unsigned psched_mtu(struct net_device *dev) +static inline unsigned psched_mtu(const struct net_device *dev) { - unsigned mtu = dev->mtu; - return dev->hard_header ? mtu + dev->hard_header_len : mtu; + return dev->mtu + dev->hard_header_len; } #endif diff --git a/net/802/fc.c b/net/802/fc.c index 675d9ba8e591..cb3475ea6fda 100644 --- a/net/802/fc.c +++ b/net/802/fc.c @@ -35,7 +35,7 @@ static int fc_header(struct sk_buff *skb, struct net_device *dev, unsigned short type, - void *daddr, void *saddr, unsigned len) + const void *daddr, const void *saddr, unsigned len) { struct fch_hdr *fch; int hdr_len; @@ -95,11 +95,14 @@ static int fc_rebuild_header(struct sk_buff *skb) #endif } +static const struct header_ops fc_header_ops = { + .create = fc_header, + .rebuild = fc_rebuild_header, +}; + static void fc_setup(struct net_device *dev) { - dev->hard_header = fc_header; - dev->rebuild_header = fc_rebuild_header; - + dev->header_ops = &fc_header_ops; dev->type = ARPHRD_IEEE802; dev->hard_header_len = FC_HLEN; dev->mtu = 2024; diff --git a/net/802/fddi.c b/net/802/fddi.c index 91dde41b5481..0549317b9356 100644 --- a/net/802/fddi.c +++ b/net/802/fddi.c @@ -52,7 +52,7 @@ static int fddi_header(struct sk_buff *skb, struct net_device *dev, unsigned short type, - void *daddr, void *saddr, unsigned len) + const void *daddr, const void *saddr, unsigned len) { int hl = FDDI_K_SNAP_HLEN; struct fddihdr *fddi; @@ -175,11 +175,15 @@ static int fddi_change_mtu(struct net_device *dev, int new_mtu) return(0); } +static const struct header_ops fddi_header_ops = { + .create = fddi_header, + .rebuild = fddi_rebuild_header, +}; + static void fddi_setup(struct net_device *dev) { dev->change_mtu = fddi_change_mtu; - dev->hard_header = fddi_header; - dev->rebuild_header = fddi_rebuild_header; + dev->header_ops = &fddi_header_ops; dev->type = ARPHRD_FDDI; dev->hard_header_len = FDDI_K_SNAP_HLEN+3; /* Assume 802.2 SNAP hdr len + 3 pad bytes */ diff --git a/net/802/hippi.c b/net/802/hippi.c index 87ffc12b6891..e35dc1e0915d 100644 --- a/net/802/hippi.c +++ b/net/802/hippi.c @@ -45,8 +45,8 @@ */ static int hippi_header(struct sk_buff *skb, struct net_device *dev, - unsigned short type, void *daddr, void *saddr, - unsigned len) + unsigned short type, + const void *daddr, const void *saddr, unsigned len) { struct hippi_hdr *hip = (struct hippi_hdr *)skb_push(skb, HIPPI_HLEN); struct hippi_cb *hcb = (struct hippi_cb *) skb->cb; @@ -182,16 +182,18 @@ static int hippi_neigh_setup_dev(struct net_device *dev, struct neigh_parms *p) return 0; } +static const struct header_ops hippi_header_ops = { + .create = hippi_header, + .rebuild = hippi_rebuild_header, +}; + + static void hippi_setup(struct net_device *dev) { dev->set_multicast_list = NULL; dev->change_mtu = hippi_change_mtu; - dev->hard_header = hippi_header; - dev->rebuild_header = hippi_rebuild_header; + dev->header_ops = &hippi_header_ops; dev->set_mac_address = hippi_mac_addr; - dev->hard_header_parse = NULL; - dev->hard_header_cache = NULL; - dev->header_cache_update = NULL; dev->neigh_setup = hippi_neigh_setup_dev; /* diff --git a/net/802/tr.c b/net/802/tr.c index aa3c2e936abc..a2bd0f2e3af8 100644 --- a/net/802/tr.c +++ b/net/802/tr.c @@ -100,7 +100,7 @@ static inline unsigned long rif_hash(const unsigned char *addr) static int tr_header(struct sk_buff *skb, struct net_device *dev, unsigned short type, - void *daddr, void *saddr, unsigned len) + const void *daddr, const void *saddr, unsigned len) { struct trh_hdr *trh; int hdr_len; @@ -142,7 +142,7 @@ static int tr_header(struct sk_buff *skb, struct net_device *dev, if(daddr) { memcpy(trh->daddr,daddr,dev->addr_len); - tr_source_route(skb,trh,dev); + tr_source_route(skb, trh, dev); return(hdr_len); } @@ -247,7 +247,8 @@ __be16 tr_type_trans(struct sk_buff *skb, struct net_device *dev) * We try to do source routing... */ -void tr_source_route(struct sk_buff *skb,struct trh_hdr *trh,struct net_device *dev) +void tr_source_route(struct sk_buff *skb,struct trh_hdr *trh, + struct net_device *dev) { int slack; unsigned int hash; @@ -592,14 +593,18 @@ static const struct file_operations rif_seq_fops = { #endif +static const struct header_ops tr_header_ops = { + .create = tr_header, + .rebuild= tr_rebuild_header, +}; + static void tr_setup(struct net_device *dev) { /* * Configure and register */ - dev->hard_header = tr_header; - dev->rebuild_header = tr_rebuild_header; + dev->header_ops = &tr_header_ops; dev->type = ARPHRD_IEEE802_TR; dev->hard_header_len = TR_HLEN; diff --git a/net/8021q/vlan.c b/net/8021q/vlan.c index 4d003e391754..f2bee234d361 100644 --- a/net/8021q/vlan.c +++ b/net/8021q/vlan.c @@ -314,6 +314,12 @@ int unregister_vlan_device(struct net_device *dev) */ static struct lock_class_key vlan_netdev_xmit_lock_key; +static const struct header_ops vlan_header_ops = { + .create = vlan_dev_hard_header, + .rebuild = vlan_dev_rebuild_header, + .parse = eth_header_parse, +}; + static int vlan_dev_init(struct net_device *dev) { struct net_device *real_dev = VLAN_DEV_INFO(dev)->real_dev; @@ -331,18 +337,14 @@ static int vlan_dev_init(struct net_device *dev) memcpy(dev->broadcast, real_dev->broadcast, dev->addr_len); if (real_dev->features & NETIF_F_HW_VLAN_TX) { - dev->hard_header = real_dev->hard_header; + dev->header_ops = real_dev->header_ops; dev->hard_header_len = real_dev->hard_header_len; dev->hard_start_xmit = vlan_dev_hwaccel_hard_start_xmit; - dev->rebuild_header = real_dev->rebuild_header; } else { - dev->hard_header = vlan_dev_hard_header; + dev->header_ops = &vlan_header_ops; dev->hard_header_len = real_dev->hard_header_len + VLAN_HLEN; dev->hard_start_xmit = vlan_dev_hard_start_xmit; - dev->rebuild_header = vlan_dev_rebuild_header; } - dev->hard_header_parse = real_dev->hard_header_parse; - dev->hard_header_cache = NULL; lockdep_set_class(&dev->_xmit_lock, &vlan_netdev_xmit_lock_key); return 0; diff --git a/net/8021q/vlan.h b/net/8021q/vlan.h index 7df5b2935579..cf4a80d06b35 100644 --- a/net/8021q/vlan.h +++ b/net/8021q/vlan.h @@ -53,8 +53,8 @@ int vlan_dev_rebuild_header(struct sk_buff *skb); int vlan_skb_recv(struct sk_buff *skb, struct net_device *dev, struct packet_type *ptype, struct net_device *orig_dev); int vlan_dev_hard_header(struct sk_buff *skb, struct net_device *dev, - unsigned short type, void *daddr, void *saddr, - unsigned len); + unsigned short type, const void *daddr, + const void *saddr, unsigned len); int vlan_dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev); int vlan_dev_hwaccel_hard_start_xmit(struct sk_buff *skb, struct net_device *dev); int vlan_dev_change_mtu(struct net_device *dev, int new_mtu); diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c index ca8090fdabbb..1a1740aa9a8b 100644 --- a/net/8021q/vlan_dev.c +++ b/net/8021q/vlan_dev.c @@ -343,8 +343,8 @@ static inline unsigned short vlan_dev_get_egress_qos_mask(struct net_device* dev * physical devices. */ int vlan_dev_hard_header(struct sk_buff *skb, struct net_device *dev, - unsigned short type, void *daddr, void *saddr, - unsigned len) + unsigned short type, + const void *daddr, const void *saddr, unsigned len) { struct vlan_hdr *vhdr; unsigned short veth_TCI = 0; diff --git a/net/appletalk/dev.c b/net/appletalk/dev.c index 9e4dffc1e423..d856a62ab50f 100644 --- a/net/appletalk/dev.c +++ b/net/appletalk/dev.c @@ -24,11 +24,7 @@ static void ltalk_setup(struct net_device *dev) /* Fill in the fields of the device structure with localtalk-generic values. */ dev->change_mtu = ltalk_change_mtu; - dev->hard_header = NULL; - dev->rebuild_header = NULL; dev->set_mac_address = ltalk_mac_addr; - dev->hard_header_cache = NULL; - dev->header_cache_update= NULL; dev->type = ARPHRD_LOCALTLK; dev->hard_header_len = LTALK_HLEN; diff --git a/net/ax25/ax25_ip.c b/net/ax25/ax25_ip.c index 930e4918037f..f047a57aa95c 100644 --- a/net/ax25/ax25_ip.c +++ b/net/ax25/ax25_ip.c @@ -46,7 +46,9 @@ #ifdef CONFIG_INET -int ax25_hard_header(struct sk_buff *skb, struct net_device *dev, unsigned short type, void *daddr, void *saddr, unsigned len) +int ax25_hard_header(struct sk_buff *skb, struct net_device *dev, + unsigned short type, const void *daddr, + const void *saddr, unsigned len) { unsigned char *buff; @@ -215,7 +217,9 @@ put: #else /* INET */ -int ax25_hard_header(struct sk_buff *skb, struct net_device *dev, unsigned short type, void *daddr, void *saddr, unsigned len) +int ax25_hard_header(struct sk_buff *skb, struct net_device *dev, + unsigned short type, const void *daddr, + const void *saddr, unsigned len) { return -AX25_HEADER_LEN; } @@ -227,5 +231,12 @@ int ax25_rebuild_header(struct sk_buff *skb) #endif +const struct header_ops ax25_header_ops = { + .create = ax25_hard_header, + .rebuild = ax25_rebuild_header, +}; + EXPORT_SYMBOL(ax25_hard_header); EXPORT_SYMBOL(ax25_rebuild_header); +EXPORT_SYMBOL(ax25_header_ops); + diff --git a/net/core/dev.c b/net/core/dev.c index 3923d5133050..d99864662582 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -967,14 +967,6 @@ void dev_load(struct net *net, const char *name) request_module("%s", name); } -static int default_rebuild_header(struct sk_buff *skb) -{ - printk(KERN_DEBUG "%s: default_rebuild_header called -- BUG!\n", - skb->dev ? skb->dev->name : "NULL!!!"); - kfree_skb(skb); - return 1; -} - /** * dev_open - prepare an interface for use. * @dev: device to open @@ -3561,14 +3553,6 @@ int register_netdevice(struct net_device *dev) } } - /* - * nil rebuild_header routine, - * that should be never called and used as just bug trap. - */ - - if (!dev->rebuild_header) - dev->rebuild_header = default_rebuild_header; - ret = netdev_register_kobject(dev); if (ret) goto err_uninit; diff --git a/net/core/neighbour.c b/net/core/neighbour.c index 10bcb9f8da5c..c52df858d0be 100644 --- a/net/core/neighbour.c +++ b/net/core/neighbour.c @@ -897,8 +897,8 @@ out_unlock_bh: static void neigh_update_hhs(struct neighbour *neigh) { struct hh_cache *hh; - void (*update)(struct hh_cache*, struct net_device*, unsigned char *) = - neigh->dev->header_cache_update; + void (*update)(struct hh_cache*, const struct net_device*, const unsigned char *) + = neigh->dev->header_ops->cache_update; if (update) { for (hh = neigh->hh; hh; hh = hh->hh_next) { @@ -1095,7 +1095,8 @@ static void neigh_hh_init(struct neighbour *n, struct dst_entry *dst, hh->hh_type = protocol; atomic_set(&hh->hh_refcnt, 0); hh->hh_next = NULL; - if (dev->hard_header_cache(n, hh)) { + + if (dev->header_ops->cache(n, hh)) { kfree(hh); hh = NULL; } else { @@ -1127,7 +1128,7 @@ int neigh_compat_output(struct sk_buff *skb) if (dev_hard_header(skb, dev, ntohs(skb->protocol), NULL, NULL, skb->len) < 0 && - dev->rebuild_header(skb)) + dev->header_ops->rebuild(skb)) return 0; return dev_queue_xmit(skb); @@ -1149,7 +1150,7 @@ int neigh_resolve_output(struct sk_buff *skb) if (!neigh_event_send(neigh, skb)) { int err; struct net_device *dev = neigh->dev; - if (dev->hard_header_cache && !dst->hh) { + if (dev->header_ops->cache && !dst->hh) { write_lock_bh(&neigh->lock); if (!dst->hh) neigh_hh_init(neigh, dst, dst->ops->protocol); diff --git a/net/ethernet/eth.c b/net/ethernet/eth.c index bdeb2f0ace32..ed8a3d49487d 100644 --- a/net/ethernet/eth.c +++ b/net/ethernet/eth.c @@ -75,8 +75,9 @@ __setup("ether=", netdev_boot_setup); * Set the protocol type. For a packet of type ETH_P_802_3 we put the length * in here instead. It is up to the 802.2 layer to carry protocol information. */ -int eth_header(struct sk_buff *skb, struct net_device *dev, unsigned short type, - void *daddr, void *saddr, unsigned len) +int eth_header(struct sk_buff *skb, struct net_device *dev, + unsigned short type, + const void *daddr, const void *saddr, unsigned len) { struct ethhdr *eth = (struct ethhdr *)skb_push(skb, ETH_HLEN); @@ -109,6 +110,7 @@ int eth_header(struct sk_buff *skb, struct net_device *dev, unsigned short type, return -ETH_HLEN; } +EXPORT_SYMBOL(eth_header); /** * eth_rebuild_header- rebuild the Ethernet MAC header. @@ -141,6 +143,7 @@ int eth_rebuild_header(struct sk_buff *skb) return 0; } +EXPORT_SYMBOL(eth_rebuild_header); /** * eth_type_trans - determine the packet's protocol ID. @@ -207,12 +210,13 @@ EXPORT_SYMBOL(eth_type_trans); * @skb: packet to extract header from * @haddr: destination buffer */ -static int eth_header_parse(const struct sk_buff *skb, unsigned char *haddr) +int eth_header_parse(const struct sk_buff *skb, unsigned char *haddr) { const struct ethhdr *eth = eth_hdr(skb); memcpy(haddr, eth->h_source, ETH_ALEN); return ETH_ALEN; } +EXPORT_SYMBOL(eth_header_parse); /** * eth_header_cache - fill cache entry from neighbour @@ -220,11 +224,11 @@ static int eth_header_parse(const struct sk_buff *skb, unsigned char *haddr) * @hh: destination cache entry * Create an Ethernet header template from the neighbour. */ -int eth_header_cache(struct neighbour *neigh, struct hh_cache *hh) +int eth_header_cache(const struct neighbour *neigh, struct hh_cache *hh) { __be16 type = hh->hh_type; struct ethhdr *eth; - struct net_device *dev = neigh->dev; + const struct net_device *dev = neigh->dev; eth = (struct ethhdr *) (((u8 *) hh->hh_data) + (HH_DATA_OFF(sizeof(*eth)))); @@ -238,6 +242,7 @@ int eth_header_cache(struct neighbour *neigh, struct hh_cache *hh) hh->hh_len = ETH_HLEN; return 0; } +EXPORT_SYMBOL(eth_header_cache); /** * eth_header_cache_update - update cache entry @@ -247,12 +252,14 @@ int eth_header_cache(struct neighbour *neigh, struct hh_cache *hh) * * Called by Address Resolution module to notify changes in address. */ -void eth_header_cache_update(struct hh_cache *hh, struct net_device *dev, - unsigned char *haddr) +void eth_header_cache_update(struct hh_cache *hh, + const struct net_device *dev, + const unsigned char *haddr) { memcpy(((u8 *) hh->hh_data) + HH_DATA_OFF(sizeof(struct ethhdr)), haddr, ETH_ALEN); } +EXPORT_SYMBOL(eth_header_cache_update); /** * eth_mac_addr - set new Ethernet hardware address @@ -291,6 +298,14 @@ static int eth_change_mtu(struct net_device *dev, int new_mtu) return 0; } +const struct header_ops eth_header_ops ____cacheline_aligned = { + .create = eth_header, + .parse = eth_header_parse, + .rebuild = eth_rebuild_header, + .cache = eth_header_cache, + .cache_update = eth_header_cache_update, +}; + /** * ether_setup - setup Ethernet network device * @dev: network device @@ -298,13 +313,10 @@ static int eth_change_mtu(struct net_device *dev, int new_mtu) */ void ether_setup(struct net_device *dev) { + dev->header_ops = ð_header_ops; + dev->change_mtu = eth_change_mtu; - dev->hard_header = eth_header; - dev->rebuild_header = eth_rebuild_header; dev->set_mac_address = eth_mac_addr; - dev->hard_header_cache = eth_header_cache; - dev->header_cache_update= eth_header_cache_update; - dev->hard_header_parse = eth_header_parse; dev->type = ARPHRD_ETHER; dev->hard_header_len = ETH_HLEN; diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c index 5b24c65b13c6..d8248198bcd7 100644 --- a/net/ipv4/arp.c +++ b/net/ipv4/arp.c @@ -253,7 +253,7 @@ static int arp_constructor(struct neighbour *neigh) neigh->parms = neigh_parms_clone(parms); rcu_read_unlock(); - if (dev->hard_header == NULL) { + if (!dev->header_ops) { neigh->nud_state = NUD_NOARP; neigh->ops = &arp_direct_ops; neigh->output = neigh->ops->queue_xmit; @@ -310,10 +310,12 @@ static int arp_constructor(struct neighbour *neigh) neigh->nud_state = NUD_NOARP; memcpy(neigh->ha, dev->broadcast, dev->addr_len); } - if (dev->hard_header_cache) + + if (dev->header_ops->cache) neigh->ops = &arp_hh_ops; else neigh->ops = &arp_generic_ops; + if (neigh->nud_state&NUD_VALID) neigh->output = neigh->ops->connected_output; else diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c index ffa9f1c9dcbb..f151900efaf9 100644 --- a/net/ipv4/ip_gre.c +++ b/net/ipv4/ip_gre.c @@ -684,7 +684,7 @@ static int ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev) goto tx_error; } - if (dev->hard_header) { + if (dev->header_ops) { gre_hlen = 0; tiph = (struct iphdr*)skb->data; } else { @@ -1063,8 +1063,9 @@ static int ipgre_tunnel_change_mtu(struct net_device *dev, int new_mtu) */ -static int ipgre_header(struct sk_buff *skb, struct net_device *dev, unsigned short type, - void *daddr, void *saddr, unsigned len) +static int ipgre_header(struct sk_buff *skb, struct net_device *dev, + unsigned short type, + const void *daddr, const void *saddr, unsigned len) { struct ip_tunnel *t = netdev_priv(dev); struct iphdr *iph = (struct iphdr *)skb_push(skb, t->hlen); @@ -1091,6 +1092,10 @@ static int ipgre_header(struct sk_buff *skb, struct net_device *dev, unsigned sh return -t->hlen; } +static const struct header_ops ipgre_header_ops = { + .create = ipgre_header, +}; + static int ipgre_open(struct net_device *dev) { struct ip_tunnel *t = netdev_priv(dev); @@ -1187,7 +1192,7 @@ static int ipgre_tunnel_init(struct net_device *dev) if (!iph->saddr) return -EINVAL; dev->flags = IFF_BROADCAST; - dev->hard_header = ipgre_header; + dev->header_ops = &ipgre_header_ops; dev->open = ipgre_open; dev->stop = ipgre_close; } diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c index 77f67b7cb9bf..699f06781fd8 100644 --- a/net/ipv4/ip_output.c +++ b/net/ipv4/ip_output.c @@ -169,7 +169,7 @@ static inline int ip_finish_output2(struct sk_buff *skb) IP_INC_STATS(IPSTATS_MIB_OUTBCASTPKTS); /* Be paranoid, rather than too clever. */ - if (unlikely(skb_headroom(skb) < hh_len && dev->hard_header)) { + if (unlikely(skb_headroom(skb) < hh_len && dev->header_ops)) { struct sk_buff *skb2; skb2 = skb_realloc_headroom(skb, LL_RESERVED_SPACE(dev)); diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c index 7ea5a502ca08..b761dbed8cec 100644 --- a/net/ipv6/ndisc.c +++ b/net/ipv6/ndisc.c @@ -354,7 +354,7 @@ static int ndisc_constructor(struct neighbour *neigh) rcu_read_unlock(); neigh->type = is_multicast ? RTN_MULTICAST : RTN_UNICAST; - if (dev->hard_header == NULL) { + if (!dev->header_ops) { neigh->nud_state = NUD_NOARP; neigh->ops = &ndisc_direct_ops; neigh->output = neigh->ops->queue_xmit; @@ -371,7 +371,7 @@ static int ndisc_constructor(struct neighbour *neigh) neigh->nud_state = NUD_NOARP; memcpy(neigh->ha, dev->broadcast, dev->addr_len); } - if (dev->hard_header_cache) + if (dev->header_ops->cache) neigh->ops = &ndisc_hh_ops; else neigh->ops = &ndisc_generic_ops; @@ -807,7 +807,7 @@ static void ndisc_recv_ns(struct sk_buff *skb) neigh_update(neigh, lladdr, NUD_STALE, NEIGH_UPDATE_F_WEAK_OVERRIDE| NEIGH_UPDATE_F_OVERRIDE); - if (neigh || !dev->hard_header) { + if (neigh || !dev->header_ops) { ndisc_send_na(dev, neigh, saddr, &msg->target, is_router, 1, (ifp != NULL && inc), inc); diff --git a/net/mac80211/ieee80211.c b/net/mac80211/ieee80211.c index 0cdcf0d0c6ca..57ec8880bb1a 100644 --- a/net/mac80211/ieee80211.c +++ b/net/mac80211/ieee80211.c @@ -228,7 +228,6 @@ void ieee80211_if_mgmt_setup(struct net_device *dev) dev->open = ieee80211_mgmt_open; dev->stop = ieee80211_mgmt_stop; dev->type = ARPHRD_IEEE80211_PRISM; - dev->hard_header_parse = header_parse_80211; dev->uninit = ieee80211_if_reinit; dev->destructor = ieee80211_if_free; } @@ -546,10 +545,19 @@ static void ieee80211_set_multicast_list(struct net_device *dev) netif_tx_unlock(local->mdev); } +static const struct header_ops ieee80211_header_ops = { + .create = eth_header, + .parse = header_parse_80211, + .rebuild = eth_rebuild_header, + .cache = eth_header_cache, + .cache_update = eth_header_cache_update, +}; + /* Must not be called for mdev and apdev */ void ieee80211_if_setup(struct net_device *dev) { ether_setup(dev); + dev->header_ops = &ieee80211_header_ops; dev->hard_start_xmit = ieee80211_subif_start_xmit; dev->wireless_handlers = &ieee80211_iw_handler_def; dev->set_multicast_list = ieee80211_set_multicast_list; @@ -1197,7 +1205,7 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len, mdev->open = ieee80211_master_open; mdev->stop = ieee80211_master_stop; mdev->type = ARPHRD_IEEE80211; - mdev->hard_header_parse = header_parse_80211; + mdev->header_ops = &ieee80211_header_ops; sdata->type = IEEE80211_IF_TYPE_AP; sdata->dev = mdev; diff --git a/net/netrom/nr_dev.c b/net/netrom/nr_dev.c index c7b5d930e732..8c68da5ef0a1 100644 --- a/net/netrom/nr_dev.c +++ b/net/netrom/nr_dev.c @@ -95,8 +95,9 @@ static int nr_rebuild_header(struct sk_buff *skb) #endif -static int nr_header(struct sk_buff *skb, struct net_device *dev, unsigned short type, - void *daddr, void *saddr, unsigned len) +static int nr_header(struct sk_buff *skb, struct net_device *dev, + unsigned short type, + const void *daddr, const void *saddr, unsigned len) { unsigned char *buff = skb_push(skb, NR_NETWORK_LEN + NR_TRANSPORT_LEN); @@ -193,6 +194,12 @@ static struct net_device_stats *nr_get_stats(struct net_device *dev) return &nr->stats; } +static const struct header_ops nr_header_ops = { + .create = nr_header, + .rebuild= nr_rebuild_header, +}; + + void nr_setup(struct net_device *dev) { dev->mtu = NR_MAX_PACKET_SIZE; @@ -200,11 +207,10 @@ void nr_setup(struct net_device *dev) dev->open = nr_open; dev->stop = nr_close; - dev->hard_header = nr_header; + dev->header_ops = &nr_header_ops; dev->hard_header_len = NR_NETWORK_LEN + NR_TRANSPORT_LEN; dev->addr_len = AX25_ADDR_LEN; dev->type = ARPHRD_NETROM; - dev->rebuild_header = nr_rebuild_header; dev->set_mac_address = nr_set_mac_address; /* New-style flags. */ diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c index c9ee343c2a6c..e11000a8e950 100644 --- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c @@ -389,7 +389,7 @@ static int packet_sendmsg_spkt(struct kiocb *iocb, struct socket *sock, skb_reset_network_header(skb); /* Try to align data part correctly */ - if (dev->hard_header) { + if (dev->header_ops) { skb->data -= dev->hard_header_len; skb->tail -= dev->hard_header_len; if (len < dev->hard_header_len) @@ -466,7 +466,7 @@ static int packet_rcv(struct sk_buff *skb, struct net_device *dev, struct packet skb->dev = dev; - if (dev->hard_header) { + if (dev->header_ops) { /* The device has an explicit notion of ll header, exported to higher levels. @@ -581,7 +581,7 @@ static int tpacket_rcv(struct sk_buff *skb, struct net_device *dev, struct packe sk = pt->af_packet_priv; po = pkt_sk(sk); - if (dev->hard_header) { + if (dev->header_ops) { if (sk->sk_type != SOCK_DGRAM) skb_push(skb, skb->data - skb_mac_header(skb)); else if (skb->pkt_type == PACKET_OUTGOING) { diff --git a/net/rose/rose_dev.c b/net/rose/rose_dev.c index 8d88795dc663..1b6741f1d746 100644 --- a/net/rose/rose_dev.c +++ b/net/rose/rose_dev.c @@ -35,8 +35,9 @@ #include #include -static int rose_header(struct sk_buff *skb, struct net_device *dev, unsigned short type, - void *daddr, void *saddr, unsigned len) +static int rose_header(struct sk_buff *skb, struct net_device *dev, + unsigned short type, + const void *daddr, const void *saddr, unsigned len) { unsigned char *buff = skb_push(skb, ROSE_MIN_LEN + 2); @@ -148,6 +149,11 @@ static struct net_device_stats *rose_get_stats(struct net_device *dev) return netdev_priv(dev); } +static const struct header_ops rose_header_ops = { + .create = rose_header, + .rebuild= rose_rebuild_header, +}; + void rose_setup(struct net_device *dev) { dev->mtu = ROSE_MAX_PACKET_SIZE - 2; @@ -155,11 +161,10 @@ void rose_setup(struct net_device *dev) dev->open = rose_open; dev->stop = rose_close; - dev->hard_header = rose_header; + dev->header_ops = &rose_header_ops; dev->hard_header_len = AX25_BPQ_HEADER_LEN + AX25_MAX_HEADER_LEN + ROSE_MIN_LEN; dev->addr_len = ROSE_ADDR_LEN; dev->type = ARPHRD_ROSE; - dev->rebuild_header = rose_rebuild_header; dev->set_mac_address = rose_set_mac_address; /* New-style flags. */ diff --git a/net/sched/sch_teql.c b/net/sched/sch_teql.c index d13970f3c7b1..be57cf317a7f 100644 --- a/net/sched/sch_teql.c +++ b/net/sched/sch_teql.c @@ -249,10 +249,10 @@ __teql_resolve(struct sk_buff *skb, struct sk_buff *skb_res, struct net_device * return (skb_res == NULL) ? -EAGAIN : 1; } -static __inline__ int -teql_resolve(struct sk_buff *skb, struct sk_buff *skb_res, struct net_device *dev) +static inline int teql_resolve(struct sk_buff *skb, + struct sk_buff *skb_res, struct net_device *dev) { - if (dev->hard_header == NULL || + if (dev->header_ops == NULL || skb->dst == NULL || skb->dst->neighbour == NULL) return 0; -- cgit v1.2.3 From f97df02e23269c7650869f6192e809f8ac1a4b39 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 18 Sep 2007 17:29:20 -0400 Subject: [PATCH] wireless networking: move frame inline functions to generic header These inlines are generally useful, not just with mac80211. Signed-off-by: Johannes Berg Signed-off-by: Michael Wu Signed-off-by: John W. Linville --- include/linux/ieee80211.h | 61 +++++++++++++++++++++++++++++++++++++++++++++++ include/net/mac80211.h | 60 ---------------------------------------------- 2 files changed, 61 insertions(+), 60 deletions(-) (limited to 'include/linux') diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h index 272f8c8c90da..30621c27159f 100644 --- a/include/linux/ieee80211.h +++ b/include/linux/ieee80211.h @@ -16,6 +16,7 @@ #define IEEE80211_H #include +#include #define FCS_LEN 4 @@ -350,4 +351,64 @@ enum ieee80211_eid { #define WLAN_MAX_KEY_LEN 32 +/** + * ieee80211_get_SA - get pointer to SA + * + * Given an 802.11 frame, this function returns the offset + * to the source address (SA). It does not verify that the + * header is long enough to contain the address, and the + * header must be long enough to contain the frame control + * field. + * + * @hdr: the frame + */ +static inline u8 *ieee80211_get_SA(struct ieee80211_hdr *hdr) +{ + u8 *raw = (u8 *) hdr; + u8 tofrom = (*(raw+1)) & 3; /* get the TODS and FROMDS bits */ + + switch (tofrom) { + case 2: + return hdr->addr3; + case 3: + return hdr->addr4; + } + return hdr->addr2; +} + +/** + * ieee80211_get_DA - get pointer to DA + * + * Given an 802.11 frame, this function returns the offset + * to the destination address (DA). It does not verify that + * the header is long enough to contain the address, and the + * header must be long enough to contain the frame control + * field. + * + * @hdr: the frame + */ +static inline u8 *ieee80211_get_DA(struct ieee80211_hdr *hdr) +{ + u8 *raw = (u8 *) hdr; + u8 to_ds = (*(raw+1)) & 1; /* get the TODS bit */ + + if (to_ds) + return hdr->addr3; + return hdr->addr1; +} + +/** + * ieee80211_get_morefrag - determine whether the MOREFRAGS bit is set + * + * This function determines whether the "more fragments" bit is set + * in the frame. + * + * @hdr: the frame + */ +static inline int ieee80211_get_morefrag(struct ieee80211_hdr *hdr) +{ + return (le16_to_cpu(hdr->frame_control) & + IEEE80211_FCTL_MOREFRAGS) != 0; +} + #endif /* IEEE80211_H */ diff --git a/include/net/mac80211.h b/include/net/mac80211.h index d2cf734402e3..fcca9c39b9e7 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -1399,64 +1399,4 @@ void ieee80211_wake_queues(struct ieee80211_hw *hw); */ void ieee80211_scan_completed(struct ieee80211_hw *hw); -/** - * ieee80211_get_SA - get pointer to SA - * - * Given an 802.11 frame, this function returns the offset - * to the source address (SA). It does not verify that the - * header is long enough to contain the address, and the - * header must be long enough to contain the frame control - * field. - * - * @hdr: the frame - */ -static inline u8 *ieee80211_get_SA(struct ieee80211_hdr *hdr) -{ - u8 *raw = (u8 *) hdr; - u8 tofrom = (*(raw+1)) & 3; /* get the TODS and FROMDS bits */ - - switch (tofrom) { - case 2: - return hdr->addr3; - case 3: - return hdr->addr4; - } - return hdr->addr2; -} - -/** - * ieee80211_get_DA - get pointer to DA - * - * Given an 802.11 frame, this function returns the offset - * to the destination address (DA). It does not verify that - * the header is long enough to contain the address, and the - * header must be long enough to contain the frame control - * field. - * - * @hdr: the frame - */ -static inline u8 *ieee80211_get_DA(struct ieee80211_hdr *hdr) -{ - u8 *raw = (u8 *) hdr; - u8 to_ds = (*(raw+1)) & 1; /* get the TODS bit */ - - if (to_ds) - return hdr->addr3; - return hdr->addr1; -} - -/** - * ieee80211_get_morefrag - determine whether the MOREFRAGS bit is set - * - * This function determines whether the "more fragments" bit is set - * in the frame. - * - * @hdr: the frame - */ -static inline int ieee80211_get_morefrag(struct ieee80211_hdr *hdr) -{ - return (le16_to_cpu(hdr->frame_control) & - IEEE80211_FCTL_MOREFRAGS) != 0; -} - #endif /* MAC80211_H */ -- cgit v1.2.3 From b4219952356baa162368f2f5dab6421a5dbc5e15 Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Thu, 27 Sep 2007 12:48:05 -0700 Subject: [PKT_SCHED]: Add stateless NAT Stateless NAT is useful in controlled environments where restrictions are placed on through traffic such that we don't need connection tracking to correctly NAT protocol-specific data. In particular, this is of interest when the number of flows or the number of addresses being NATed is large, or if connection tracking information has to be replicated and where it is not practical to do so. Previously we had stateless NAT functionality which was integrated into the IPv4 routing subsystem. This was a great solution as long as the NAT worked on a subnet to subnet basis such that the number of NAT rules was relatively small. The reason is that for SNAT the routing based system had to perform a linear scan through the rules. If the number of rules is large then major renovations would have take place in the routing subsystem to make this practical. For the time being, the least intrusive way of achieving this is to use the u32 classifier written by Alexey Kuznetsov along with the actions infrastructure implemented by Jamal Hadi Salim. The following patch is an attempt at this problem by creating a new nat action that can be invoked from u32 hash tables which would allow large number of stateless NAT rules that can be used/updated in constant time. The actual NAT code is mostly based on the previous stateless NAT code written by Alexey. In future we might be able to utilise the protocol NAT code from netfilter to improve support for other protocols. Signed-off-by: Herbert Xu Signed-off-by: David S. Miller --- include/linux/tc_act/tc_nat.h | 29 ++++ include/net/tc_act/tc_nat.h | 21 +++ net/sched/Kconfig | 11 ++ net/sched/Makefile | 1 + net/sched/act_nat.c | 322 ++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 384 insertions(+) create mode 100644 include/linux/tc_act/tc_nat.h create mode 100644 include/net/tc_act/tc_nat.h create mode 100644 net/sched/act_nat.c (limited to 'include/linux') diff --git a/include/linux/tc_act/tc_nat.h b/include/linux/tc_act/tc_nat.h new file mode 100644 index 000000000000..e7cf31e8ba79 --- /dev/null +++ b/include/linux/tc_act/tc_nat.h @@ -0,0 +1,29 @@ +#ifndef __LINUX_TC_NAT_H +#define __LINUX_TC_NAT_H + +#include +#include + +#define TCA_ACT_NAT 9 + +enum +{ + TCA_NAT_UNSPEC, + TCA_NAT_PARMS, + TCA_NAT_TM, + __TCA_NAT_MAX +}; +#define TCA_NAT_MAX (__TCA_NAT_MAX - 1) + +#define TCA_NAT_FLAG_EGRESS 1 + +struct tc_nat +{ + tc_gen; + __be32 old_addr; + __be32 new_addr; + __be32 mask; + __u32 flags; +}; + +#endif diff --git a/include/net/tc_act/tc_nat.h b/include/net/tc_act/tc_nat.h new file mode 100644 index 000000000000..4a691f34d703 --- /dev/null +++ b/include/net/tc_act/tc_nat.h @@ -0,0 +1,21 @@ +#ifndef __NET_TC_NAT_H +#define __NET_TC_NAT_H + +#include +#include + +struct tcf_nat { + struct tcf_common common; + + __be32 old_addr; + __be32 new_addr; + __be32 mask; + u32 flags; +}; + +static inline struct tcf_nat *to_tcf_nat(struct tcf_common *pc) +{ + return container_of(pc, struct tcf_nat, common); +} + +#endif /* __NET_TC_NAT_H */ diff --git a/net/sched/Kconfig b/net/sched/Kconfig index 8a74cac0be8c..92435a882fac 100644 --- a/net/sched/Kconfig +++ b/net/sched/Kconfig @@ -447,6 +447,17 @@ config NET_ACT_IPT To compile this code as a module, choose M here: the module will be called ipt. +config NET_ACT_NAT + tristate "Stateless NAT" + depends on NET_CLS_ACT + select NETFILTER + ---help--- + Say Y here to do stateless NAT on IPv4 packets. You should use + netfilter for NAT unless you know what you are doing. + + To compile this code as a module, choose M here: the + module will be called nat. + config NET_ACT_PEDIT tristate "Packet Editing" depends on NET_CLS_ACT diff --git a/net/sched/Makefile b/net/sched/Makefile index b67c36f65cf2..81ecbe8e7dce 100644 --- a/net/sched/Makefile +++ b/net/sched/Makefile @@ -11,6 +11,7 @@ obj-$(CONFIG_NET_ACT_POLICE) += act_police.o obj-$(CONFIG_NET_ACT_GACT) += act_gact.o obj-$(CONFIG_NET_ACT_MIRRED) += act_mirred.o obj-$(CONFIG_NET_ACT_IPT) += act_ipt.o +obj-$(CONFIG_NET_ACT_NAT) += act_nat.o obj-$(CONFIG_NET_ACT_PEDIT) += act_pedit.o obj-$(CONFIG_NET_ACT_SIMP) += act_simple.o obj-$(CONFIG_NET_SCH_FIFO) += sch_fifo.o diff --git a/net/sched/act_nat.c b/net/sched/act_nat.c new file mode 100644 index 000000000000..c96273bcaf9c --- /dev/null +++ b/net/sched/act_nat.c @@ -0,0 +1,322 @@ +/* + * Stateless NAT actions + * + * Copyright (c) 2007 Herbert Xu + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#define NAT_TAB_MASK 15 +static struct tcf_common *tcf_nat_ht[NAT_TAB_MASK + 1]; +static u32 nat_idx_gen; +static DEFINE_RWLOCK(nat_lock); + +static struct tcf_hashinfo nat_hash_info = { + .htab = tcf_nat_ht, + .hmask = NAT_TAB_MASK, + .lock = &nat_lock, +}; + +static int tcf_nat_init(struct rtattr *rta, struct rtattr *est, + struct tc_action *a, int ovr, int bind) +{ + struct rtattr *tb[TCA_NAT_MAX]; + struct tc_nat *parm; + int ret = 0; + struct tcf_nat *p; + struct tcf_common *pc; + + if (rta == NULL || rtattr_parse_nested(tb, TCA_NAT_MAX, rta) < 0) + return -EINVAL; + + if (tb[TCA_NAT_PARMS - 1] == NULL || + RTA_PAYLOAD(tb[TCA_NAT_PARMS - 1]) < sizeof(*parm)) + return -EINVAL; + parm = RTA_DATA(tb[TCA_NAT_PARMS - 1]); + + pc = tcf_hash_check(parm->index, a, bind, &nat_hash_info); + if (!pc) { + pc = tcf_hash_create(parm->index, est, a, sizeof(*p), bind, + &nat_idx_gen, &nat_hash_info); + if (unlikely(!pc)) + return -ENOMEM; + p = to_tcf_nat(pc); + ret = ACT_P_CREATED; + } else { + p = to_tcf_nat(pc); + if (!ovr) { + tcf_hash_release(pc, bind, &nat_hash_info); + return -EEXIST; + } + } + + spin_lock_bh(&p->tcf_lock); + p->old_addr = parm->old_addr; + p->new_addr = parm->new_addr; + p->mask = parm->mask; + p->flags = parm->flags; + + p->tcf_action = parm->action; + spin_unlock_bh(&p->tcf_lock); + + if (ret == ACT_P_CREATED) + tcf_hash_insert(pc, &nat_hash_info); + + return ret; +} + +static int tcf_nat_cleanup(struct tc_action *a, int bind) +{ + struct tcf_nat *p = a->priv; + + return tcf_hash_release(&p->common, bind, &nat_hash_info); +} + +static int tcf_nat(struct sk_buff *skb, struct tc_action *a, + struct tcf_result *res) +{ + struct tcf_nat *p = a->priv; + struct iphdr *iph; + __be32 old_addr; + __be32 new_addr; + __be32 mask; + __be32 addr; + int egress; + int action; + int ihl; + + spin_lock(&p->tcf_lock); + + p->tcf_tm.lastuse = jiffies; + old_addr = p->old_addr; + new_addr = p->new_addr; + mask = p->mask; + egress = p->flags & TCA_NAT_FLAG_EGRESS; + action = p->tcf_action; + + p->tcf_bstats.bytes += skb->len; + p->tcf_bstats.packets++; + + spin_unlock(&p->tcf_lock); + + if (unlikely(action == TC_ACT_SHOT)) + goto drop; + + if (!pskb_may_pull(skb, sizeof(*iph))) + goto drop; + + iph = ip_hdr(skb); + + if (egress) + addr = iph->saddr; + else + addr = iph->daddr; + + if (!((old_addr ^ addr) & mask)) { + if (skb_cloned(skb) && + !skb_clone_writable(skb, sizeof(*iph)) && + pskb_expand_head(skb, 0, 0, GFP_ATOMIC)) + goto drop; + + new_addr &= mask; + new_addr |= addr & ~mask; + + /* Rewrite IP header */ + iph = ip_hdr(skb); + if (egress) + iph->saddr = new_addr; + else + iph->daddr = new_addr; + + nf_csum_replace4(&iph->check, addr, new_addr); + } + + ihl = iph->ihl * 4; + + /* It would be nice to share code with stateful NAT. */ + switch (iph->frag_off & htons(IP_OFFSET) ? 0 : iph->protocol) { + case IPPROTO_TCP: + { + struct tcphdr *tcph; + + if (!pskb_may_pull(skb, ihl + sizeof(*tcph)) || + (skb_cloned(skb) && + !skb_clone_writable(skb, ihl + sizeof(*tcph)) && + pskb_expand_head(skb, 0, 0, GFP_ATOMIC))) + goto drop; + + tcph = (void *)(skb_network_header(skb) + ihl); + nf_proto_csum_replace4(&tcph->check, skb, addr, new_addr, 1); + break; + } + case IPPROTO_UDP: + { + struct udphdr *udph; + + if (!pskb_may_pull(skb, ihl + sizeof(*udph)) || + (skb_cloned(skb) && + !skb_clone_writable(skb, ihl + sizeof(*udph)) && + pskb_expand_head(skb, 0, 0, GFP_ATOMIC))) + goto drop; + + udph = (void *)(skb_network_header(skb) + ihl); + if (udph->check || skb->ip_summed == CHECKSUM_PARTIAL) { + nf_proto_csum_replace4(&udph->check, skb, addr, + new_addr, 1); + if (!udph->check) + udph->check = CSUM_MANGLED_0; + } + break; + } + case IPPROTO_ICMP: + { + struct icmphdr *icmph; + + if (!pskb_may_pull(skb, ihl + sizeof(*icmph) + sizeof(*iph))) + goto drop; + + icmph = (void *)(skb_network_header(skb) + ihl); + + if ((icmph->type != ICMP_DEST_UNREACH) && + (icmph->type != ICMP_TIME_EXCEEDED) && + (icmph->type != ICMP_PARAMETERPROB)) + break; + + iph = (void *)(icmph + 1); + if (egress) + addr = iph->daddr; + else + addr = iph->saddr; + + if ((old_addr ^ addr) & mask) + break; + + if (skb_cloned(skb) && + !skb_clone_writable(skb, + ihl + sizeof(*icmph) + sizeof(*iph)) && + pskb_expand_head(skb, 0, 0, GFP_ATOMIC)) + goto drop; + + icmph = (void *)(skb_network_header(skb) + ihl); + iph = (void *)(icmph + 1); + + new_addr &= mask; + new_addr |= addr & ~mask; + + /* XXX Fix up the inner checksums. */ + if (egress) + iph->daddr = new_addr; + else + iph->saddr = new_addr; + + nf_proto_csum_replace4(&icmph->checksum, skb, addr, new_addr, + 1); + break; + } + default: + break; + } + + return action; + +drop: + spin_lock(&p->tcf_lock); + p->tcf_qstats.drops++; + spin_unlock(&p->tcf_lock); + return TC_ACT_SHOT; +} + +static int tcf_nat_dump(struct sk_buff *skb, struct tc_action *a, + int bind, int ref) +{ + unsigned char *b = skb_tail_pointer(skb); + struct tcf_nat *p = a->priv; + struct tc_nat *opt; + struct tcf_t t; + int s; + + s = sizeof(*opt); + + /* netlink spinlocks held above us - must use ATOMIC */ + opt = kzalloc(s, GFP_ATOMIC); + if (unlikely(!opt)) + return -ENOBUFS; + + opt->old_addr = p->old_addr; + opt->new_addr = p->new_addr; + opt->mask = p->mask; + opt->flags = p->flags; + + opt->index = p->tcf_index; + opt->action = p->tcf_action; + opt->refcnt = p->tcf_refcnt - ref; + opt->bindcnt = p->tcf_bindcnt - bind; + + RTA_PUT(skb, TCA_NAT_PARMS, s, opt); + t.install = jiffies_to_clock_t(jiffies - p->tcf_tm.install); + t.lastuse = jiffies_to_clock_t(jiffies - p->tcf_tm.lastuse); + t.expires = jiffies_to_clock_t(p->tcf_tm.expires); + RTA_PUT(skb, TCA_NAT_TM, sizeof(t), &t); + + kfree(opt); + + return skb->len; + +rtattr_failure: + nlmsg_trim(skb, b); + kfree(opt); + return -1; +} + +static struct tc_action_ops act_nat_ops = { + .kind = "nat", + .hinfo = &nat_hash_info, + .type = TCA_ACT_NAT, + .capab = TCA_CAP_NONE, + .owner = THIS_MODULE, + .act = tcf_nat, + .dump = tcf_nat_dump, + .cleanup = tcf_nat_cleanup, + .lookup = tcf_hash_search, + .init = tcf_nat_init, + .walk = tcf_generic_walker +}; + +MODULE_DESCRIPTION("Stateless NAT actions"); +MODULE_LICENSE("GPL"); + +static int __init nat_init_module(void) +{ + return tcf_register_action(&act_nat_ops); +} + +static void __exit nat_cleanup_module(void) +{ + tcf_unregister_action(&act_nat_ops); +} + +module_init(nat_init_module); +module_exit(nat_cleanup_module); -- cgit v1.2.3 From 279632be3f546f4d88bdb086fa71479bcde9d641 Mon Sep 17 00:00:00 2001 From: Michael Buesch Date: Thu, 27 Sep 2007 14:42:42 +0200 Subject: [PATCH] rfkill: Fix documentation typos Signed-off-by: Michael Buesch Signed-off-by: John W. Linville --- include/linux/rfkill.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'include/linux') diff --git a/include/linux/rfkill.h b/include/linux/rfkill.h index f9a50dab4168..8909682415dc 100644 --- a/include/linux/rfkill.h +++ b/include/linux/rfkill.h @@ -29,9 +29,9 @@ /** * enum rfkill_type - type of rfkill switch. - * RFKILL_TYPE_WLAN: switch is no a Wireless network devices. - * RFKILL_TYPE_BlUETOOTH: switch is on a bluetooth device. - * RFKILL_TYPE_UWB: switch is on a Ultra wideband device. + * RFKILL_TYPE_WLAN: switch is on a 802.11 wireless network device. + * RFKILL_TYPE_BLUETOOTH: switch is on a bluetooth device. + * RFKILL_TYPE_UWB: switch is on a ultra wideband device. */ enum rfkill_type { RFKILL_TYPE_WLAN , -- cgit v1.2.3 From fe242cfd3390b1c7d54d60f7ebb6a4054804cd41 Mon Sep 17 00:00:00 2001 From: Ivo van Doorn Date: Thu, 27 Sep 2007 14:57:05 -0700 Subject: [RFKILL]: Move rfkill_switch_all out of global header rfkill_switch_all shouldn't be called by drivers directly, instead they should send a signal over the input device. To prevent confusion for driver developers, move the function into a rfkill private header. Signed-off-by: Ivo van Doorn Signed-off-by: David S. Miller --- include/linux/rfkill.h | 4 +--- net/rfkill/rfkill-input.c | 2 ++ net/rfkill/rfkill-input.h | 16 ++++++++++++++++ net/rfkill/rfkill.c | 2 +- 4 files changed, 20 insertions(+), 4 deletions(-) create mode 100644 net/rfkill/rfkill-input.h (limited to 'include/linux') diff --git a/include/linux/rfkill.h b/include/linux/rfkill.h index 8909682415dc..d76397ca95ad 100644 --- a/include/linux/rfkill.h +++ b/include/linux/rfkill.h @@ -2,7 +2,7 @@ #define __RFKILL_H /* - * Copyright (C) 2006 Ivo van Doorn + * Copyright (C) 2006 - 2007 Ivo van Doorn * Copyright (C) 2007 Dmitry Torokhov * * This program is free software; you can redistribute it and/or modify @@ -84,6 +84,4 @@ void rfkill_free(struct rfkill *rfkill); int rfkill_register(struct rfkill *rfkill); void rfkill_unregister(struct rfkill *rfkill); -void rfkill_switch_all(enum rfkill_type type, enum rfkill_state state); - #endif /* RFKILL_H */ diff --git a/net/rfkill/rfkill-input.c b/net/rfkill/rfkill-input.c index 8e4516a5fe32..eaabf087c59b 100644 --- a/net/rfkill/rfkill-input.c +++ b/net/rfkill/rfkill-input.c @@ -17,6 +17,8 @@ #include #include +#include "rfkill-input.h" + MODULE_AUTHOR("Dmitry Torokhov "); MODULE_DESCRIPTION("Input layer to RF switch connector"); MODULE_LICENSE("GPL"); diff --git a/net/rfkill/rfkill-input.h b/net/rfkill/rfkill-input.h new file mode 100644 index 000000000000..4dae5006fc77 --- /dev/null +++ b/net/rfkill/rfkill-input.h @@ -0,0 +1,16 @@ +/* + * Copyright (C) 2007 Ivo van Doorn + */ + +/* + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + */ + +#ifndef __RFKILL_INPUT_H +#define __RFKILL_INPUT_H + +void rfkill_switch_all(enum rfkill_type type, enum rfkill_state state); + +#endif /* __RFKILL_INPUT_H */ diff --git a/net/rfkill/rfkill.c b/net/rfkill/rfkill.c index 03ed7fd8afe0..637a9f0c7655 100644 --- a/net/rfkill/rfkill.c +++ b/net/rfkill/rfkill.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2006 Ivo van Doorn + * Copyright (C) 2006 - 2007 Ivo van Doorn * Copyright (C) 2007 Dmitry Torokhov * * This program is free software; you can redistribute it and/or modify -- cgit v1.2.3 From 169e36742572934f5d846cfa5f9d76e72d505db4 Mon Sep 17 00:00:00 2001 From: "Eric W. Biederman" Date: Thu, 27 Sep 2007 17:10:06 -0700 Subject: [NETNS]: CLONE_NEWNET don't use the same clone flag as the pid namespace. Signed-off-by: Eric W. Biederman Signed-off-by: David S. Miller --- include/linux/sched.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/sched.h b/include/linux/sched.h index a4a141055c44..833f7dc2b8de 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -27,7 +27,7 @@ #define CLONE_NEWUTS 0x04000000 /* New utsname group? */ #define CLONE_NEWIPC 0x08000000 /* New ipcs */ #define CLONE_NEWUSER 0x10000000 /* New user namespace */ -#define CLONE_NEWNET 0x20000000 /* New network namespace */ +#define CLONE_NEWNET 0x40000000 /* New network namespace */ /* * Scheduling policies -- cgit v1.2.3 From 7c8d4cb4198d199e65a6ced8c81f71e3ac3f4cfc Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Fri, 28 Sep 2007 14:15:45 -0700 Subject: [NETFILTER]: nfnetlink: make subsystem and callbacks const Signed-off-by: Patrick McHardy Signed-off-by: David S. Miller --- include/linux/netfilter/nfnetlink.h | 10 +++++----- net/netfilter/nf_conntrack_netlink.c | 8 ++++---- net/netfilter/nfnetlink.c | 18 +++++++++--------- net/netfilter/nfnetlink_log.c | 4 ++-- net/netfilter/nfnetlink_queue.c | 4 ++-- 5 files changed, 22 insertions(+), 22 deletions(-) (limited to 'include/linux') diff --git a/include/linux/netfilter/nfnetlink.h b/include/linux/netfilter/nfnetlink.h index 0f9311df1559..e32418bcc661 100644 --- a/include/linux/netfilter/nfnetlink.h +++ b/include/linux/netfilter/nfnetlink.h @@ -118,9 +118,9 @@ struct nfnl_callback struct nfnetlink_subsystem { const char *name; - __u8 subsys_id; /* nfnetlink subsystem ID */ - __u8 cb_count; /* number of callbacks */ - struct nfnl_callback *cb; /* callback for individual types */ + __u8 subsys_id; /* nfnetlink subsystem ID */ + __u8 cb_count; /* number of callbacks */ + const struct nfnl_callback *cb; /* callback for individual types */ }; extern void __nfa_fill(struct sk_buff *skb, int attrtype, @@ -129,8 +129,8 @@ extern void __nfa_fill(struct sk_buff *skb, int attrtype, ({ if (skb_tailroom(skb) < (int)NFA_SPACE(attrlen)) goto nfattr_failure; \ __nfa_fill(skb, attrtype, attrlen, data); }) -extern int nfnetlink_subsys_register(struct nfnetlink_subsystem *n); -extern int nfnetlink_subsys_unregister(struct nfnetlink_subsystem *n); +extern int nfnetlink_subsys_register(const struct nfnetlink_subsystem *n); +extern int nfnetlink_subsys_unregister(const struct nfnetlink_subsystem *n); extern void nfattr_parse(struct nfattr *tb[], int maxattr, struct nfattr *nfa, int len); diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c index 2863e72b4091..5080045fdc74 100644 --- a/net/netfilter/nf_conntrack_netlink.c +++ b/net/netfilter/nf_conntrack_netlink.c @@ -1548,7 +1548,7 @@ static struct notifier_block ctnl_notifier_exp = { }; #endif -static struct nfnl_callback ctnl_cb[IPCTNL_MSG_MAX] = { +static const struct nfnl_callback ctnl_cb[IPCTNL_MSG_MAX] = { [IPCTNL_MSG_CT_NEW] = { .call = ctnetlink_new_conntrack, .attr_count = CTA_MAX, }, [IPCTNL_MSG_CT_GET] = { .call = ctnetlink_get_conntrack, @@ -1559,7 +1559,7 @@ static struct nfnl_callback ctnl_cb[IPCTNL_MSG_MAX] = { .attr_count = CTA_MAX, }, }; -static struct nfnl_callback ctnl_exp_cb[IPCTNL_MSG_EXP_MAX] = { +static const struct nfnl_callback ctnl_exp_cb[IPCTNL_MSG_EXP_MAX] = { [IPCTNL_MSG_EXP_GET] = { .call = ctnetlink_get_expect, .attr_count = CTA_EXPECT_MAX, }, [IPCTNL_MSG_EXP_NEW] = { .call = ctnetlink_new_expect, @@ -1568,14 +1568,14 @@ static struct nfnl_callback ctnl_exp_cb[IPCTNL_MSG_EXP_MAX] = { .attr_count = CTA_EXPECT_MAX, }, }; -static struct nfnetlink_subsystem ctnl_subsys = { +static const struct nfnetlink_subsystem ctnl_subsys = { .name = "conntrack", .subsys_id = NFNL_SUBSYS_CTNETLINK, .cb_count = IPCTNL_MSG_MAX, .cb = ctnl_cb, }; -static struct nfnetlink_subsystem ctnl_exp_subsys = { +static const struct nfnetlink_subsystem ctnl_exp_subsys = { .name = "conntrack_expect", .subsys_id = NFNL_SUBSYS_CTNETLINK_EXP, .cb_count = IPCTNL_MSG_EXP_MAX, diff --git a/net/netfilter/nfnetlink.c b/net/netfilter/nfnetlink.c index 4aa56e7ff156..032224c1409f 100644 --- a/net/netfilter/nfnetlink.c +++ b/net/netfilter/nfnetlink.c @@ -41,7 +41,7 @@ MODULE_ALIAS_NET_PF_PROTO(PF_NETLINK, NETLINK_NETFILTER); static char __initdata nfversion[] = "0.30"; static struct sock *nfnl = NULL; -static struct nfnetlink_subsystem *subsys_table[NFNL_SUBSYS_COUNT]; +static const struct nfnetlink_subsystem *subsys_table[NFNL_SUBSYS_COUNT]; static DEFINE_MUTEX(nfnl_mutex); static void nfnl_lock(void) @@ -66,7 +66,7 @@ static void nfnl_unlock(void) nfnl->sk_data_ready(nfnl, 0); } -int nfnetlink_subsys_register(struct nfnetlink_subsystem *n) +int nfnetlink_subsys_register(const struct nfnetlink_subsystem *n) { nfnl_lock(); if (subsys_table[n->subsys_id]) { @@ -80,7 +80,7 @@ int nfnetlink_subsys_register(struct nfnetlink_subsystem *n) } EXPORT_SYMBOL_GPL(nfnetlink_subsys_register); -int nfnetlink_subsys_unregister(struct nfnetlink_subsystem *n) +int nfnetlink_subsys_unregister(const struct nfnetlink_subsystem *n) { nfnl_lock(); subsys_table[n->subsys_id] = NULL; @@ -90,7 +90,7 @@ int nfnetlink_subsys_unregister(struct nfnetlink_subsystem *n) } EXPORT_SYMBOL_GPL(nfnetlink_subsys_unregister); -static inline struct nfnetlink_subsystem *nfnetlink_get_subsys(u_int16_t type) +static inline const struct nfnetlink_subsystem *nfnetlink_get_subsys(u_int16_t type) { u_int8_t subsys_id = NFNL_SUBSYS_ID(type); @@ -100,8 +100,8 @@ static inline struct nfnetlink_subsystem *nfnetlink_get_subsys(u_int16_t type) return subsys_table[subsys_id]; } -static inline struct nfnl_callback * -nfnetlink_find_client(u_int16_t type, struct nfnetlink_subsystem *ss) +static inline const struct nfnl_callback * +nfnetlink_find_client(u_int16_t type, const struct nfnetlink_subsystem *ss) { u_int8_t cb_id = NFNL_MSG_TYPE(type); @@ -147,7 +147,7 @@ EXPORT_SYMBOL_GPL(nfattr_parse); * */ static int -nfnetlink_check_attributes(struct nfnetlink_subsystem *subsys, +nfnetlink_check_attributes(const struct nfnetlink_subsystem *subsys, struct nlmsghdr *nlh, struct nfattr *cda[]) { int min_len = NLMSG_SPACE(sizeof(struct nfgenmsg)); @@ -197,8 +197,8 @@ EXPORT_SYMBOL_GPL(nfnetlink_unicast); /* Process one complete nfnetlink message. */ static int nfnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) { - struct nfnl_callback *nc; - struct nfnetlink_subsystem *ss; + const struct nfnl_callback *nc; + const struct nfnetlink_subsystem *ss; int type, err; if (security_netlink_recv(skb, CAP_NET_ADMIN)) diff --git a/net/netfilter/nfnetlink_log.c b/net/netfilter/nfnetlink_log.c index 332e0f7f6f9e..c3aa8918035f 100644 --- a/net/netfilter/nfnetlink_log.c +++ b/net/netfilter/nfnetlink_log.c @@ -883,14 +883,14 @@ out: return ret; } -static struct nfnl_callback nfulnl_cb[NFULNL_MSG_MAX] = { +static const struct nfnl_callback nfulnl_cb[NFULNL_MSG_MAX] = { [NFULNL_MSG_PACKET] = { .call = nfulnl_recv_unsupp, .attr_count = NFULA_MAX, }, [NFULNL_MSG_CONFIG] = { .call = nfulnl_recv_config, .attr_count = NFULA_CFG_MAX, }, }; -static struct nfnetlink_subsystem nfulnl_subsys = { +static const struct nfnetlink_subsystem nfulnl_subsys = { .name = "log", .subsys_id = NFNL_SUBSYS_ULOG, .cb_count = NFULNL_MSG_MAX, diff --git a/net/netfilter/nfnetlink_queue.c b/net/netfilter/nfnetlink_queue.c index a813185c766d..bfcc0563bfd4 100644 --- a/net/netfilter/nfnetlink_queue.c +++ b/net/netfilter/nfnetlink_queue.c @@ -961,7 +961,7 @@ out_put: return ret; } -static struct nfnl_callback nfqnl_cb[NFQNL_MSG_MAX] = { +static const struct nfnl_callback nfqnl_cb[NFQNL_MSG_MAX] = { [NFQNL_MSG_PACKET] = { .call = nfqnl_recv_unsupp, .attr_count = NFQA_MAX, }, [NFQNL_MSG_VERDICT] = { .call = nfqnl_recv_verdict, @@ -970,7 +970,7 @@ static struct nfnl_callback nfqnl_cb[NFQNL_MSG_MAX] = { .attr_count = NFQA_CFG_MAX, }, }; -static struct nfnetlink_subsystem nfqnl_subsys = { +static const struct nfnetlink_subsystem nfqnl_subsys = { .name = "nf_queue", .subsys_id = NFNL_SUBSYS_QUEUE, .cb_count = NFQNL_MSG_MAX, -- cgit v1.2.3 From df6fb868d6118686805c2fa566e213a8f31c8e4f Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Fri, 28 Sep 2007 14:37:03 -0700 Subject: [NETFILTER]: nfnetlink: convert to generic netlink attribute functions Get rid of the duplicated rtnetlink macros and use the generic netlink attribute functions. The old duplicated stuff is moved to a new header file that exists just for userspace. Signed-off-by: Patrick McHardy Signed-off-by: David S. Miller --- include/linux/netfilter/Kbuild | 1 + include/linux/netfilter/nfnetlink.h | 78 +---- include/linux/netfilter/nfnetlink_compat.h | 61 ++++ include/net/netfilter/nf_conntrack_l3proto.h | 5 +- include/net/netfilter/nf_conntrack_l4proto.h | 10 +- include/net/netfilter/nf_nat_protocol.h | 4 +- net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c | 20 +- net/ipv4/netfilter/nf_conntrack_proto_icmp.c | 30 +- net/ipv4/netfilter/nf_nat_core.c | 16 +- net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c | 20 +- net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c | 30 +- net/netfilter/nf_conntrack_core.c | 21 +- net/netfilter/nf_conntrack_netlink.c | 393 +++++++++++++------------ net/netfilter/nf_conntrack_proto_tcp.c | 63 ++-- net/netfilter/nfnetlink.c | 39 +-- net/netfilter/nfnetlink_log.c | 155 +++++----- net/netfilter/nfnetlink_queue.c | 113 ++++--- 17 files changed, 527 insertions(+), 532 deletions(-) create mode 100644 include/linux/netfilter/nfnetlink_compat.h (limited to 'include/linux') diff --git a/include/linux/netfilter/Kbuild b/include/linux/netfilter/Kbuild index ab57cb7d7c61..f2eaea2234ec 100644 --- a/include/linux/netfilter/Kbuild +++ b/include/linux/netfilter/Kbuild @@ -40,5 +40,6 @@ unifdef-y += nf_conntrack_common.h unifdef-y += nf_conntrack_ftp.h unifdef-y += nf_conntrack_tcp.h unifdef-y += nfnetlink.h +unifdef-y += nfnetlink_compat.h unifdef-y += x_tables.h unifdef-y += xt_physdev.h diff --git a/include/linux/netfilter/nfnetlink.h b/include/linux/netfilter/nfnetlink.h index e32418bcc661..47457b4c8c62 100644 --- a/include/linux/netfilter/nfnetlink.h +++ b/include/linux/netfilter/nfnetlink.h @@ -1,16 +1,7 @@ #ifndef _NFNETLINK_H #define _NFNETLINK_H #include - -#ifndef __KERNEL__ -/* nfnetlink groups: Up to 32 maximum - backwards compatibility for userspace */ -#define NF_NETLINK_CONNTRACK_NEW 0x00000001 -#define NF_NETLINK_CONNTRACK_UPDATE 0x00000002 -#define NF_NETLINK_CONNTRACK_DESTROY 0x00000004 -#define NF_NETLINK_CONNTRACK_EXP_NEW 0x00000008 -#define NF_NETLINK_CONNTRACK_EXP_UPDATE 0x00000010 -#define NF_NETLINK_CONNTRACK_EXP_DESTROY 0x00000020 -#endif +#include enum nfnetlink_groups { NFNLGRP_NONE, @@ -31,48 +22,6 @@ enum nfnetlink_groups { }; #define NFNLGRP_MAX (__NFNLGRP_MAX - 1) -/* Generic structure for encapsulation optional netfilter information. - * It is reminiscent of sockaddr, but with sa_family replaced - * with attribute type. - * ! This should someday be put somewhere generic as now rtnetlink and - * ! nfnetlink use the same attributes methods. - J. Schulist. - */ - -struct nfattr -{ - u_int16_t nfa_len; - u_int16_t nfa_type; /* we use 15 bits for the type, and the highest - * bit to indicate whether the payload is nested */ -}; - -/* FIXME: Apart from NFNL_NFA_NESTED shamelessly copy and pasted from - * rtnetlink.h, it's time to put this in a generic file */ - -#define NFNL_NFA_NEST 0x8000 -#define NFA_TYPE(attr) ((attr)->nfa_type & 0x7fff) - -#define NFA_ALIGNTO 4 -#define NFA_ALIGN(len) (((len) + NFA_ALIGNTO - 1) & ~(NFA_ALIGNTO - 1)) -#define NFA_OK(nfa,len) ((len) > 0 && (nfa)->nfa_len >= sizeof(struct nfattr) \ - && (nfa)->nfa_len <= (len)) -#define NFA_NEXT(nfa,attrlen) ((attrlen) -= NFA_ALIGN((nfa)->nfa_len), \ - (struct nfattr *)(((char *)(nfa)) + NFA_ALIGN((nfa)->nfa_len))) -#define NFA_LENGTH(len) (NFA_ALIGN(sizeof(struct nfattr)) + (len)) -#define NFA_SPACE(len) NFA_ALIGN(NFA_LENGTH(len)) -#define NFA_DATA(nfa) ((void *)(((char *)(nfa)) + NFA_LENGTH(0))) -#define NFA_PAYLOAD(nfa) ((int)((nfa)->nfa_len) - NFA_LENGTH(0)) -#define NFA_NEST(skb, type) \ -({ struct nfattr *__start = (struct nfattr *)skb_tail_pointer(skb); \ - NFA_PUT(skb, (NFNL_NFA_NEST | type), 0, NULL); \ - __start; }) -#define NFA_NEST_END(skb, start) \ -({ (start)->nfa_len = skb_tail_pointer(skb) - (unsigned char *)(start); \ - (skb)->len; }) -#define NFA_NEST_CANCEL(skb, start) \ -({ if (start) \ - skb_trim(skb, (unsigned char *) (start) - (skb)->data); \ - -1; }) - /* General form of address family dependent message. */ struct nfgenmsg { @@ -83,10 +32,6 @@ struct nfgenmsg { #define NFNETLINK_V0 0 -#define NFM_NFA(n) ((struct nfattr *)(((char *)(n)) \ - + NLMSG_ALIGN(sizeof(struct nfgenmsg)))) -#define NFM_PAYLOAD(n) NLMSG_PAYLOAD(n, sizeof(struct nfgenmsg)) - /* netfilter netlink message types are split in two pieces: * 8 bit subsystem, 8bit operation. */ @@ -107,12 +52,13 @@ struct nfgenmsg { #include #include +#include struct nfnl_callback { int (*call)(struct sock *nl, struct sk_buff *skb, - struct nlmsghdr *nlh, struct nfattr *cda[]); - u_int16_t attr_count; /* number of nfattr's */ + struct nlmsghdr *nlh, struct nlattr *cda[]); + u_int16_t attr_count; /* number of nlattr's */ }; struct nfnetlink_subsystem @@ -123,27 +69,15 @@ struct nfnetlink_subsystem const struct nfnl_callback *cb; /* callback for individual types */ }; -extern void __nfa_fill(struct sk_buff *skb, int attrtype, - int attrlen, const void *data); -#define NFA_PUT(skb, attrtype, attrlen, data) \ -({ if (skb_tailroom(skb) < (int)NFA_SPACE(attrlen)) goto nfattr_failure; \ - __nfa_fill(skb, attrtype, attrlen, data); }) - extern int nfnetlink_subsys_register(const struct nfnetlink_subsystem *n); extern int nfnetlink_subsys_unregister(const struct nfnetlink_subsystem *n); -extern void nfattr_parse(struct nfattr *tb[], int maxattr, - struct nfattr *nfa, int len); - -#define nfattr_parse_nested(tb, max, nfa) \ - nfattr_parse((tb), (max), NFA_DATA((nfa)), NFA_PAYLOAD((nfa))) - #define nfattr_bad_size(tb, max, cta_min) \ ({ int __i, __res = 0; \ - for (__i=0; __infa_type & 0x7fff) + +#define NFA_ALIGNTO 4 +#define NFA_ALIGN(len) (((len) + NFA_ALIGNTO - 1) & ~(NFA_ALIGNTO - 1)) +#define NFA_OK(nfa,len) ((len) > 0 && (nfa)->nfa_len >= sizeof(struct nfattr) \ + && (nfa)->nfa_len <= (len)) +#define NFA_NEXT(nfa,attrlen) ((attrlen) -= NFA_ALIGN((nfa)->nfa_len), \ + (struct nfattr *)(((char *)(nfa)) + NFA_ALIGN((nfa)->nfa_len))) +#define NFA_LENGTH(len) (NFA_ALIGN(sizeof(struct nfattr)) + (len)) +#define NFA_SPACE(len) NFA_ALIGN(NFA_LENGTH(len)) +#define NFA_DATA(nfa) ((void *)(((char *)(nfa)) + NFA_LENGTH(0))) +#define NFA_PAYLOAD(nfa) ((int)((nfa)->nfa_len) - NFA_LENGTH(0)) +#define NFA_NEST(skb, type) \ +({ struct nfattr *__start = (struct nfattr *)skb_tail_pointer(skb); \ + NFA_PUT(skb, (NFNL_NFA_NEST | type), 0, NULL); \ + __start; }) +#define NFA_NEST_END(skb, start) \ +({ (start)->nfa_len = skb_tail_pointer(skb) - (unsigned char *)(start); \ + (skb)->len; }) +#define NFA_NEST_CANCEL(skb, start) \ +({ if (start) \ + skb_trim(skb, (unsigned char *) (start) - (skb)->data); \ + -1; }) + +#define NFM_NFA(n) ((struct nfattr *)(((char *)(n)) \ + + NLMSG_ALIGN(sizeof(struct nfgenmsg)))) +#define NFM_PAYLOAD(n) NLMSG_PAYLOAD(n, sizeof(struct nfgenmsg)) + +#endif /* ! __KERNEL__ */ +#endif /* _NFNETLINK_COMPAT_H */ diff --git a/include/net/netfilter/nf_conntrack_l3proto.h b/include/net/netfilter/nf_conntrack_l3proto.h index 3c58a2c4df28..c02402d5ec36 100644 --- a/include/net/netfilter/nf_conntrack_l3proto.h +++ b/include/net/netfilter/nf_conntrack_l3proto.h @@ -11,11 +11,10 @@ #ifndef _NF_CONNTRACK_L3PROTO_H #define _NF_CONNTRACK_L3PROTO_H +#include #include #include -struct nfattr; - struct nf_conntrack_l3proto { /* L3 Protocol Family number. ex) PF_INET */ @@ -67,7 +66,7 @@ struct nf_conntrack_l3proto int (*tuple_to_nfattr)(struct sk_buff *skb, const struct nf_conntrack_tuple *t); - int (*nfattr_to_tuple)(struct nfattr *tb[], + int (*nfattr_to_tuple)(struct nlattr *tb[], struct nf_conntrack_tuple *t); #ifdef CONFIG_SYSCTL diff --git a/include/net/netfilter/nf_conntrack_l4proto.h b/include/net/netfilter/nf_conntrack_l4proto.h index f46cb930414c..a43c4e484ea1 100644 --- a/include/net/netfilter/nf_conntrack_l4proto.h +++ b/include/net/netfilter/nf_conntrack_l4proto.h @@ -9,10 +9,10 @@ #ifndef _NF_CONNTRACK_L4PROTO_H #define _NF_CONNTRACK_L4PROTO_H +#include #include struct seq_file; -struct nfattr; struct nf_conntrack_l4proto { @@ -65,15 +65,15 @@ struct nf_conntrack_l4proto int pf, unsigned int hooknum); /* convert protoinfo to nfnetink attributes */ - int (*to_nfattr)(struct sk_buff *skb, struct nfattr *nfa, + int (*to_nfattr)(struct sk_buff *skb, struct nlattr *nla, const struct nf_conn *ct); /* convert nfnetlink attributes to protoinfo */ - int (*from_nfattr)(struct nfattr *tb[], struct nf_conn *ct); + int (*from_nfattr)(struct nlattr *tb[], struct nf_conn *ct); int (*tuple_to_nfattr)(struct sk_buff *skb, const struct nf_conntrack_tuple *t); - int (*nfattr_to_tuple)(struct nfattr *tb[], + int (*nfattr_to_tuple)(struct nlattr *tb[], struct nf_conntrack_tuple *t); #ifdef CONFIG_SYSCTL @@ -113,7 +113,7 @@ extern void nf_conntrack_l4proto_unregister(struct nf_conntrack_l4proto *proto); /* Generic netlink helpers */ extern int nf_ct_port_tuple_to_nfattr(struct sk_buff *skb, const struct nf_conntrack_tuple *tuple); -extern int nf_ct_port_nfattr_to_tuple(struct nfattr *tb[], +extern int nf_ct_port_nfattr_to_tuple(struct nlattr *tb[], struct nf_conntrack_tuple *t); /* Log invalid packets */ diff --git a/include/net/netfilter/nf_nat_protocol.h b/include/net/netfilter/nf_nat_protocol.h index a9ec5ef61468..90a82de7e7e0 100644 --- a/include/net/netfilter/nf_nat_protocol.h +++ b/include/net/netfilter/nf_nat_protocol.h @@ -41,7 +41,7 @@ struct nf_nat_protocol int (*range_to_nfattr)(struct sk_buff *skb, const struct nf_nat_range *range); - int (*nfattr_to_range)(struct nfattr *tb[], + int (*nfattr_to_range)(struct nlattr *tb[], struct nf_nat_range *range); }; @@ -64,7 +64,7 @@ extern struct nf_nat_protocol *find_nat_proto(u_int16_t protonum); extern int nf_nat_port_range_to_nfattr(struct sk_buff *skb, const struct nf_nat_range *range); -extern int nf_nat_port_nfattr_to_range(struct nfattr *tb[], +extern int nf_nat_port_nfattr_to_range(struct nlattr *tb[], struct nf_nat_range *range); #endif /*_NF_NAT_PROTO_H*/ diff --git a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c index f813e02aab30..f8771e058b9e 100644 --- a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c +++ b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c @@ -363,32 +363,32 @@ getorigdst(struct sock *sk, int optval, void __user *user, int *len) static int ipv4_tuple_to_nfattr(struct sk_buff *skb, const struct nf_conntrack_tuple *tuple) { - NFA_PUT(skb, CTA_IP_V4_SRC, sizeof(u_int32_t), + NLA_PUT(skb, CTA_IP_V4_SRC, sizeof(u_int32_t), &tuple->src.u3.ip); - NFA_PUT(skb, CTA_IP_V4_DST, sizeof(u_int32_t), + NLA_PUT(skb, CTA_IP_V4_DST, sizeof(u_int32_t), &tuple->dst.u3.ip); return 0; -nfattr_failure: +nla_put_failure: return -1; } -static const size_t cta_min_ip[CTA_IP_MAX] = { - [CTA_IP_V4_SRC-1] = sizeof(u_int32_t), - [CTA_IP_V4_DST-1] = sizeof(u_int32_t), +static const size_t cta_min_ip[CTA_IP_MAX+1] = { + [CTA_IP_V4_SRC] = sizeof(u_int32_t), + [CTA_IP_V4_DST] = sizeof(u_int32_t), }; -static int ipv4_nfattr_to_tuple(struct nfattr *tb[], +static int ipv4_nfattr_to_tuple(struct nlattr *tb[], struct nf_conntrack_tuple *t) { - if (!tb[CTA_IP_V4_SRC-1] || !tb[CTA_IP_V4_DST-1]) + if (!tb[CTA_IP_V4_SRC] || !tb[CTA_IP_V4_DST]) return -EINVAL; if (nfattr_bad_size(tb, CTA_IP_MAX, cta_min_ip)) return -EINVAL; - t->src.u3.ip = *(__be32 *)NFA_DATA(tb[CTA_IP_V4_SRC-1]); - t->dst.u3.ip = *(__be32 *)NFA_DATA(tb[CTA_IP_V4_DST-1]); + t->src.u3.ip = *(__be32 *)nla_data(tb[CTA_IP_V4_SRC]); + t->dst.u3.ip = *(__be32 *)nla_data(tb[CTA_IP_V4_DST]); return 0; } diff --git a/net/ipv4/netfilter/nf_conntrack_proto_icmp.c b/net/ipv4/netfilter/nf_conntrack_proto_icmp.c index 6593fd2c5b10..714332b8869e 100644 --- a/net/ipv4/netfilter/nf_conntrack_proto_icmp.c +++ b/net/ipv4/netfilter/nf_conntrack_proto_icmp.c @@ -235,42 +235,42 @@ icmp_error(struct sk_buff *skb, unsigned int dataoff, static int icmp_tuple_to_nfattr(struct sk_buff *skb, const struct nf_conntrack_tuple *t) { - NFA_PUT(skb, CTA_PROTO_ICMP_ID, sizeof(u_int16_t), + NLA_PUT(skb, CTA_PROTO_ICMP_ID, sizeof(u_int16_t), &t->src.u.icmp.id); - NFA_PUT(skb, CTA_PROTO_ICMP_TYPE, sizeof(u_int8_t), + NLA_PUT(skb, CTA_PROTO_ICMP_TYPE, sizeof(u_int8_t), &t->dst.u.icmp.type); - NFA_PUT(skb, CTA_PROTO_ICMP_CODE, sizeof(u_int8_t), + NLA_PUT(skb, CTA_PROTO_ICMP_CODE, sizeof(u_int8_t), &t->dst.u.icmp.code); return 0; -nfattr_failure: +nla_put_failure: return -1; } -static const size_t cta_min_proto[CTA_PROTO_MAX] = { - [CTA_PROTO_ICMP_TYPE-1] = sizeof(u_int8_t), - [CTA_PROTO_ICMP_CODE-1] = sizeof(u_int8_t), - [CTA_PROTO_ICMP_ID-1] = sizeof(u_int16_t) +static const size_t cta_min_proto[CTA_PROTO_MAX+1] = { + [CTA_PROTO_ICMP_TYPE] = sizeof(u_int8_t), + [CTA_PROTO_ICMP_CODE] = sizeof(u_int8_t), + [CTA_PROTO_ICMP_ID] = sizeof(u_int16_t) }; -static int icmp_nfattr_to_tuple(struct nfattr *tb[], +static int icmp_nfattr_to_tuple(struct nlattr *tb[], struct nf_conntrack_tuple *tuple) { - if (!tb[CTA_PROTO_ICMP_TYPE-1] - || !tb[CTA_PROTO_ICMP_CODE-1] - || !tb[CTA_PROTO_ICMP_ID-1]) + if (!tb[CTA_PROTO_ICMP_TYPE] + || !tb[CTA_PROTO_ICMP_CODE] + || !tb[CTA_PROTO_ICMP_ID]) return -EINVAL; if (nfattr_bad_size(tb, CTA_PROTO_MAX, cta_min_proto)) return -EINVAL; tuple->dst.u.icmp.type = - *(u_int8_t *)NFA_DATA(tb[CTA_PROTO_ICMP_TYPE-1]); + *(u_int8_t *)nla_data(tb[CTA_PROTO_ICMP_TYPE]); tuple->dst.u.icmp.code = - *(u_int8_t *)NFA_DATA(tb[CTA_PROTO_ICMP_CODE-1]); + *(u_int8_t *)nla_data(tb[CTA_PROTO_ICMP_CODE]); tuple->src.u.icmp.id = - *(__be16 *)NFA_DATA(tb[CTA_PROTO_ICMP_ID-1]); + *(__be16 *)nla_data(tb[CTA_PROTO_ICMP_ID]); if (tuple->dst.u.icmp.type >= sizeof(invmap) || !invmap[tuple->dst.u.icmp.type]) diff --git a/net/ipv4/netfilter/nf_nat_core.c b/net/ipv4/netfilter/nf_nat_core.c index deab27facbad..4bdbb128fe50 100644 --- a/net/ipv4/netfilter/nf_nat_core.c +++ b/net/ipv4/netfilter/nf_nat_core.c @@ -547,38 +547,38 @@ int nf_nat_port_range_to_nfattr(struct sk_buff *skb, const struct nf_nat_range *range) { - NFA_PUT(skb, CTA_PROTONAT_PORT_MIN, sizeof(__be16), + NLA_PUT(skb, CTA_PROTONAT_PORT_MIN, sizeof(__be16), &range->min.tcp.port); - NFA_PUT(skb, CTA_PROTONAT_PORT_MAX, sizeof(__be16), + NLA_PUT(skb, CTA_PROTONAT_PORT_MAX, sizeof(__be16), &range->max.tcp.port); return 0; -nfattr_failure: +nla_put_failure: return -1; } EXPORT_SYMBOL_GPL(nf_nat_port_nfattr_to_range); int -nf_nat_port_nfattr_to_range(struct nfattr *tb[], struct nf_nat_range *range) +nf_nat_port_nfattr_to_range(struct nlattr *tb[], struct nf_nat_range *range) { int ret = 0; /* we have to return whether we actually parsed something or not */ - if (tb[CTA_PROTONAT_PORT_MIN-1]) { + if (tb[CTA_PROTONAT_PORT_MIN]) { ret = 1; range->min.tcp.port = - *(__be16 *)NFA_DATA(tb[CTA_PROTONAT_PORT_MIN-1]); + *(__be16 *)nla_data(tb[CTA_PROTONAT_PORT_MIN]); } - if (!tb[CTA_PROTONAT_PORT_MAX-1]) { + if (!tb[CTA_PROTONAT_PORT_MAX]) { if (ret) range->max.tcp.port = range->min.tcp.port; } else { ret = 1; range->max.tcp.port = - *(__be16 *)NFA_DATA(tb[CTA_PROTONAT_PORT_MAX-1]); + *(__be16 *)nla_data(tb[CTA_PROTONAT_PORT_MAX]); } return ret; diff --git a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c index 3153e15e0f7c..f0ea3fb51670 100644 --- a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c +++ b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c @@ -340,33 +340,33 @@ static ctl_table nf_ct_ipv6_sysctl_table[] = { static int ipv6_tuple_to_nfattr(struct sk_buff *skb, const struct nf_conntrack_tuple *tuple) { - NFA_PUT(skb, CTA_IP_V6_SRC, sizeof(u_int32_t) * 4, + NLA_PUT(skb, CTA_IP_V6_SRC, sizeof(u_int32_t) * 4, &tuple->src.u3.ip6); - NFA_PUT(skb, CTA_IP_V6_DST, sizeof(u_int32_t) * 4, + NLA_PUT(skb, CTA_IP_V6_DST, sizeof(u_int32_t) * 4, &tuple->dst.u3.ip6); return 0; -nfattr_failure: +nla_put_failure: return -1; } -static const size_t cta_min_ip[CTA_IP_MAX] = { - [CTA_IP_V6_SRC-1] = sizeof(u_int32_t)*4, - [CTA_IP_V6_DST-1] = sizeof(u_int32_t)*4, +static const size_t cta_min_ip[CTA_IP_MAX+1] = { + [CTA_IP_V6_SRC] = sizeof(u_int32_t)*4, + [CTA_IP_V6_DST] = sizeof(u_int32_t)*4, }; -static int ipv6_nfattr_to_tuple(struct nfattr *tb[], +static int ipv6_nfattr_to_tuple(struct nlattr *tb[], struct nf_conntrack_tuple *t) { - if (!tb[CTA_IP_V6_SRC-1] || !tb[CTA_IP_V6_DST-1]) + if (!tb[CTA_IP_V6_SRC] || !tb[CTA_IP_V6_DST]) return -EINVAL; if (nfattr_bad_size(tb, CTA_IP_MAX, cta_min_ip)) return -EINVAL; - memcpy(&t->src.u3.ip6, NFA_DATA(tb[CTA_IP_V6_SRC-1]), + memcpy(&t->src.u3.ip6, nla_data(tb[CTA_IP_V6_SRC]), sizeof(u_int32_t) * 4); - memcpy(&t->dst.u3.ip6, NFA_DATA(tb[CTA_IP_V6_DST-1]), + memcpy(&t->dst.u3.ip6, nla_data(tb[CTA_IP_V6_DST]), sizeof(u_int32_t) * 4); return 0; diff --git a/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c b/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c index ab154fb90018..c18183823faf 100644 --- a/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c +++ b/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c @@ -213,42 +213,42 @@ icmpv6_error(struct sk_buff *skb, unsigned int dataoff, static int icmpv6_tuple_to_nfattr(struct sk_buff *skb, const struct nf_conntrack_tuple *t) { - NFA_PUT(skb, CTA_PROTO_ICMPV6_ID, sizeof(u_int16_t), + NLA_PUT(skb, CTA_PROTO_ICMPV6_ID, sizeof(u_int16_t), &t->src.u.icmp.id); - NFA_PUT(skb, CTA_PROTO_ICMPV6_TYPE, sizeof(u_int8_t), + NLA_PUT(skb, CTA_PROTO_ICMPV6_TYPE, sizeof(u_int8_t), &t->dst.u.icmp.type); - NFA_PUT(skb, CTA_PROTO_ICMPV6_CODE, sizeof(u_int8_t), + NLA_PUT(skb, CTA_PROTO_ICMPV6_CODE, sizeof(u_int8_t), &t->dst.u.icmp.code); return 0; -nfattr_failure: +nla_put_failure: return -1; } -static const size_t cta_min_proto[CTA_PROTO_MAX] = { - [CTA_PROTO_ICMPV6_TYPE-1] = sizeof(u_int8_t), - [CTA_PROTO_ICMPV6_CODE-1] = sizeof(u_int8_t), - [CTA_PROTO_ICMPV6_ID-1] = sizeof(u_int16_t) +static const size_t cta_min_proto[CTA_PROTO_MAX+1] = { + [CTA_PROTO_ICMPV6_TYPE] = sizeof(u_int8_t), + [CTA_PROTO_ICMPV6_CODE] = sizeof(u_int8_t), + [CTA_PROTO_ICMPV6_ID] = sizeof(u_int16_t) }; -static int icmpv6_nfattr_to_tuple(struct nfattr *tb[], +static int icmpv6_nfattr_to_tuple(struct nlattr *tb[], struct nf_conntrack_tuple *tuple) { - if (!tb[CTA_PROTO_ICMPV6_TYPE-1] - || !tb[CTA_PROTO_ICMPV6_CODE-1] - || !tb[CTA_PROTO_ICMPV6_ID-1]) + if (!tb[CTA_PROTO_ICMPV6_TYPE] + || !tb[CTA_PROTO_ICMPV6_CODE] + || !tb[CTA_PROTO_ICMPV6_ID]) return -EINVAL; if (nfattr_bad_size(tb, CTA_PROTO_MAX, cta_min_proto)) return -EINVAL; tuple->dst.u.icmp.type = - *(u_int8_t *)NFA_DATA(tb[CTA_PROTO_ICMPV6_TYPE-1]); + *(u_int8_t *)nla_data(tb[CTA_PROTO_ICMPV6_TYPE]); tuple->dst.u.icmp.code = - *(u_int8_t *)NFA_DATA(tb[CTA_PROTO_ICMPV6_CODE-1]); + *(u_int8_t *)nla_data(tb[CTA_PROTO_ICMPV6_CODE]); tuple->src.u.icmp.id = - *(__be16 *)NFA_DATA(tb[CTA_PROTO_ICMPV6_ID-1]); + *(__be16 *)nla_data(tb[CTA_PROTO_ICMPV6_ID]); if (tuple->dst.u.icmp.type < 128 || tuple->dst.u.icmp.type - 128 >= sizeof(invmap) diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c index 0fe11889ce14..b64656abc4e0 100644 --- a/net/netfilter/nf_conntrack_core.c +++ b/net/netfilter/nf_conntrack_core.c @@ -827,40 +827,39 @@ EXPORT_SYMBOL_GPL(__nf_ct_refresh_acct); #include #include - /* Generic function for tcp/udp/sctp/dccp and alike. This needs to be * in ip_conntrack_core, since we don't want the protocols to autoload * or depend on ctnetlink */ int nf_ct_port_tuple_to_nfattr(struct sk_buff *skb, const struct nf_conntrack_tuple *tuple) { - NFA_PUT(skb, CTA_PROTO_SRC_PORT, sizeof(u_int16_t), + NLA_PUT(skb, CTA_PROTO_SRC_PORT, sizeof(u_int16_t), &tuple->src.u.tcp.port); - NFA_PUT(skb, CTA_PROTO_DST_PORT, sizeof(u_int16_t), + NLA_PUT(skb, CTA_PROTO_DST_PORT, sizeof(u_int16_t), &tuple->dst.u.tcp.port); return 0; -nfattr_failure: +nla_put_failure: return -1; } EXPORT_SYMBOL_GPL(nf_ct_port_tuple_to_nfattr); -static const size_t cta_min_proto[CTA_PROTO_MAX] = { - [CTA_PROTO_SRC_PORT-1] = sizeof(u_int16_t), - [CTA_PROTO_DST_PORT-1] = sizeof(u_int16_t) +static const size_t cta_min_proto[CTA_PROTO_MAX+1] = { + [CTA_PROTO_SRC_PORT] = sizeof(u_int16_t), + [CTA_PROTO_DST_PORT] = sizeof(u_int16_t) }; -int nf_ct_port_nfattr_to_tuple(struct nfattr *tb[], +int nf_ct_port_nfattr_to_tuple(struct nlattr *tb[], struct nf_conntrack_tuple *t) { - if (!tb[CTA_PROTO_SRC_PORT-1] || !tb[CTA_PROTO_DST_PORT-1]) + if (!tb[CTA_PROTO_SRC_PORT] || !tb[CTA_PROTO_DST_PORT]) return -EINVAL; if (nfattr_bad_size(tb, CTA_PROTO_MAX, cta_min_proto)) return -EINVAL; - t->src.u.tcp.port = *(__be16 *)NFA_DATA(tb[CTA_PROTO_SRC_PORT-1]); - t->dst.u.tcp.port = *(__be16 *)NFA_DATA(tb[CTA_PROTO_DST_PORT-1]); + t->src.u.tcp.port = *(__be16 *)nla_data(tb[CTA_PROTO_SRC_PORT]); + t->dst.u.tcp.port = *(__be16 *)nla_data(tb[CTA_PROTO_DST_PORT]); return 0; } diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c index 5080045fdc74..221c38f889bf 100644 --- a/net/netfilter/nf_conntrack_netlink.c +++ b/net/netfilter/nf_conntrack_netlink.c @@ -54,18 +54,21 @@ ctnetlink_dump_tuples_proto(struct sk_buff *skb, struct nf_conntrack_l4proto *l4proto) { int ret = 0; - struct nfattr *nest_parms = NFA_NEST(skb, CTA_TUPLE_PROTO); + struct nlattr *nest_parms; - NFA_PUT(skb, CTA_PROTO_NUM, sizeof(u_int8_t), &tuple->dst.protonum); + nest_parms = nla_nest_start(skb, CTA_TUPLE_PROTO | NLA_F_NESTED); + if (!nest_parms) + goto nla_put_failure; + NLA_PUT(skb, CTA_PROTO_NUM, sizeof(u_int8_t), &tuple->dst.protonum); if (likely(l4proto->tuple_to_nfattr)) ret = l4proto->tuple_to_nfattr(skb, tuple); - NFA_NEST_END(skb, nest_parms); + nla_nest_end(skb, nest_parms); return ret; -nfattr_failure: +nla_put_failure: return -1; } @@ -75,16 +78,20 @@ ctnetlink_dump_tuples_ip(struct sk_buff *skb, struct nf_conntrack_l3proto *l3proto) { int ret = 0; - struct nfattr *nest_parms = NFA_NEST(skb, CTA_TUPLE_IP); + struct nlattr *nest_parms; + + nest_parms = nla_nest_start(skb, CTA_TUPLE_IP | NLA_F_NESTED); + if (!nest_parms) + goto nla_put_failure; if (likely(l3proto->tuple_to_nfattr)) ret = l3proto->tuple_to_nfattr(skb, tuple); - NFA_NEST_END(skb, nest_parms); + nla_nest_end(skb, nest_parms); return ret; -nfattr_failure: +nla_put_failure: return -1; } @@ -114,10 +121,10 @@ static inline int ctnetlink_dump_status(struct sk_buff *skb, const struct nf_conn *ct) { __be32 status = htonl((u_int32_t) ct->status); - NFA_PUT(skb, CTA_STATUS, sizeof(status), &status); + NLA_PUT(skb, CTA_STATUS, sizeof(status), &status); return 0; -nfattr_failure: +nla_put_failure: return -1; } @@ -132,10 +139,10 @@ ctnetlink_dump_timeout(struct sk_buff *skb, const struct nf_conn *ct) else timeout = htonl(timeout_l / HZ); - NFA_PUT(skb, CTA_TIMEOUT, sizeof(timeout), &timeout); + NLA_PUT(skb, CTA_TIMEOUT, sizeof(timeout), &timeout); return 0; -nfattr_failure: +nla_put_failure: return -1; } @@ -143,7 +150,7 @@ static inline int ctnetlink_dump_protoinfo(struct sk_buff *skb, const struct nf_conn *ct) { struct nf_conntrack_l4proto *l4proto = nf_ct_l4proto_find_get(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.l3num, ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum); - struct nfattr *nest_proto; + struct nlattr *nest_proto; int ret; if (!l4proto->to_nfattr) { @@ -151,17 +158,19 @@ ctnetlink_dump_protoinfo(struct sk_buff *skb, const struct nf_conn *ct) return 0; } - nest_proto = NFA_NEST(skb, CTA_PROTOINFO); + nest_proto = nla_nest_start(skb, CTA_PROTOINFO | NLA_F_NESTED); + if (!nest_proto) + goto nla_put_failure; ret = l4proto->to_nfattr(skb, nest_proto, ct); nf_ct_l4proto_put(l4proto); - NFA_NEST_END(skb, nest_proto); + nla_nest_end(skb, nest_proto); return ret; -nfattr_failure: +nla_put_failure: nf_ct_l4proto_put(l4proto); return -1; } @@ -169,7 +178,7 @@ nfattr_failure: static inline int ctnetlink_dump_helpinfo(struct sk_buff *skb, const struct nf_conn *ct) { - struct nfattr *nest_helper; + struct nlattr *nest_helper; const struct nf_conn_help *help = nfct_help(ct); struct nf_conntrack_helper *helper; @@ -181,18 +190,20 @@ ctnetlink_dump_helpinfo(struct sk_buff *skb, const struct nf_conn *ct) if (!helper) goto out; - nest_helper = NFA_NEST(skb, CTA_HELP); - NFA_PUT(skb, CTA_HELP_NAME, strlen(helper->name), helper->name); + nest_helper = nla_nest_start(skb, CTA_HELP | NLA_F_NESTED); + if (!nest_helper) + goto nla_put_failure; + NLA_PUT(skb, CTA_HELP_NAME, strlen(helper->name), helper->name); if (helper->to_nfattr) helper->to_nfattr(skb, ct); - NFA_NEST_END(skb, nest_helper); + nla_nest_end(skb, nest_helper); out: rcu_read_unlock(); return 0; -nfattr_failure: +nla_put_failure: rcu_read_unlock(); return -1; } @@ -203,20 +214,24 @@ ctnetlink_dump_counters(struct sk_buff *skb, const struct nf_conn *ct, enum ip_conntrack_dir dir) { enum ctattr_type type = dir ? CTA_COUNTERS_REPLY: CTA_COUNTERS_ORIG; - struct nfattr *nest_count = NFA_NEST(skb, type); + struct nlattr *nest_count; __be32 tmp; + nest_count = nla_nest_start(skb, type | NLA_F_NESTED); + if (!nest_count) + goto nla_put_failure; + tmp = htonl(ct->counters[dir].packets); - NFA_PUT(skb, CTA_COUNTERS32_PACKETS, sizeof(u_int32_t), &tmp); + NLA_PUT(skb, CTA_COUNTERS32_PACKETS, sizeof(u_int32_t), &tmp); tmp = htonl(ct->counters[dir].bytes); - NFA_PUT(skb, CTA_COUNTERS32_BYTES, sizeof(u_int32_t), &tmp); + NLA_PUT(skb, CTA_COUNTERS32_BYTES, sizeof(u_int32_t), &tmp); - NFA_NEST_END(skb, nest_count); + nla_nest_end(skb, nest_count); return 0; -nfattr_failure: +nla_put_failure: return -1; } #else @@ -229,10 +244,10 @@ ctnetlink_dump_mark(struct sk_buff *skb, const struct nf_conn *ct) { __be32 mark = htonl(ct->mark); - NFA_PUT(skb, CTA_MARK, sizeof(u_int32_t), &mark); + NLA_PUT(skb, CTA_MARK, sizeof(u_int32_t), &mark); return 0; -nfattr_failure: +nla_put_failure: return -1; } #else @@ -243,10 +258,10 @@ static inline int ctnetlink_dump_id(struct sk_buff *skb, const struct nf_conn *ct) { __be32 id = htonl(ct->id); - NFA_PUT(skb, CTA_ID, sizeof(u_int32_t), &id); + NLA_PUT(skb, CTA_ID, sizeof(u_int32_t), &id); return 0; -nfattr_failure: +nla_put_failure: return -1; } @@ -255,10 +270,10 @@ ctnetlink_dump_use(struct sk_buff *skb, const struct nf_conn *ct) { __be32 use = htonl(atomic_read(&ct->ct_general.use)); - NFA_PUT(skb, CTA_USE, sizeof(u_int32_t), &use); + NLA_PUT(skb, CTA_USE, sizeof(u_int32_t), &use); return 0; -nfattr_failure: +nla_put_failure: return -1; } @@ -271,7 +286,7 @@ ctnetlink_fill_info(struct sk_buff *skb, u32 pid, u32 seq, { struct nlmsghdr *nlh; struct nfgenmsg *nfmsg; - struct nfattr *nest_parms; + struct nlattr *nest_parms; unsigned char *b = skb_tail_pointer(skb); event |= NFNL_SUBSYS_CTNETLINK << 8; @@ -284,15 +299,19 @@ ctnetlink_fill_info(struct sk_buff *skb, u32 pid, u32 seq, nfmsg->version = NFNETLINK_V0; nfmsg->res_id = 0; - nest_parms = NFA_NEST(skb, CTA_TUPLE_ORIG); + nest_parms = nla_nest_start(skb, CTA_TUPLE_ORIG | NLA_F_NESTED); + if (!nest_parms) + goto nla_put_failure; if (ctnetlink_dump_tuples(skb, tuple(ct, IP_CT_DIR_ORIGINAL)) < 0) - goto nfattr_failure; - NFA_NEST_END(skb, nest_parms); + goto nla_put_failure; + nla_nest_end(skb, nest_parms); - nest_parms = NFA_NEST(skb, CTA_TUPLE_REPLY); + nest_parms = nla_nest_start(skb, CTA_TUPLE_REPLY | NLA_F_NESTED); + if (!nest_parms) + goto nla_put_failure; if (ctnetlink_dump_tuples(skb, tuple(ct, IP_CT_DIR_REPLY)) < 0) - goto nfattr_failure; - NFA_NEST_END(skb, nest_parms); + goto nla_put_failure; + nla_nest_end(skb, nest_parms); if (ctnetlink_dump_status(skb, ct) < 0 || ctnetlink_dump_timeout(skb, ct) < 0 || @@ -303,13 +322,13 @@ ctnetlink_fill_info(struct sk_buff *skb, u32 pid, u32 seq, ctnetlink_dump_mark(skb, ct) < 0 || ctnetlink_dump_id(skb, ct) < 0 || ctnetlink_dump_use(skb, ct) < 0) - goto nfattr_failure; + goto nla_put_failure; nlh->nlmsg_len = skb_tail_pointer(skb) - b; return skb->len; nlmsg_failure: -nfattr_failure: +nla_put_failure: nlmsg_trim(skb, b); return -1; } @@ -320,7 +339,7 @@ static int ctnetlink_conntrack_event(struct notifier_block *this, { struct nlmsghdr *nlh; struct nfgenmsg *nfmsg; - struct nfattr *nest_parms; + struct nlattr *nest_parms; struct nf_conn *ct = (struct nf_conn *)ptr; struct sk_buff *skb; unsigned int type; @@ -362,45 +381,49 @@ static int ctnetlink_conntrack_event(struct notifier_block *this, nfmsg->version = NFNETLINK_V0; nfmsg->res_id = 0; - nest_parms = NFA_NEST(skb, CTA_TUPLE_ORIG); + nest_parms = nla_nest_start(skb, CTA_TUPLE_ORIG | NLA_F_NESTED); + if (!nest_parms) + goto nla_put_failure; if (ctnetlink_dump_tuples(skb, tuple(ct, IP_CT_DIR_ORIGINAL)) < 0) - goto nfattr_failure; - NFA_NEST_END(skb, nest_parms); + goto nla_put_failure; + nla_nest_end(skb, nest_parms); - nest_parms = NFA_NEST(skb, CTA_TUPLE_REPLY); + nest_parms = nla_nest_start(skb, CTA_TUPLE_REPLY | NLA_F_NESTED); + if (!nest_parms) + goto nla_put_failure; if (ctnetlink_dump_tuples(skb, tuple(ct, IP_CT_DIR_REPLY)) < 0) - goto nfattr_failure; - NFA_NEST_END(skb, nest_parms); + goto nla_put_failure; + nla_nest_end(skb, nest_parms); if (events & IPCT_DESTROY) { if (ctnetlink_dump_counters(skb, ct, IP_CT_DIR_ORIGINAL) < 0 || ctnetlink_dump_counters(skb, ct, IP_CT_DIR_REPLY) < 0) - goto nfattr_failure; + goto nla_put_failure; } else { if (ctnetlink_dump_status(skb, ct) < 0) - goto nfattr_failure; + goto nla_put_failure; if (ctnetlink_dump_timeout(skb, ct) < 0) - goto nfattr_failure; + goto nla_put_failure; if (events & IPCT_PROTOINFO && ctnetlink_dump_protoinfo(skb, ct) < 0) - goto nfattr_failure; + goto nla_put_failure; if ((events & IPCT_HELPER || nfct_help(ct)) && ctnetlink_dump_helpinfo(skb, ct) < 0) - goto nfattr_failure; + goto nla_put_failure; #ifdef CONFIG_NF_CONNTRACK_MARK if ((events & IPCT_MARK || ct->mark) && ctnetlink_dump_mark(skb, ct) < 0) - goto nfattr_failure; + goto nla_put_failure; #endif if (events & IPCT_COUNTER_FILLING && (ctnetlink_dump_counters(skb, ct, IP_CT_DIR_ORIGINAL) < 0 || ctnetlink_dump_counters(skb, ct, IP_CT_DIR_REPLY) < 0)) - goto nfattr_failure; + goto nla_put_failure; } nlh->nlmsg_len = skb->tail - b; @@ -408,7 +431,7 @@ static int ctnetlink_conntrack_event(struct notifier_block *this, return NOTIFY_DONE; nlmsg_failure: -nfattr_failure: +nla_put_failure: kfree_skb(skb); return NOTIFY_DONE; } @@ -479,13 +502,13 @@ out: } static inline int -ctnetlink_parse_tuple_ip(struct nfattr *attr, struct nf_conntrack_tuple *tuple) +ctnetlink_parse_tuple_ip(struct nlattr *attr, struct nf_conntrack_tuple *tuple) { - struct nfattr *tb[CTA_IP_MAX]; + struct nlattr *tb[CTA_IP_MAX+1]; struct nf_conntrack_l3proto *l3proto; int ret = 0; - nfattr_parse_nested(tb, CTA_IP_MAX, attr); + nla_parse_nested(tb, CTA_IP_MAX, attr, NULL); l3proto = nf_ct_l3proto_find_get(tuple->src.l3num); @@ -497,26 +520,26 @@ ctnetlink_parse_tuple_ip(struct nfattr *attr, struct nf_conntrack_tuple *tuple) return ret; } -static const size_t cta_min_proto[CTA_PROTO_MAX] = { - [CTA_PROTO_NUM-1] = sizeof(u_int8_t), +static const size_t cta_min_proto[CTA_PROTO_MAX+1] = { + [CTA_PROTO_NUM] = sizeof(u_int8_t), }; static inline int -ctnetlink_parse_tuple_proto(struct nfattr *attr, +ctnetlink_parse_tuple_proto(struct nlattr *attr, struct nf_conntrack_tuple *tuple) { - struct nfattr *tb[CTA_PROTO_MAX]; + struct nlattr *tb[CTA_PROTO_MAX+1]; struct nf_conntrack_l4proto *l4proto; int ret = 0; - nfattr_parse_nested(tb, CTA_PROTO_MAX, attr); + nla_parse_nested(tb, CTA_PROTO_MAX, attr, NULL); if (nfattr_bad_size(tb, CTA_PROTO_MAX, cta_min_proto)) return -EINVAL; - if (!tb[CTA_PROTO_NUM-1]) + if (!tb[CTA_PROTO_NUM]) return -EINVAL; - tuple->dst.protonum = *(u_int8_t *)NFA_DATA(tb[CTA_PROTO_NUM-1]); + tuple->dst.protonum = *(u_int8_t *)nla_data(tb[CTA_PROTO_NUM]); l4proto = nf_ct_l4proto_find_get(tuple->src.l3num, tuple->dst.protonum); @@ -529,29 +552,29 @@ ctnetlink_parse_tuple_proto(struct nfattr *attr, } static inline int -ctnetlink_parse_tuple(struct nfattr *cda[], struct nf_conntrack_tuple *tuple, +ctnetlink_parse_tuple(struct nlattr *cda[], struct nf_conntrack_tuple *tuple, enum ctattr_tuple type, u_int8_t l3num) { - struct nfattr *tb[CTA_TUPLE_MAX]; + struct nlattr *tb[CTA_TUPLE_MAX+1]; int err; memset(tuple, 0, sizeof(*tuple)); - nfattr_parse_nested(tb, CTA_TUPLE_MAX, cda[type-1]); + nla_parse_nested(tb, CTA_TUPLE_MAX, cda[type], NULL); - if (!tb[CTA_TUPLE_IP-1]) + if (!tb[CTA_TUPLE_IP]) return -EINVAL; tuple->src.l3num = l3num; - err = ctnetlink_parse_tuple_ip(tb[CTA_TUPLE_IP-1], tuple); + err = ctnetlink_parse_tuple_ip(tb[CTA_TUPLE_IP], tuple); if (err < 0) return err; - if (!tb[CTA_TUPLE_PROTO-1]) + if (!tb[CTA_TUPLE_PROTO]) return -EINVAL; - err = ctnetlink_parse_tuple_proto(tb[CTA_TUPLE_PROTO-1], tuple); + err = ctnetlink_parse_tuple_proto(tb[CTA_TUPLE_PROTO], tuple); if (err < 0) return err; @@ -565,19 +588,19 @@ ctnetlink_parse_tuple(struct nfattr *cda[], struct nf_conntrack_tuple *tuple, } #ifdef CONFIG_NF_NAT_NEEDED -static const size_t cta_min_protonat[CTA_PROTONAT_MAX] = { - [CTA_PROTONAT_PORT_MIN-1] = sizeof(u_int16_t), - [CTA_PROTONAT_PORT_MAX-1] = sizeof(u_int16_t), +static const size_t cta_min_protonat[CTA_PROTONAT_MAX+1] = { + [CTA_PROTONAT_PORT_MIN] = sizeof(u_int16_t), + [CTA_PROTONAT_PORT_MAX] = sizeof(u_int16_t), }; -static int nfnetlink_parse_nat_proto(struct nfattr *attr, +static int nfnetlink_parse_nat_proto(struct nlattr *attr, const struct nf_conn *ct, struct nf_nat_range *range) { - struct nfattr *tb[CTA_PROTONAT_MAX]; + struct nlattr *tb[CTA_PROTONAT_MAX+1]; struct nf_nat_protocol *npt; - nfattr_parse_nested(tb, CTA_PROTONAT_MAX, attr); + nla_parse_nested(tb, CTA_PROTONAT_MAX, attr, NULL); if (nfattr_bad_size(tb, CTA_PROTONAT_MAX, cta_min_protonat)) return -EINVAL; @@ -598,40 +621,40 @@ static int nfnetlink_parse_nat_proto(struct nfattr *attr, return 0; } -static const size_t cta_min_nat[CTA_NAT_MAX] = { - [CTA_NAT_MINIP-1] = sizeof(u_int32_t), - [CTA_NAT_MAXIP-1] = sizeof(u_int32_t), +static const size_t cta_min_nat[CTA_NAT_MAX+1] = { + [CTA_NAT_MINIP] = sizeof(u_int32_t), + [CTA_NAT_MAXIP] = sizeof(u_int32_t), }; static inline int -nfnetlink_parse_nat(struct nfattr *nat, +nfnetlink_parse_nat(struct nlattr *nat, const struct nf_conn *ct, struct nf_nat_range *range) { - struct nfattr *tb[CTA_NAT_MAX]; + struct nlattr *tb[CTA_NAT_MAX+1]; int err; memset(range, 0, sizeof(*range)); - nfattr_parse_nested(tb, CTA_NAT_MAX, nat); + nla_parse_nested(tb, CTA_NAT_MAX, nat, NULL); if (nfattr_bad_size(tb, CTA_NAT_MAX, cta_min_nat)) return -EINVAL; - if (tb[CTA_NAT_MINIP-1]) - range->min_ip = *(__be32 *)NFA_DATA(tb[CTA_NAT_MINIP-1]); + if (tb[CTA_NAT_MINIP]) + range->min_ip = *(__be32 *)nla_data(tb[CTA_NAT_MINIP]); - if (!tb[CTA_NAT_MAXIP-1]) + if (!tb[CTA_NAT_MAXIP]) range->max_ip = range->min_ip; else - range->max_ip = *(__be32 *)NFA_DATA(tb[CTA_NAT_MAXIP-1]); + range->max_ip = *(__be32 *)nla_data(tb[CTA_NAT_MAXIP]); if (range->min_ip) range->flags |= IP_NAT_RANGE_MAP_IPS; - if (!tb[CTA_NAT_PROTO-1]) + if (!tb[CTA_NAT_PROTO]) return 0; - err = nfnetlink_parse_nat_proto(tb[CTA_NAT_PROTO-1], ct, range); + err = nfnetlink_parse_nat_proto(tb[CTA_NAT_PROTO], ct, range); if (err < 0) return err; @@ -640,31 +663,31 @@ nfnetlink_parse_nat(struct nfattr *nat, #endif static inline int -ctnetlink_parse_help(struct nfattr *attr, char **helper_name) +ctnetlink_parse_help(struct nlattr *attr, char **helper_name) { - struct nfattr *tb[CTA_HELP_MAX]; + struct nlattr *tb[CTA_HELP_MAX+1]; - nfattr_parse_nested(tb, CTA_HELP_MAX, attr); + nla_parse_nested(tb, CTA_HELP_MAX, attr, NULL); - if (!tb[CTA_HELP_NAME-1]) + if (!tb[CTA_HELP_NAME]) return -EINVAL; - *helper_name = NFA_DATA(tb[CTA_HELP_NAME-1]); + *helper_name = nla_data(tb[CTA_HELP_NAME]); return 0; } -static const size_t cta_min[CTA_MAX] = { - [CTA_STATUS-1] = sizeof(u_int32_t), - [CTA_TIMEOUT-1] = sizeof(u_int32_t), - [CTA_MARK-1] = sizeof(u_int32_t), - [CTA_USE-1] = sizeof(u_int32_t), - [CTA_ID-1] = sizeof(u_int32_t) +static const size_t cta_min[CTA_MAX+1] = { + [CTA_STATUS] = sizeof(u_int32_t), + [CTA_TIMEOUT] = sizeof(u_int32_t), + [CTA_MARK] = sizeof(u_int32_t), + [CTA_USE] = sizeof(u_int32_t), + [CTA_ID] = sizeof(u_int32_t) }; static int ctnetlink_del_conntrack(struct sock *ctnl, struct sk_buff *skb, - struct nlmsghdr *nlh, struct nfattr *cda[]) + struct nlmsghdr *nlh, struct nlattr *cda[]) { struct nf_conntrack_tuple_hash *h; struct nf_conntrack_tuple tuple; @@ -676,9 +699,9 @@ ctnetlink_del_conntrack(struct sock *ctnl, struct sk_buff *skb, if (nfattr_bad_size(cda, CTA_MAX, cta_min)) return -EINVAL; - if (cda[CTA_TUPLE_ORIG-1]) + if (cda[CTA_TUPLE_ORIG]) err = ctnetlink_parse_tuple(cda, &tuple, CTA_TUPLE_ORIG, u3); - else if (cda[CTA_TUPLE_REPLY-1]) + else if (cda[CTA_TUPLE_REPLY]) err = ctnetlink_parse_tuple(cda, &tuple, CTA_TUPLE_REPLY, u3); else { /* Flush the whole table */ @@ -695,8 +718,8 @@ ctnetlink_del_conntrack(struct sock *ctnl, struct sk_buff *skb, ct = nf_ct_tuplehash_to_ctrack(h); - if (cda[CTA_ID-1]) { - u_int32_t id = ntohl(*(__be32 *)NFA_DATA(cda[CTA_ID-1])); + if (cda[CTA_ID]) { + u_int32_t id = ntohl(*(__be32 *)nla_data(cda[CTA_ID])); if (ct->id != id) { nf_ct_put(ct); return -ENOENT; @@ -712,7 +735,7 @@ ctnetlink_del_conntrack(struct sock *ctnl, struct sk_buff *skb, static int ctnetlink_get_conntrack(struct sock *ctnl, struct sk_buff *skb, - struct nlmsghdr *nlh, struct nfattr *cda[]) + struct nlmsghdr *nlh, struct nlattr *cda[]) { struct nf_conntrack_tuple_hash *h; struct nf_conntrack_tuple tuple; @@ -734,9 +757,9 @@ ctnetlink_get_conntrack(struct sock *ctnl, struct sk_buff *skb, if (nfattr_bad_size(cda, CTA_MAX, cta_min)) return -EINVAL; - if (cda[CTA_TUPLE_ORIG-1]) + if (cda[CTA_TUPLE_ORIG]) err = ctnetlink_parse_tuple(cda, &tuple, CTA_TUPLE_ORIG, u3); - else if (cda[CTA_TUPLE_REPLY-1]) + else if (cda[CTA_TUPLE_REPLY]) err = ctnetlink_parse_tuple(cda, &tuple, CTA_TUPLE_REPLY, u3); else return -EINVAL; @@ -776,10 +799,10 @@ out: } static inline int -ctnetlink_change_status(struct nf_conn *ct, struct nfattr *cda[]) +ctnetlink_change_status(struct nf_conn *ct, struct nlattr *cda[]) { unsigned long d; - unsigned int status = ntohl(*(__be32 *)NFA_DATA(cda[CTA_STATUS-1])); + unsigned int status = ntohl(*(__be32 *)nla_data(cda[CTA_STATUS])); d = ct->status ^ status; if (d & (IPS_EXPECTED|IPS_CONFIRMED|IPS_DYING)) @@ -795,14 +818,14 @@ ctnetlink_change_status(struct nf_conn *ct, struct nfattr *cda[]) /* ASSURED bit can only be set */ return -EINVAL; - if (cda[CTA_NAT_SRC-1] || cda[CTA_NAT_DST-1]) { + if (cda[CTA_NAT_SRC] || cda[CTA_NAT_DST]) { #ifndef CONFIG_NF_NAT_NEEDED return -EINVAL; #else struct nf_nat_range range; - if (cda[CTA_NAT_DST-1]) { - if (nfnetlink_parse_nat(cda[CTA_NAT_DST-1], ct, + if (cda[CTA_NAT_DST]) { + if (nfnetlink_parse_nat(cda[CTA_NAT_DST], ct, &range) < 0) return -EINVAL; if (nf_nat_initialized(ct, @@ -810,8 +833,8 @@ ctnetlink_change_status(struct nf_conn *ct, struct nfattr *cda[]) return -EEXIST; nf_nat_setup_info(ct, &range, NF_IP_PRE_ROUTING); } - if (cda[CTA_NAT_SRC-1]) { - if (nfnetlink_parse_nat(cda[CTA_NAT_SRC-1], ct, + if (cda[CTA_NAT_SRC]) { + if (nfnetlink_parse_nat(cda[CTA_NAT_SRC], ct, &range) < 0) return -EINVAL; if (nf_nat_initialized(ct, @@ -831,7 +854,7 @@ ctnetlink_change_status(struct nf_conn *ct, struct nfattr *cda[]) static inline int -ctnetlink_change_helper(struct nf_conn *ct, struct nfattr *cda[]) +ctnetlink_change_helper(struct nf_conn *ct, struct nlattr *cda[]) { struct nf_conntrack_helper *helper; struct nf_conn_help *help = nfct_help(ct); @@ -842,7 +865,7 @@ ctnetlink_change_helper(struct nf_conn *ct, struct nfattr *cda[]) if (ct->master) return -EINVAL; - err = ctnetlink_parse_help(cda[CTA_HELP-1], &helpname); + err = ctnetlink_parse_help(cda[CTA_HELP], &helpname); if (err < 0) return err; @@ -879,9 +902,9 @@ ctnetlink_change_helper(struct nf_conn *ct, struct nfattr *cda[]) } static inline int -ctnetlink_change_timeout(struct nf_conn *ct, struct nfattr *cda[]) +ctnetlink_change_timeout(struct nf_conn *ct, struct nlattr *cda[]) { - u_int32_t timeout = ntohl(*(__be32 *)NFA_DATA(cda[CTA_TIMEOUT-1])); + u_int32_t timeout = ntohl(*(__be32 *)nla_data(cda[CTA_TIMEOUT])); if (!del_timer(&ct->timeout)) return -ETIME; @@ -893,15 +916,15 @@ ctnetlink_change_timeout(struct nf_conn *ct, struct nfattr *cda[]) } static inline int -ctnetlink_change_protoinfo(struct nf_conn *ct, struct nfattr *cda[]) +ctnetlink_change_protoinfo(struct nf_conn *ct, struct nlattr *cda[]) { - struct nfattr *tb[CTA_PROTOINFO_MAX], *attr = cda[CTA_PROTOINFO-1]; + struct nlattr *tb[CTA_PROTOINFO_MAX+1], *attr = cda[CTA_PROTOINFO]; struct nf_conntrack_l4proto *l4proto; u_int16_t npt = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum; u_int16_t l3num = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.l3num; int err = 0; - nfattr_parse_nested(tb, CTA_PROTOINFO_MAX, attr); + nla_parse_nested(tb, CTA_PROTOINFO_MAX, attr, NULL); l4proto = nf_ct_l4proto_find_get(l3num, npt); @@ -913,44 +936,44 @@ ctnetlink_change_protoinfo(struct nf_conn *ct, struct nfattr *cda[]) } static int -ctnetlink_change_conntrack(struct nf_conn *ct, struct nfattr *cda[]) +ctnetlink_change_conntrack(struct nf_conn *ct, struct nlattr *cda[]) { int err; - if (cda[CTA_HELP-1]) { + if (cda[CTA_HELP]) { err = ctnetlink_change_helper(ct, cda); if (err < 0) return err; } - if (cda[CTA_TIMEOUT-1]) { + if (cda[CTA_TIMEOUT]) { err = ctnetlink_change_timeout(ct, cda); if (err < 0) return err; } - if (cda[CTA_STATUS-1]) { + if (cda[CTA_STATUS]) { err = ctnetlink_change_status(ct, cda); if (err < 0) return err; } - if (cda[CTA_PROTOINFO-1]) { + if (cda[CTA_PROTOINFO]) { err = ctnetlink_change_protoinfo(ct, cda); if (err < 0) return err; } #if defined(CONFIG_NF_CONNTRACK_MARK) - if (cda[CTA_MARK-1]) - ct->mark = ntohl(*(__be32 *)NFA_DATA(cda[CTA_MARK-1])); + if (cda[CTA_MARK]) + ct->mark = ntohl(*(__be32 *)nla_data(cda[CTA_MARK])); #endif return 0; } static int -ctnetlink_create_conntrack(struct nfattr *cda[], +ctnetlink_create_conntrack(struct nlattr *cda[], struct nf_conntrack_tuple *otuple, struct nf_conntrack_tuple *rtuple) { @@ -963,28 +986,28 @@ ctnetlink_create_conntrack(struct nfattr *cda[], if (ct == NULL || IS_ERR(ct)) return -ENOMEM; - if (!cda[CTA_TIMEOUT-1]) + if (!cda[CTA_TIMEOUT]) goto err; - ct->timeout.expires = ntohl(*(__be32 *)NFA_DATA(cda[CTA_TIMEOUT-1])); + ct->timeout.expires = ntohl(*(__be32 *)nla_data(cda[CTA_TIMEOUT])); ct->timeout.expires = jiffies + ct->timeout.expires * HZ; ct->status |= IPS_CONFIRMED; - if (cda[CTA_STATUS-1]) { + if (cda[CTA_STATUS]) { err = ctnetlink_change_status(ct, cda); if (err < 0) goto err; } - if (cda[CTA_PROTOINFO-1]) { + if (cda[CTA_PROTOINFO]) { err = ctnetlink_change_protoinfo(ct, cda); if (err < 0) goto err; } #if defined(CONFIG_NF_CONNTRACK_MARK) - if (cda[CTA_MARK-1]) - ct->mark = ntohl(*(__be32 *)NFA_DATA(cda[CTA_MARK-1])); + if (cda[CTA_MARK]) + ct->mark = ntohl(*(__be32 *)nla_data(cda[CTA_MARK])); #endif helper = nf_ct_helper_find_get(rtuple); @@ -1014,7 +1037,7 @@ err: static int ctnetlink_new_conntrack(struct sock *ctnl, struct sk_buff *skb, - struct nlmsghdr *nlh, struct nfattr *cda[]) + struct nlmsghdr *nlh, struct nlattr *cda[]) { struct nf_conntrack_tuple otuple, rtuple; struct nf_conntrack_tuple_hash *h = NULL; @@ -1025,22 +1048,22 @@ ctnetlink_new_conntrack(struct sock *ctnl, struct sk_buff *skb, if (nfattr_bad_size(cda, CTA_MAX, cta_min)) return -EINVAL; - if (cda[CTA_TUPLE_ORIG-1]) { + if (cda[CTA_TUPLE_ORIG]) { err = ctnetlink_parse_tuple(cda, &otuple, CTA_TUPLE_ORIG, u3); if (err < 0) return err; } - if (cda[CTA_TUPLE_REPLY-1]) { + if (cda[CTA_TUPLE_REPLY]) { err = ctnetlink_parse_tuple(cda, &rtuple, CTA_TUPLE_REPLY, u3); if (err < 0) return err; } write_lock_bh(&nf_conntrack_lock); - if (cda[CTA_TUPLE_ORIG-1]) + if (cda[CTA_TUPLE_ORIG]) h = __nf_conntrack_find(&otuple, NULL); - else if (cda[CTA_TUPLE_REPLY-1]) + else if (cda[CTA_TUPLE_REPLY]) h = __nf_conntrack_find(&rtuple, NULL); if (h == NULL) { @@ -1057,7 +1080,7 @@ ctnetlink_new_conntrack(struct sock *ctnl, struct sk_buff *skb, err = -EEXIST; if (!(nlh->nlmsg_flags & NLM_F_EXCL)) { /* we only allow nat config for new conntracks */ - if (cda[CTA_NAT_SRC-1] || cda[CTA_NAT_DST-1]) { + if (cda[CTA_NAT_SRC] || cda[CTA_NAT_DST]) { err = -EINVAL; goto out_unlock; } @@ -1079,16 +1102,18 @@ ctnetlink_exp_dump_tuple(struct sk_buff *skb, const struct nf_conntrack_tuple *tuple, enum ctattr_expect type) { - struct nfattr *nest_parms = NFA_NEST(skb, type); + struct nlattr *nest_parms; + nest_parms = nla_nest_start(skb, type | NLA_F_NESTED); + if (!nest_parms) + goto nla_put_failure; if (ctnetlink_dump_tuples(skb, tuple) < 0) - goto nfattr_failure; - - NFA_NEST_END(skb, nest_parms); + goto nla_put_failure; + nla_nest_end(skb, nest_parms); return 0; -nfattr_failure: +nla_put_failure: return -1; } @@ -1101,32 +1126,34 @@ ctnetlink_exp_dump_mask(struct sk_buff *skb, struct nf_conntrack_l3proto *l3proto; struct nf_conntrack_l4proto *l4proto; struct nf_conntrack_tuple m; - struct nfattr *nest_parms; + struct nlattr *nest_parms; memset(&m, 0xFF, sizeof(m)); m.src.u.all = mask->src.u.all; memcpy(&m.src.u3, &mask->src.u3, sizeof(m.src.u3)); - nest_parms = NFA_NEST(skb, CTA_EXPECT_MASK); + nest_parms = nla_nest_start(skb, CTA_EXPECT_MASK | NLA_F_NESTED); + if (!nest_parms) + goto nla_put_failure; l3proto = nf_ct_l3proto_find_get(tuple->src.l3num); ret = ctnetlink_dump_tuples_ip(skb, &m, l3proto); nf_ct_l3proto_put(l3proto); if (unlikely(ret < 0)) - goto nfattr_failure; + goto nla_put_failure; l4proto = nf_ct_l4proto_find_get(tuple->src.l3num, tuple->dst.protonum); ret = ctnetlink_dump_tuples_proto(skb, &m, l4proto); nf_ct_l4proto_put(l4proto); if (unlikely(ret < 0)) - goto nfattr_failure; + goto nla_put_failure; - NFA_NEST_END(skb, nest_parms); + nla_nest_end(skb, nest_parms); return 0; -nfattr_failure: +nla_put_failure: return -1; } @@ -1139,20 +1166,20 @@ ctnetlink_exp_dump_expect(struct sk_buff *skb, __be32 id = htonl(exp->id); if (ctnetlink_exp_dump_tuple(skb, &exp->tuple, CTA_EXPECT_TUPLE) < 0) - goto nfattr_failure; + goto nla_put_failure; if (ctnetlink_exp_dump_mask(skb, &exp->tuple, &exp->mask) < 0) - goto nfattr_failure; + goto nla_put_failure; if (ctnetlink_exp_dump_tuple(skb, &master->tuplehash[IP_CT_DIR_ORIGINAL].tuple, CTA_EXPECT_MASTER) < 0) - goto nfattr_failure; + goto nla_put_failure; - NFA_PUT(skb, CTA_EXPECT_TIMEOUT, sizeof(timeout), &timeout); - NFA_PUT(skb, CTA_EXPECT_ID, sizeof(u_int32_t), &id); + NLA_PUT(skb, CTA_EXPECT_TIMEOUT, sizeof(timeout), &timeout); + NLA_PUT(skb, CTA_EXPECT_ID, sizeof(u_int32_t), &id); return 0; -nfattr_failure: +nla_put_failure: return -1; } @@ -1176,13 +1203,13 @@ ctnetlink_exp_fill_info(struct sk_buff *skb, u32 pid, u32 seq, nfmsg->res_id = 0; if (ctnetlink_exp_dump_expect(skb, exp) < 0) - goto nfattr_failure; + goto nla_put_failure; nlh->nlmsg_len = skb_tail_pointer(skb) - b; return skb->len; nlmsg_failure: -nfattr_failure: +nla_put_failure: nlmsg_trim(skb, b); return -1; } @@ -1224,14 +1251,14 @@ static int ctnetlink_expect_event(struct notifier_block *this, nfmsg->res_id = 0; if (ctnetlink_exp_dump_expect(skb, exp) < 0) - goto nfattr_failure; + goto nla_put_failure; nlh->nlmsg_len = skb->tail - b; nfnetlink_send(skb, 0, NFNLGRP_CONNTRACK_EXP_NEW, 0); return NOTIFY_DONE; nlmsg_failure: -nfattr_failure: +nla_put_failure: kfree_skb(skb); return NOTIFY_DONE; } @@ -1286,14 +1313,14 @@ out: return skb->len; } -static const size_t cta_min_exp[CTA_EXPECT_MAX] = { - [CTA_EXPECT_TIMEOUT-1] = sizeof(u_int32_t), - [CTA_EXPECT_ID-1] = sizeof(u_int32_t) +static const size_t cta_min_exp[CTA_EXPECT_MAX+1] = { + [CTA_EXPECT_TIMEOUT] = sizeof(u_int32_t), + [CTA_EXPECT_ID] = sizeof(u_int32_t) }; static int ctnetlink_get_expect(struct sock *ctnl, struct sk_buff *skb, - struct nlmsghdr *nlh, struct nfattr *cda[]) + struct nlmsghdr *nlh, struct nlattr *cda[]) { struct nf_conntrack_tuple tuple; struct nf_conntrack_expect *exp; @@ -1311,7 +1338,7 @@ ctnetlink_get_expect(struct sock *ctnl, struct sk_buff *skb, ctnetlink_exp_done); } - if (cda[CTA_EXPECT_MASTER-1]) + if (cda[CTA_EXPECT_MASTER]) err = ctnetlink_parse_tuple(cda, &tuple, CTA_EXPECT_MASTER, u3); else return -EINVAL; @@ -1323,8 +1350,8 @@ ctnetlink_get_expect(struct sock *ctnl, struct sk_buff *skb, if (!exp) return -ENOENT; - if (cda[CTA_EXPECT_ID-1]) { - __be32 id = *(__be32 *)NFA_DATA(cda[CTA_EXPECT_ID-1]); + if (cda[CTA_EXPECT_ID]) { + __be32 id = *(__be32 *)nla_data(cda[CTA_EXPECT_ID]); if (exp->id != ntohl(id)) { nf_ct_expect_put(exp); return -ENOENT; @@ -1355,7 +1382,7 @@ out: static int ctnetlink_del_expect(struct sock *ctnl, struct sk_buff *skb, - struct nlmsghdr *nlh, struct nfattr *cda[]) + struct nlmsghdr *nlh, struct nlattr *cda[]) { struct nf_conntrack_expect *exp; struct nf_conntrack_tuple tuple; @@ -1369,7 +1396,7 @@ ctnetlink_del_expect(struct sock *ctnl, struct sk_buff *skb, if (nfattr_bad_size(cda, CTA_EXPECT_MAX, cta_min_exp)) return -EINVAL; - if (cda[CTA_EXPECT_TUPLE-1]) { + if (cda[CTA_EXPECT_TUPLE]) { /* delete a single expect by tuple */ err = ctnetlink_parse_tuple(cda, &tuple, CTA_EXPECT_TUPLE, u3); if (err < 0) @@ -1380,8 +1407,8 @@ ctnetlink_del_expect(struct sock *ctnl, struct sk_buff *skb, if (!exp) return -ENOENT; - if (cda[CTA_EXPECT_ID-1]) { - __be32 id = *(__be32 *)NFA_DATA(cda[CTA_EXPECT_ID-1]); + if (cda[CTA_EXPECT_ID]) { + __be32 id = *(__be32 *)nla_data(cda[CTA_EXPECT_ID]); if (exp->id != ntohl(id)) { nf_ct_expect_put(exp); return -ENOENT; @@ -1393,8 +1420,8 @@ ctnetlink_del_expect(struct sock *ctnl, struct sk_buff *skb, /* have to put what we 'get' above. * after this line usage count == 0 */ nf_ct_expect_put(exp); - } else if (cda[CTA_EXPECT_HELP_NAME-1]) { - char *name = NFA_DATA(cda[CTA_EXPECT_HELP_NAME-1]); + } else if (cda[CTA_EXPECT_HELP_NAME]) { + char *name = nla_data(cda[CTA_EXPECT_HELP_NAME]); struct nf_conn_help *m_help; /* delete all expectations for this helper */ @@ -1436,13 +1463,13 @@ ctnetlink_del_expect(struct sock *ctnl, struct sk_buff *skb, return 0; } static int -ctnetlink_change_expect(struct nf_conntrack_expect *x, struct nfattr *cda[]) +ctnetlink_change_expect(struct nf_conntrack_expect *x, struct nlattr *cda[]) { return -EOPNOTSUPP; } static int -ctnetlink_create_expect(struct nfattr *cda[], u_int8_t u3) +ctnetlink_create_expect(struct nlattr *cda[], u_int8_t u3) { struct nf_conntrack_tuple tuple, mask, master_tuple; struct nf_conntrack_tuple_hash *h = NULL; @@ -1499,7 +1526,7 @@ out: static int ctnetlink_new_expect(struct sock *ctnl, struct sk_buff *skb, - struct nlmsghdr *nlh, struct nfattr *cda[]) + struct nlmsghdr *nlh, struct nlattr *cda[]) { struct nf_conntrack_tuple tuple; struct nf_conntrack_expect *exp; @@ -1510,9 +1537,9 @@ ctnetlink_new_expect(struct sock *ctnl, struct sk_buff *skb, if (nfattr_bad_size(cda, CTA_EXPECT_MAX, cta_min_exp)) return -EINVAL; - if (!cda[CTA_EXPECT_TUPLE-1] - || !cda[CTA_EXPECT_MASK-1] - || !cda[CTA_EXPECT_MASTER-1]) + if (!cda[CTA_EXPECT_TUPLE] + || !cda[CTA_EXPECT_MASK] + || !cda[CTA_EXPECT_MASTER]) return -EINVAL; err = ctnetlink_parse_tuple(cda, &tuple, CTA_EXPECT_TUPLE, u3); diff --git a/net/netfilter/nf_conntrack_proto_tcp.c b/net/netfilter/nf_conntrack_proto_tcp.c index eb3fe7401466..1d167e61cc44 100644 --- a/net/netfilter/nf_conntrack_proto_tcp.c +++ b/net/netfilter/nf_conntrack_proto_tcp.c @@ -1067,93 +1067,96 @@ static int tcp_new(struct nf_conn *conntrack, #include #include -static int tcp_to_nfattr(struct sk_buff *skb, struct nfattr *nfa, +static int tcp_to_nfattr(struct sk_buff *skb, struct nlattr *nla, const struct nf_conn *ct) { - struct nfattr *nest_parms; + struct nlattr *nest_parms; struct nf_ct_tcp_flags tmp = {}; read_lock_bh(&tcp_lock); - nest_parms = NFA_NEST(skb, CTA_PROTOINFO_TCP); - NFA_PUT(skb, CTA_PROTOINFO_TCP_STATE, sizeof(u_int8_t), + nest_parms = nla_nest_start(skb, CTA_PROTOINFO_TCP | NLA_F_NESTED); + if (!nest_parms) + goto nla_put_failure; + + NLA_PUT(skb, CTA_PROTOINFO_TCP_STATE, sizeof(u_int8_t), &ct->proto.tcp.state); - NFA_PUT(skb, CTA_PROTOINFO_TCP_WSCALE_ORIGINAL, sizeof(u_int8_t), + NLA_PUT(skb, CTA_PROTOINFO_TCP_WSCALE_ORIGINAL, sizeof(u_int8_t), &ct->proto.tcp.seen[0].td_scale); - NFA_PUT(skb, CTA_PROTOINFO_TCP_WSCALE_REPLY, sizeof(u_int8_t), + NLA_PUT(skb, CTA_PROTOINFO_TCP_WSCALE_REPLY, sizeof(u_int8_t), &ct->proto.tcp.seen[1].td_scale); tmp.flags = ct->proto.tcp.seen[0].flags; - NFA_PUT(skb, CTA_PROTOINFO_TCP_FLAGS_ORIGINAL, + NLA_PUT(skb, CTA_PROTOINFO_TCP_FLAGS_ORIGINAL, sizeof(struct nf_ct_tcp_flags), &tmp); tmp.flags = ct->proto.tcp.seen[1].flags; - NFA_PUT(skb, CTA_PROTOINFO_TCP_FLAGS_REPLY, + NLA_PUT(skb, CTA_PROTOINFO_TCP_FLAGS_REPLY, sizeof(struct nf_ct_tcp_flags), &tmp); read_unlock_bh(&tcp_lock); - NFA_NEST_END(skb, nest_parms); + nla_nest_end(skb, nest_parms); return 0; -nfattr_failure: +nla_put_failure: read_unlock_bh(&tcp_lock); return -1; } -static const size_t cta_min_tcp[CTA_PROTOINFO_TCP_MAX] = { - [CTA_PROTOINFO_TCP_STATE-1] = sizeof(u_int8_t), - [CTA_PROTOINFO_TCP_WSCALE_ORIGINAL-1] = sizeof(u_int8_t), - [CTA_PROTOINFO_TCP_WSCALE_REPLY-1] = sizeof(u_int8_t), - [CTA_PROTOINFO_TCP_FLAGS_ORIGINAL-1] = sizeof(struct nf_ct_tcp_flags), - [CTA_PROTOINFO_TCP_FLAGS_REPLY-1] = sizeof(struct nf_ct_tcp_flags) +static const size_t cta_min_tcp[CTA_PROTOINFO_TCP_MAX+1] = { + [CTA_PROTOINFO_TCP_STATE] = sizeof(u_int8_t), + [CTA_PROTOINFO_TCP_WSCALE_ORIGINAL] = sizeof(u_int8_t), + [CTA_PROTOINFO_TCP_WSCALE_REPLY] = sizeof(u_int8_t), + [CTA_PROTOINFO_TCP_FLAGS_ORIGINAL] = sizeof(struct nf_ct_tcp_flags), + [CTA_PROTOINFO_TCP_FLAGS_REPLY] = sizeof(struct nf_ct_tcp_flags) }; -static int nfattr_to_tcp(struct nfattr *cda[], struct nf_conn *ct) +static int nfattr_to_tcp(struct nlattr *cda[], struct nf_conn *ct) { - struct nfattr *attr = cda[CTA_PROTOINFO_TCP-1]; - struct nfattr *tb[CTA_PROTOINFO_TCP_MAX]; + struct nlattr *attr = cda[CTA_PROTOINFO_TCP]; + struct nlattr *tb[CTA_PROTOINFO_TCP_MAX+1]; /* updates could not contain anything about the private * protocol info, in that case skip the parsing */ if (!attr) return 0; - nfattr_parse_nested(tb, CTA_PROTOINFO_TCP_MAX, attr); + nla_parse_nested(tb, CTA_PROTOINFO_TCP_MAX, attr, NULL); if (nfattr_bad_size(tb, CTA_PROTOINFO_TCP_MAX, cta_min_tcp)) return -EINVAL; - if (!tb[CTA_PROTOINFO_TCP_STATE-1]) + if (!tb[CTA_PROTOINFO_TCP_STATE]) return -EINVAL; write_lock_bh(&tcp_lock); ct->proto.tcp.state = - *(u_int8_t *)NFA_DATA(tb[CTA_PROTOINFO_TCP_STATE-1]); + *(u_int8_t *)nla_data(tb[CTA_PROTOINFO_TCP_STATE]); - if (tb[CTA_PROTOINFO_TCP_FLAGS_ORIGINAL-1]) { + if (tb[CTA_PROTOINFO_TCP_FLAGS_ORIGINAL]) { struct nf_ct_tcp_flags *attr = - NFA_DATA(tb[CTA_PROTOINFO_TCP_FLAGS_ORIGINAL-1]); + nla_data(tb[CTA_PROTOINFO_TCP_FLAGS_ORIGINAL]); ct->proto.tcp.seen[0].flags &= ~attr->mask; ct->proto.tcp.seen[0].flags |= attr->flags & attr->mask; } - if (tb[CTA_PROTOINFO_TCP_FLAGS_REPLY-1]) { + if (tb[CTA_PROTOINFO_TCP_FLAGS_REPLY]) { struct nf_ct_tcp_flags *attr = - NFA_DATA(tb[CTA_PROTOINFO_TCP_FLAGS_REPLY-1]); + nla_data(tb[CTA_PROTOINFO_TCP_FLAGS_REPLY]); ct->proto.tcp.seen[1].flags &= ~attr->mask; ct->proto.tcp.seen[1].flags |= attr->flags & attr->mask; } - if (tb[CTA_PROTOINFO_TCP_WSCALE_ORIGINAL-1] && - tb[CTA_PROTOINFO_TCP_WSCALE_REPLY-1] && + if (tb[CTA_PROTOINFO_TCP_WSCALE_ORIGINAL] && + tb[CTA_PROTOINFO_TCP_WSCALE_REPLY] && ct->proto.tcp.seen[0].flags & IP_CT_TCP_FLAG_WINDOW_SCALE && ct->proto.tcp.seen[1].flags & IP_CT_TCP_FLAG_WINDOW_SCALE) { ct->proto.tcp.seen[0].td_scale = *(u_int8_t *) - NFA_DATA(tb[CTA_PROTOINFO_TCP_WSCALE_ORIGINAL-1]); + nla_data(tb[CTA_PROTOINFO_TCP_WSCALE_ORIGINAL]); ct->proto.tcp.seen[1].td_scale = *(u_int8_t *) - NFA_DATA(tb[CTA_PROTOINFO_TCP_WSCALE_REPLY-1]); + nla_data(tb[CTA_PROTOINFO_TCP_WSCALE_REPLY]); } write_unlock_bh(&tcp_lock); diff --git a/net/netfilter/nfnetlink.c b/net/netfilter/nfnetlink.c index 032224c1409f..3cfa76b89a20 100644 --- a/net/netfilter/nfnetlink.c +++ b/net/netfilter/nfnetlink.c @@ -111,44 +111,17 @@ nfnetlink_find_client(u_int16_t type, const struct nfnetlink_subsystem *ss) return &ss->cb[cb_id]; } -void __nfa_fill(struct sk_buff *skb, int attrtype, int attrlen, - const void *data) -{ - struct nfattr *nfa; - int size = NFA_LENGTH(attrlen); - - nfa = (struct nfattr *)skb_put(skb, NFA_ALIGN(size)); - nfa->nfa_type = attrtype; - nfa->nfa_len = size; - memcpy(NFA_DATA(nfa), data, attrlen); - memset(NFA_DATA(nfa) + attrlen, 0, NFA_ALIGN(size) - size); -} -EXPORT_SYMBOL_GPL(__nfa_fill); - -void nfattr_parse(struct nfattr *tb[], int maxattr, struct nfattr *nfa, int len) -{ - memset(tb, 0, sizeof(struct nfattr *) * maxattr); - - while (NFA_OK(nfa, len)) { - unsigned flavor = NFA_TYPE(nfa); - if (flavor && flavor <= maxattr) - tb[flavor-1] = nfa; - nfa = NFA_NEXT(nfa, len); - } -} -EXPORT_SYMBOL_GPL(nfattr_parse); - /** * nfnetlink_check_attributes - check and parse nfnetlink attributes * * subsys: nfnl subsystem for which this message is to be parsed * nlmsghdr: netlink message to be checked/parsed - * cda: array of pointers, needs to be at least subsys->attr_count big + * cda: array of pointers, needs to be at least subsys->attr_count+1 big * */ static int nfnetlink_check_attributes(const struct nfnetlink_subsystem *subsys, - struct nlmsghdr *nlh, struct nfattr *cda[]) + struct nlmsghdr *nlh, struct nlattr *cda[]) { int min_len = NLMSG_SPACE(sizeof(struct nfgenmsg)); u_int8_t cb_id = NFNL_MSG_TYPE(nlh->nlmsg_type); @@ -156,9 +129,9 @@ nfnetlink_check_attributes(const struct nfnetlink_subsystem *subsys, /* check attribute lengths. */ if (likely(nlh->nlmsg_len > min_len)) { - struct nfattr *attr = NFM_NFA(NLMSG_DATA(nlh)); + struct nlattr *attr = (void *)nlh + NLMSG_ALIGN(min_len); int attrlen = nlh->nlmsg_len - NLMSG_ALIGN(min_len); - nfattr_parse(cda, attr_count, attr, attrlen); + nla_parse(cda, attr_count, attr, attrlen, NULL); } /* implicit: if nlmsg_len == min_len, we return 0, and an empty @@ -230,9 +203,9 @@ static int nfnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) { u_int16_t attr_count = ss->cb[NFNL_MSG_TYPE(nlh->nlmsg_type)].attr_count; - struct nfattr *cda[attr_count]; + struct nlattr *cda[attr_count+1]; - memset(cda, 0, sizeof(struct nfattr *) * attr_count); + memset(cda, 0, sizeof(struct nlattr *) * attr_count); err = nfnetlink_check_attributes(ss, nlh, cda); if (err < 0) diff --git a/net/netfilter/nfnetlink_log.c b/net/netfilter/nfnetlink_log.c index c3aa8918035f..c7fd82f6cb7d 100644 --- a/net/netfilter/nfnetlink_log.c +++ b/net/netfilter/nfnetlink_log.c @@ -244,7 +244,7 @@ nfulnl_set_mode(struct nfulnl_instance *inst, u_int8_t mode, case NFULNL_COPY_PACKET: inst->copy_mode = mode; - /* we're using struct nfattr which has 16bit nfa_len */ + /* we're using struct nlattr which has 16bit nfa_len */ if (range > 0xffff) inst->copy_range = 0xffff; else @@ -409,36 +409,36 @@ __build_packet_message(struct nfulnl_instance *inst, pmsg.hw_protocol = skb->protocol; pmsg.hook = hooknum; - NFA_PUT(inst->skb, NFULA_PACKET_HDR, sizeof(pmsg), &pmsg); + NLA_PUT(inst->skb, NFULA_PACKET_HDR, sizeof(pmsg), &pmsg); if (prefix) - NFA_PUT(inst->skb, NFULA_PREFIX, plen, prefix); + NLA_PUT(inst->skb, NFULA_PREFIX, plen, prefix); if (indev) { tmp_uint = htonl(indev->ifindex); #ifndef CONFIG_BRIDGE_NETFILTER - NFA_PUT(inst->skb, NFULA_IFINDEX_INDEV, sizeof(tmp_uint), + NLA_PUT(inst->skb, NFULA_IFINDEX_INDEV, sizeof(tmp_uint), &tmp_uint); #else if (pf == PF_BRIDGE) { /* Case 1: outdev is physical input device, we need to * look for bridge group (when called from * netfilter_bridge) */ - NFA_PUT(inst->skb, NFULA_IFINDEX_PHYSINDEV, + NLA_PUT(inst->skb, NFULA_IFINDEX_PHYSINDEV, sizeof(tmp_uint), &tmp_uint); /* this is the bridge group "brX" */ tmp_uint = htonl(indev->br_port->br->dev->ifindex); - NFA_PUT(inst->skb, NFULA_IFINDEX_INDEV, + NLA_PUT(inst->skb, NFULA_IFINDEX_INDEV, sizeof(tmp_uint), &tmp_uint); } else { /* Case 2: indev is bridge group, we need to look for * physical device (when called from ipv4) */ - NFA_PUT(inst->skb, NFULA_IFINDEX_INDEV, + NLA_PUT(inst->skb, NFULA_IFINDEX_INDEV, sizeof(tmp_uint), &tmp_uint); if (skb->nf_bridge && skb->nf_bridge->physindev) { tmp_uint = htonl(skb->nf_bridge->physindev->ifindex); - NFA_PUT(inst->skb, NFULA_IFINDEX_PHYSINDEV, + NLA_PUT(inst->skb, NFULA_IFINDEX_PHYSINDEV, sizeof(tmp_uint), &tmp_uint); } } @@ -448,28 +448,28 @@ __build_packet_message(struct nfulnl_instance *inst, if (outdev) { tmp_uint = htonl(outdev->ifindex); #ifndef CONFIG_BRIDGE_NETFILTER - NFA_PUT(inst->skb, NFULA_IFINDEX_OUTDEV, sizeof(tmp_uint), + NLA_PUT(inst->skb, NFULA_IFINDEX_OUTDEV, sizeof(tmp_uint), &tmp_uint); #else if (pf == PF_BRIDGE) { /* Case 1: outdev is physical output device, we need to * look for bridge group (when called from * netfilter_bridge) */ - NFA_PUT(inst->skb, NFULA_IFINDEX_PHYSOUTDEV, + NLA_PUT(inst->skb, NFULA_IFINDEX_PHYSOUTDEV, sizeof(tmp_uint), &tmp_uint); /* this is the bridge group "brX" */ tmp_uint = htonl(outdev->br_port->br->dev->ifindex); - NFA_PUT(inst->skb, NFULA_IFINDEX_OUTDEV, + NLA_PUT(inst->skb, NFULA_IFINDEX_OUTDEV, sizeof(tmp_uint), &tmp_uint); } else { /* Case 2: indev is a bridge group, we need to look * for physical device (when called from ipv4) */ - NFA_PUT(inst->skb, NFULA_IFINDEX_OUTDEV, + NLA_PUT(inst->skb, NFULA_IFINDEX_OUTDEV, sizeof(tmp_uint), &tmp_uint); if (skb->nf_bridge && skb->nf_bridge->physoutdev) { tmp_uint = htonl(skb->nf_bridge->physoutdev->ifindex); - NFA_PUT(inst->skb, NFULA_IFINDEX_PHYSOUTDEV, + NLA_PUT(inst->skb, NFULA_IFINDEX_PHYSOUTDEV, sizeof(tmp_uint), &tmp_uint); } } @@ -478,7 +478,7 @@ __build_packet_message(struct nfulnl_instance *inst, if (skb->mark) { tmp_uint = htonl(skb->mark); - NFA_PUT(inst->skb, NFULA_MARK, sizeof(tmp_uint), &tmp_uint); + NLA_PUT(inst->skb, NFULA_MARK, sizeof(tmp_uint), &tmp_uint); } if (indev && skb->dev) { @@ -486,7 +486,7 @@ __build_packet_message(struct nfulnl_instance *inst, int len = dev_parse_header(skb, phw.hw_addr); if (len > 0) { phw.hw_addrlen = htons(len); - NFA_PUT(inst->skb, NFULA_HWADDR, sizeof(phw), &phw); + NLA_PUT(inst->skb, NFULA_HWADDR, sizeof(phw), &phw); } } @@ -496,7 +496,7 @@ __build_packet_message(struct nfulnl_instance *inst, ts.sec = cpu_to_be64(tv.tv_sec); ts.usec = cpu_to_be64(tv.tv_usec); - NFA_PUT(inst->skb, NFULA_TIMESTAMP, sizeof(ts), &ts); + NLA_PUT(inst->skb, NFULA_TIMESTAMP, sizeof(ts), &ts); } /* UID */ @@ -504,9 +504,9 @@ __build_packet_message(struct nfulnl_instance *inst, read_lock_bh(&skb->sk->sk_callback_lock); if (skb->sk->sk_socket && skb->sk->sk_socket->file) { __be32 uid = htonl(skb->sk->sk_socket->file->f_uid); - /* need to unlock here since NFA_PUT may goto */ + /* need to unlock here since NLA_PUT may goto */ read_unlock_bh(&skb->sk->sk_callback_lock); - NFA_PUT(inst->skb, NFULA_UID, sizeof(uid), &uid); + NLA_PUT(inst->skb, NFULA_UID, sizeof(uid), &uid); } else read_unlock_bh(&skb->sk->sk_callback_lock); } @@ -514,28 +514,28 @@ __build_packet_message(struct nfulnl_instance *inst, /* local sequence number */ if (inst->flags & NFULNL_CFG_F_SEQ) { tmp_uint = htonl(inst->seq++); - NFA_PUT(inst->skb, NFULA_SEQ, sizeof(tmp_uint), &tmp_uint); + NLA_PUT(inst->skb, NFULA_SEQ, sizeof(tmp_uint), &tmp_uint); } /* global sequence number */ if (inst->flags & NFULNL_CFG_F_SEQ_GLOBAL) { tmp_uint = htonl(atomic_inc_return(&global_seq)); - NFA_PUT(inst->skb, NFULA_SEQ_GLOBAL, sizeof(tmp_uint), &tmp_uint); + NLA_PUT(inst->skb, NFULA_SEQ_GLOBAL, sizeof(tmp_uint), &tmp_uint); } if (data_len) { - struct nfattr *nfa; - int size = NFA_LENGTH(data_len); + struct nlattr *nla; + int size = nla_attr_size(data_len); - if (skb_tailroom(inst->skb) < (int)NFA_SPACE(data_len)) { + if (skb_tailroom(inst->skb) < nla_total_size(data_len)) { printk(KERN_WARNING "nfnetlink_log: no tailroom!\n"); goto nlmsg_failure; } - nfa = (struct nfattr *)skb_put(inst->skb, NFA_ALIGN(size)); - nfa->nfa_type = NFULA_PAYLOAD; - nfa->nfa_len = size; + nla = (struct nlattr *)skb_put(inst->skb, nla_total_size(data_len)); + nla->nla_type = NFULA_PAYLOAD; + nla->nla_len = size; - if (skb_copy_bits(skb, 0, NFA_DATA(nfa), data_len)) + if (skb_copy_bits(skb, 0, nla_data(nla), data_len)) BUG(); } @@ -544,7 +544,7 @@ __build_packet_message(struct nfulnl_instance *inst, nlmsg_failure: UDEBUG("nlmsg_failure\n"); -nfattr_failure: +nla_put_failure: PRINTR(KERN_ERR "nfnetlink_log: error creating log nlmsg\n"); return -1; } @@ -591,32 +591,31 @@ nfulnl_log_packet(unsigned int pf, if (prefix) plen = strlen(prefix) + 1; - /* all macros expand to constant values at compile time */ /* FIXME: do we want to make the size calculation conditional based on * what is actually present? way more branches and checks, but more * memory efficient... */ - size = NLMSG_SPACE(sizeof(struct nfgenmsg)) - + NFA_SPACE(sizeof(struct nfulnl_msg_packet_hdr)) - + NFA_SPACE(sizeof(u_int32_t)) /* ifindex */ - + NFA_SPACE(sizeof(u_int32_t)) /* ifindex */ + size = NLMSG_ALIGN(sizeof(struct nfgenmsg)) + + nla_total_size(sizeof(struct nfulnl_msg_packet_hdr)) + + nla_total_size(sizeof(u_int32_t)) /* ifindex */ + + nla_total_size(sizeof(u_int32_t)) /* ifindex */ #ifdef CONFIG_BRIDGE_NETFILTER - + NFA_SPACE(sizeof(u_int32_t)) /* ifindex */ - + NFA_SPACE(sizeof(u_int32_t)) /* ifindex */ + + nla_total_size(sizeof(u_int32_t)) /* ifindex */ + + nla_total_size(sizeof(u_int32_t)) /* ifindex */ #endif - + NFA_SPACE(sizeof(u_int32_t)) /* mark */ - + NFA_SPACE(sizeof(u_int32_t)) /* uid */ - + NFA_SPACE(plen) /* prefix */ - + NFA_SPACE(sizeof(struct nfulnl_msg_packet_hw)) - + NFA_SPACE(sizeof(struct nfulnl_msg_packet_timestamp)); + + nla_total_size(sizeof(u_int32_t)) /* mark */ + + nla_total_size(sizeof(u_int32_t)) /* uid */ + + nla_total_size(plen) /* prefix */ + + nla_total_size(sizeof(struct nfulnl_msg_packet_hw)) + + nla_total_size(sizeof(struct nfulnl_msg_packet_timestamp)); UDEBUG("initial size=%u\n", size); spin_lock_bh(&inst->lock); if (inst->flags & NFULNL_CFG_F_SEQ) - size += NFA_SPACE(sizeof(u_int32_t)); + size += nla_total_size(sizeof(u_int32_t)); if (inst->flags & NFULNL_CFG_F_SEQ_GLOBAL) - size += NFA_SPACE(sizeof(u_int32_t)); + size += nla_total_size(sizeof(u_int32_t)); qthreshold = inst->qthreshold; /* per-rule qthreshold overrides per-instance */ @@ -636,7 +635,7 @@ nfulnl_log_packet(unsigned int pf, else data_len = inst->copy_range; - size += NFA_SPACE(data_len); + size += nla_total_size(data_len); UDEBUG("copy_packet, therefore size now %u\n", size); break; @@ -723,7 +722,7 @@ static struct notifier_block nfulnl_rtnl_notifier = { static int nfulnl_recv_unsupp(struct sock *ctnl, struct sk_buff *skb, - struct nlmsghdr *nlh, struct nfattr *nfqa[]) + struct nlmsghdr *nlh, struct nlattr *nfqa[]) { return -ENOTSUPP; } @@ -734,34 +733,34 @@ static struct nf_logger nfulnl_logger = { .me = THIS_MODULE, }; -static const int nfula_min[NFULA_MAX] = { - [NFULA_PACKET_HDR-1] = sizeof(struct nfulnl_msg_packet_hdr), - [NFULA_MARK-1] = sizeof(u_int32_t), - [NFULA_TIMESTAMP-1] = sizeof(struct nfulnl_msg_packet_timestamp), - [NFULA_IFINDEX_INDEV-1] = sizeof(u_int32_t), - [NFULA_IFINDEX_OUTDEV-1]= sizeof(u_int32_t), - [NFULA_IFINDEX_PHYSINDEV-1] = sizeof(u_int32_t), - [NFULA_IFINDEX_PHYSOUTDEV-1] = sizeof(u_int32_t), - [NFULA_HWADDR-1] = sizeof(struct nfulnl_msg_packet_hw), - [NFULA_PAYLOAD-1] = 0, - [NFULA_PREFIX-1] = 0, - [NFULA_UID-1] = sizeof(u_int32_t), - [NFULA_SEQ-1] = sizeof(u_int32_t), - [NFULA_SEQ_GLOBAL-1] = sizeof(u_int32_t), +static const int nfula_min[NFULA_MAX+1] = { + [NFULA_PACKET_HDR] = sizeof(struct nfulnl_msg_packet_hdr), + [NFULA_MARK] = sizeof(u_int32_t), + [NFULA_TIMESTAMP] = sizeof(struct nfulnl_msg_packet_timestamp), + [NFULA_IFINDEX_INDEV] = sizeof(u_int32_t), + [NFULA_IFINDEX_OUTDEV] = sizeof(u_int32_t), + [NFULA_IFINDEX_PHYSINDEV] = sizeof(u_int32_t), + [NFULA_IFINDEX_PHYSOUTDEV] = sizeof(u_int32_t), + [NFULA_HWADDR] = sizeof(struct nfulnl_msg_packet_hw), + [NFULA_PAYLOAD] = 0, + [NFULA_PREFIX] = 0, + [NFULA_UID] = sizeof(u_int32_t), + [NFULA_SEQ] = sizeof(u_int32_t), + [NFULA_SEQ_GLOBAL] = sizeof(u_int32_t), }; -static const int nfula_cfg_min[NFULA_CFG_MAX] = { - [NFULA_CFG_CMD-1] = sizeof(struct nfulnl_msg_config_cmd), - [NFULA_CFG_MODE-1] = sizeof(struct nfulnl_msg_config_mode), - [NFULA_CFG_TIMEOUT-1] = sizeof(u_int32_t), - [NFULA_CFG_QTHRESH-1] = sizeof(u_int32_t), - [NFULA_CFG_NLBUFSIZ-1] = sizeof(u_int32_t), - [NFULA_CFG_FLAGS-1] = sizeof(u_int16_t), +static const int nfula_cfg_min[NFULA_CFG_MAX+1] = { + [NFULA_CFG_CMD] = sizeof(struct nfulnl_msg_config_cmd), + [NFULA_CFG_MODE] = sizeof(struct nfulnl_msg_config_mode), + [NFULA_CFG_TIMEOUT] = sizeof(u_int32_t), + [NFULA_CFG_QTHRESH] = sizeof(u_int32_t), + [NFULA_CFG_NLBUFSIZ] = sizeof(u_int32_t), + [NFULA_CFG_FLAGS] = sizeof(u_int16_t), }; static int nfulnl_recv_config(struct sock *ctnl, struct sk_buff *skb, - struct nlmsghdr *nlh, struct nfattr *nfula[]) + struct nlmsghdr *nlh, struct nlattr *nfula[]) { struct nfgenmsg *nfmsg = NLMSG_DATA(nlh); u_int16_t group_num = ntohs(nfmsg->res_id); @@ -776,10 +775,10 @@ nfulnl_recv_config(struct sock *ctnl, struct sk_buff *skb, } inst = instance_lookup_get(group_num); - if (nfula[NFULA_CFG_CMD-1]) { + if (nfula[NFULA_CFG_CMD]) { u_int8_t pf = nfmsg->nfgen_family; struct nfulnl_msg_config_cmd *cmd; - cmd = NFA_DATA(nfula[NFULA_CFG_CMD-1]); + cmd = nla_data(nfula[NFULA_CFG_CMD]); UDEBUG("found CFG_CMD for\n"); switch (cmd->command) { @@ -842,38 +841,38 @@ nfulnl_recv_config(struct sock *ctnl, struct sk_buff *skb, } } - if (nfula[NFULA_CFG_MODE-1]) { + if (nfula[NFULA_CFG_MODE]) { struct nfulnl_msg_config_mode *params; - params = NFA_DATA(nfula[NFULA_CFG_MODE-1]); + params = nla_data(nfula[NFULA_CFG_MODE]); nfulnl_set_mode(inst, params->copy_mode, ntohl(params->copy_range)); } - if (nfula[NFULA_CFG_TIMEOUT-1]) { + if (nfula[NFULA_CFG_TIMEOUT]) { __be32 timeout = - *(__be32 *)NFA_DATA(nfula[NFULA_CFG_TIMEOUT-1]); + *(__be32 *)nla_data(nfula[NFULA_CFG_TIMEOUT]); nfulnl_set_timeout(inst, ntohl(timeout)); } - if (nfula[NFULA_CFG_NLBUFSIZ-1]) { + if (nfula[NFULA_CFG_NLBUFSIZ]) { __be32 nlbufsiz = - *(__be32 *)NFA_DATA(nfula[NFULA_CFG_NLBUFSIZ-1]); + *(__be32 *)nla_data(nfula[NFULA_CFG_NLBUFSIZ]); nfulnl_set_nlbufsiz(inst, ntohl(nlbufsiz)); } - if (nfula[NFULA_CFG_QTHRESH-1]) { + if (nfula[NFULA_CFG_QTHRESH]) { __be32 qthresh = - *(__be32 *)NFA_DATA(nfula[NFULA_CFG_QTHRESH-1]); + *(__be32 *)nla_data(nfula[NFULA_CFG_QTHRESH]); nfulnl_set_qthresh(inst, ntohl(qthresh)); } - if (nfula[NFULA_CFG_FLAGS-1]) { + if (nfula[NFULA_CFG_FLAGS]) { __be16 flags = - *(__be16 *)NFA_DATA(nfula[NFULA_CFG_FLAGS-1]); + *(__be16 *)nla_data(nfula[NFULA_CFG_FLAGS]); nfulnl_set_flags(inst, ntohs(flags)); } diff --git a/net/netfilter/nfnetlink_queue.c b/net/netfilter/nfnetlink_queue.c index bfcc0563bfd4..068e88b46ba0 100644 --- a/net/netfilter/nfnetlink_queue.c +++ b/net/netfilter/nfnetlink_queue.c @@ -299,7 +299,7 @@ __nfqnl_set_mode(struct nfqnl_instance *queue, case NFQNL_COPY_PACKET: queue->copy_mode = mode; - /* we're using struct nfattr which has 16bit nfa_len */ + /* we're using struct nlattr which has 16bit nla_len */ if (range > 0xffff) queue->copy_range = 0xffff; else @@ -353,18 +353,17 @@ nfqnl_build_packet_message(struct nfqnl_instance *queue, QDEBUG("entered\n"); - /* all macros expand to constant values at compile time */ - size = NLMSG_SPACE(sizeof(struct nfgenmsg)) + - + NFA_SPACE(sizeof(struct nfqnl_msg_packet_hdr)) - + NFA_SPACE(sizeof(u_int32_t)) /* ifindex */ - + NFA_SPACE(sizeof(u_int32_t)) /* ifindex */ + size = NLMSG_ALIGN(sizeof(struct nfgenmsg)) + + nla_total_size(sizeof(struct nfqnl_msg_packet_hdr)) + + nla_total_size(sizeof(u_int32_t)) /* ifindex */ + + nla_total_size(sizeof(u_int32_t)) /* ifindex */ #ifdef CONFIG_BRIDGE_NETFILTER - + NFA_SPACE(sizeof(u_int32_t)) /* ifindex */ - + NFA_SPACE(sizeof(u_int32_t)) /* ifindex */ + + nla_total_size(sizeof(u_int32_t)) /* ifindex */ + + nla_total_size(sizeof(u_int32_t)) /* ifindex */ #endif - + NFA_SPACE(sizeof(u_int32_t)) /* mark */ - + NFA_SPACE(sizeof(struct nfqnl_msg_packet_hw)) - + NFA_SPACE(sizeof(struct nfqnl_msg_packet_timestamp)); + + nla_total_size(sizeof(u_int32_t)) /* mark */ + + nla_total_size(sizeof(struct nfqnl_msg_packet_hw)) + + nla_total_size(sizeof(struct nfqnl_msg_packet_timestamp)); outdev = entinf->outdev; @@ -389,7 +388,7 @@ nfqnl_build_packet_message(struct nfqnl_instance *queue, else data_len = queue->copy_range; - size += NFA_SPACE(data_len); + size += nla_total_size(data_len); break; default: @@ -417,33 +416,33 @@ nfqnl_build_packet_message(struct nfqnl_instance *queue, pmsg.hw_protocol = entskb->protocol; pmsg.hook = entinf->hook; - NFA_PUT(skb, NFQA_PACKET_HDR, sizeof(pmsg), &pmsg); + NLA_PUT(skb, NFQA_PACKET_HDR, sizeof(pmsg), &pmsg); indev = entinf->indev; if (indev) { tmp_uint = htonl(indev->ifindex); #ifndef CONFIG_BRIDGE_NETFILTER - NFA_PUT(skb, NFQA_IFINDEX_INDEV, sizeof(tmp_uint), &tmp_uint); + NLA_PUT(skb, NFQA_IFINDEX_INDEV, sizeof(tmp_uint), &tmp_uint); #else if (entinf->pf == PF_BRIDGE) { /* Case 1: indev is physical input device, we need to * look for bridge group (when called from * netfilter_bridge) */ - NFA_PUT(skb, NFQA_IFINDEX_PHYSINDEV, sizeof(tmp_uint), + NLA_PUT(skb, NFQA_IFINDEX_PHYSINDEV, sizeof(tmp_uint), &tmp_uint); /* this is the bridge group "brX" */ tmp_uint = htonl(indev->br_port->br->dev->ifindex); - NFA_PUT(skb, NFQA_IFINDEX_INDEV, sizeof(tmp_uint), + NLA_PUT(skb, NFQA_IFINDEX_INDEV, sizeof(tmp_uint), &tmp_uint); } else { /* Case 2: indev is bridge group, we need to look for * physical device (when called from ipv4) */ - NFA_PUT(skb, NFQA_IFINDEX_INDEV, sizeof(tmp_uint), + NLA_PUT(skb, NFQA_IFINDEX_INDEV, sizeof(tmp_uint), &tmp_uint); if (entskb->nf_bridge && entskb->nf_bridge->physindev) { tmp_uint = htonl(entskb->nf_bridge->physindev->ifindex); - NFA_PUT(skb, NFQA_IFINDEX_PHYSINDEV, + NLA_PUT(skb, NFQA_IFINDEX_PHYSINDEV, sizeof(tmp_uint), &tmp_uint); } } @@ -453,27 +452,27 @@ nfqnl_build_packet_message(struct nfqnl_instance *queue, if (outdev) { tmp_uint = htonl(outdev->ifindex); #ifndef CONFIG_BRIDGE_NETFILTER - NFA_PUT(skb, NFQA_IFINDEX_OUTDEV, sizeof(tmp_uint), &tmp_uint); + NLA_PUT(skb, NFQA_IFINDEX_OUTDEV, sizeof(tmp_uint), &tmp_uint); #else if (entinf->pf == PF_BRIDGE) { /* Case 1: outdev is physical output device, we need to * look for bridge group (when called from * netfilter_bridge) */ - NFA_PUT(skb, NFQA_IFINDEX_PHYSOUTDEV, sizeof(tmp_uint), + NLA_PUT(skb, NFQA_IFINDEX_PHYSOUTDEV, sizeof(tmp_uint), &tmp_uint); /* this is the bridge group "brX" */ tmp_uint = htonl(outdev->br_port->br->dev->ifindex); - NFA_PUT(skb, NFQA_IFINDEX_OUTDEV, sizeof(tmp_uint), + NLA_PUT(skb, NFQA_IFINDEX_OUTDEV, sizeof(tmp_uint), &tmp_uint); } else { /* Case 2: outdev is bridge group, we need to look for * physical output device (when called from ipv4) */ - NFA_PUT(skb, NFQA_IFINDEX_OUTDEV, sizeof(tmp_uint), + NLA_PUT(skb, NFQA_IFINDEX_OUTDEV, sizeof(tmp_uint), &tmp_uint); if (entskb->nf_bridge && entskb->nf_bridge->physoutdev) { tmp_uint = htonl(entskb->nf_bridge->physoutdev->ifindex); - NFA_PUT(skb, NFQA_IFINDEX_PHYSOUTDEV, + NLA_PUT(skb, NFQA_IFINDEX_PHYSOUTDEV, sizeof(tmp_uint), &tmp_uint); } } @@ -482,7 +481,7 @@ nfqnl_build_packet_message(struct nfqnl_instance *queue, if (entskb->mark) { tmp_uint = htonl(entskb->mark); - NFA_PUT(skb, NFQA_MARK, sizeof(u_int32_t), &tmp_uint); + NLA_PUT(skb, NFQA_MARK, sizeof(u_int32_t), &tmp_uint); } if (indev && entskb->dev) { @@ -490,7 +489,7 @@ nfqnl_build_packet_message(struct nfqnl_instance *queue, int len = dev_parse_header(entskb, phw.hw_addr); if (len) { phw.hw_addrlen = htons(len); - NFA_PUT(skb, NFQA_HWADDR, sizeof(phw), &phw); + NLA_PUT(skb, NFQA_HWADDR, sizeof(phw), &phw); } } @@ -500,23 +499,23 @@ nfqnl_build_packet_message(struct nfqnl_instance *queue, ts.sec = cpu_to_be64(tv.tv_sec); ts.usec = cpu_to_be64(tv.tv_usec); - NFA_PUT(skb, NFQA_TIMESTAMP, sizeof(ts), &ts); + NLA_PUT(skb, NFQA_TIMESTAMP, sizeof(ts), &ts); } if (data_len) { - struct nfattr *nfa; - int size = NFA_LENGTH(data_len); + struct nlattr *nla; + int size = nla_attr_size(data_len); - if (skb_tailroom(skb) < (int)NFA_SPACE(data_len)) { + if (skb_tailroom(skb) < nla_total_size(data_len)) { printk(KERN_WARNING "nf_queue: no tailroom!\n"); goto nlmsg_failure; } - nfa = (struct nfattr *)skb_put(skb, NFA_ALIGN(size)); - nfa->nfa_type = NFQA_PAYLOAD; - nfa->nfa_len = size; + nla = (struct nlattr *)skb_put(skb, nla_total_size(data_len)); + nla->nla_type = NFQA_PAYLOAD; + nla->nla_len = size; - if (skb_copy_bits(entskb, 0, NFA_DATA(nfa), data_len)) + if (skb_copy_bits(entskb, 0, nla_data(nla), data_len)) BUG(); } @@ -524,7 +523,7 @@ nfqnl_build_packet_message(struct nfqnl_instance *queue, return skb; nlmsg_failure: -nfattr_failure: +nla_put_failure: if (skb) kfree_skb(skb); *errp = -EINVAL; @@ -778,15 +777,15 @@ static struct notifier_block nfqnl_rtnl_notifier = { .notifier_call = nfqnl_rcv_nl_event, }; -static const int nfqa_verdict_min[NFQA_MAX] = { - [NFQA_VERDICT_HDR-1] = sizeof(struct nfqnl_msg_verdict_hdr), - [NFQA_MARK-1] = sizeof(u_int32_t), - [NFQA_PAYLOAD-1] = 0, +static const int nfqa_verdict_min[NFQA_MAX+1] = { + [NFQA_VERDICT_HDR] = sizeof(struct nfqnl_msg_verdict_hdr), + [NFQA_MARK] = sizeof(u_int32_t), + [NFQA_PAYLOAD] = 0, }; static int nfqnl_recv_verdict(struct sock *ctnl, struct sk_buff *skb, - struct nlmsghdr *nlh, struct nfattr *nfqa[]) + struct nlmsghdr *nlh, struct nlattr *nfqa[]) { struct nfgenmsg *nfmsg = NLMSG_DATA(nlh); u_int16_t queue_num = ntohs(nfmsg->res_id); @@ -811,12 +810,12 @@ nfqnl_recv_verdict(struct sock *ctnl, struct sk_buff *skb, goto err_out_put; } - if (!nfqa[NFQA_VERDICT_HDR-1]) { + if (!nfqa[NFQA_VERDICT_HDR]) { err = -EINVAL; goto err_out_put; } - vhdr = NFA_DATA(nfqa[NFQA_VERDICT_HDR-1]); + vhdr = nla_data(nfqa[NFQA_VERDICT_HDR]); verdict = ntohl(vhdr->verdict); if ((verdict & NF_VERDICT_MASK) > NF_MAX_VERDICT) { @@ -830,15 +829,15 @@ nfqnl_recv_verdict(struct sock *ctnl, struct sk_buff *skb, goto err_out_put; } - if (nfqa[NFQA_PAYLOAD-1]) { - if (nfqnl_mangle(NFA_DATA(nfqa[NFQA_PAYLOAD-1]), - NFA_PAYLOAD(nfqa[NFQA_PAYLOAD-1]), entry) < 0) + if (nfqa[NFQA_PAYLOAD]) { + if (nfqnl_mangle(nla_data(nfqa[NFQA_PAYLOAD]), + nla_len(nfqa[NFQA_PAYLOAD]), entry) < 0) verdict = NF_DROP; } - if (nfqa[NFQA_MARK-1]) + if (nfqa[NFQA_MARK]) entry->skb->mark = ntohl(*(__be32 *) - NFA_DATA(nfqa[NFQA_MARK-1])); + nla_data(nfqa[NFQA_MARK])); issue_verdict(entry, verdict); instance_put(queue); @@ -851,14 +850,14 @@ err_out_put: static int nfqnl_recv_unsupp(struct sock *ctnl, struct sk_buff *skb, - struct nlmsghdr *nlh, struct nfattr *nfqa[]) + struct nlmsghdr *nlh, struct nlattr *nfqa[]) { return -ENOTSUPP; } -static const int nfqa_cfg_min[NFQA_CFG_MAX] = { - [NFQA_CFG_CMD-1] = sizeof(struct nfqnl_msg_config_cmd), - [NFQA_CFG_PARAMS-1] = sizeof(struct nfqnl_msg_config_params), +static const int nfqa_cfg_min[NFQA_CFG_MAX+1] = { + [NFQA_CFG_CMD] = sizeof(struct nfqnl_msg_config_cmd), + [NFQA_CFG_PARAMS] = sizeof(struct nfqnl_msg_config_params), }; static struct nf_queue_handler nfqh = { @@ -868,7 +867,7 @@ static struct nf_queue_handler nfqh = { static int nfqnl_recv_config(struct sock *ctnl, struct sk_buff *skb, - struct nlmsghdr *nlh, struct nfattr *nfqa[]) + struct nlmsghdr *nlh, struct nlattr *nfqa[]) { struct nfgenmsg *nfmsg = NLMSG_DATA(nlh); u_int16_t queue_num = ntohs(nfmsg->res_id); @@ -883,9 +882,9 @@ nfqnl_recv_config(struct sock *ctnl, struct sk_buff *skb, } queue = instance_lookup_get(queue_num); - if (nfqa[NFQA_CFG_CMD-1]) { + if (nfqa[NFQA_CFG_CMD]) { struct nfqnl_msg_config_cmd *cmd; - cmd = NFA_DATA(nfqa[NFQA_CFG_CMD-1]); + cmd = nla_data(nfqa[NFQA_CFG_CMD]); QDEBUG("found CFG_CMD\n"); switch (cmd->command) { @@ -936,21 +935,21 @@ nfqnl_recv_config(struct sock *ctnl, struct sk_buff *skb, } } - if (nfqa[NFQA_CFG_PARAMS-1]) { + if (nfqa[NFQA_CFG_PARAMS]) { struct nfqnl_msg_config_params *params; if (!queue) { ret = -ENOENT; goto out_put; } - params = NFA_DATA(nfqa[NFQA_CFG_PARAMS-1]); + params = nla_data(nfqa[NFQA_CFG_PARAMS]); nfqnl_set_mode(queue, params->copy_mode, ntohl(params->copy_range)); } - if (nfqa[NFQA_CFG_QUEUE_MAXLEN-1]) { + if (nfqa[NFQA_CFG_QUEUE_MAXLEN]) { __be32 *queue_maxlen; - queue_maxlen = NFA_DATA(nfqa[NFQA_CFG_QUEUE_MAXLEN-1]); + queue_maxlen = nla_data(nfqa[NFQA_CFG_QUEUE_MAXLEN]); spin_lock_bh(&queue->lock); queue->queue_maxlen = ntohl(*queue_maxlen); spin_unlock_bh(&queue->lock); -- cgit v1.2.3 From fdf708322d4658daa6eb795d1a835b97efdb335e Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Fri, 28 Sep 2007 14:37:41 -0700 Subject: [NETFILTER]: nfnetlink: rename functions containing 'nfattr' There is no struct nfattr anymore, rename functions to 'nlattr'. Signed-off-by: Patrick McHardy Signed-off-by: David S. Miller --- include/linux/netfilter/nfnetlink.h | 2 +- include/net/netfilter/nf_conntrack_helper.h | 2 +- include/net/netfilter/nf_conntrack_l3proto.h | 4 +- include/net/netfilter/nf_conntrack_l4proto.h | 12 +++--- include/net/netfilter/nf_nat_protocol.h | 8 ++-- net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c | 10 ++--- net/ipv4/netfilter/nf_conntrack_proto_icmp.c | 10 ++--- net/ipv4/netfilter/nf_nat_core.c | 8 ++-- net/ipv4/netfilter/nf_nat_proto_gre.c | 4 +- net/ipv4/netfilter/nf_nat_proto_icmp.c | 4 +- net/ipv4/netfilter/nf_nat_proto_tcp.c | 4 +- net/ipv4/netfilter/nf_nat_proto_udp.c | 4 +- net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c | 10 ++--- net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c | 10 ++--- net/netfilter/nf_conntrack_core.c | 10 ++--- net/netfilter/nf_conntrack_netlink.c | 52 +++++++++++++------------- net/netfilter/nf_conntrack_proto_gre.c | 4 +- net/netfilter/nf_conntrack_proto_tcp.c | 22 +++++------ net/netfilter/nf_conntrack_proto_udp.c | 8 ++-- net/netfilter/nf_conntrack_proto_udplite.c | 8 ++-- net/netfilter/nfnetlink_log.c | 2 +- net/netfilter/nfnetlink_queue.c | 4 +- 22 files changed, 101 insertions(+), 101 deletions(-) (limited to 'include/linux') diff --git a/include/linux/netfilter/nfnetlink.h b/include/linux/netfilter/nfnetlink.h index 47457b4c8c62..e61a8a5fcaff 100644 --- a/include/linux/netfilter/nfnetlink.h +++ b/include/linux/netfilter/nfnetlink.h @@ -72,7 +72,7 @@ struct nfnetlink_subsystem extern int nfnetlink_subsys_register(const struct nfnetlink_subsystem *n); extern int nfnetlink_subsys_unregister(const struct nfnetlink_subsystem *n); -#define nfattr_bad_size(tb, max, cta_min) \ +#define nlattr_bad_size(tb, max, cta_min) \ ({ int __i, __res = 0; \ for (__i=1; __i <= max; __i++) { \ if (!cta_min[__i]) \ diff --git a/include/net/netfilter/nf_conntrack_helper.h b/include/net/netfilter/nf_conntrack_helper.h index d04f99964d94..0dcc4c828ce9 100644 --- a/include/net/netfilter/nf_conntrack_helper.h +++ b/include/net/netfilter/nf_conntrack_helper.h @@ -36,7 +36,7 @@ struct nf_conntrack_helper void (*destroy)(struct nf_conn *ct); - int (*to_nfattr)(struct sk_buff *skb, const struct nf_conn *ct); + int (*to_nlattr)(struct sk_buff *skb, const struct nf_conn *ct); }; extern struct nf_conntrack_helper * diff --git a/include/net/netfilter/nf_conntrack_l3proto.h b/include/net/netfilter/nf_conntrack_l3proto.h index c02402d5ec36..f6c372d4ec1f 100644 --- a/include/net/netfilter/nf_conntrack_l3proto.h +++ b/include/net/netfilter/nf_conntrack_l3proto.h @@ -63,10 +63,10 @@ struct nf_conntrack_l3proto int (*get_l4proto)(const struct sk_buff *skb, unsigned int nhoff, unsigned int *dataoff, u_int8_t *protonum); - int (*tuple_to_nfattr)(struct sk_buff *skb, + int (*tuple_to_nlattr)(struct sk_buff *skb, const struct nf_conntrack_tuple *t); - int (*nfattr_to_tuple)(struct nlattr *tb[], + int (*nlattr_to_tuple)(struct nlattr *tb[], struct nf_conntrack_tuple *t); #ifdef CONFIG_SYSCTL diff --git a/include/net/netfilter/nf_conntrack_l4proto.h b/include/net/netfilter/nf_conntrack_l4proto.h index a43c4e484ea1..658daccc6b56 100644 --- a/include/net/netfilter/nf_conntrack_l4proto.h +++ b/include/net/netfilter/nf_conntrack_l4proto.h @@ -65,15 +65,15 @@ struct nf_conntrack_l4proto int pf, unsigned int hooknum); /* convert protoinfo to nfnetink attributes */ - int (*to_nfattr)(struct sk_buff *skb, struct nlattr *nla, + int (*to_nlattr)(struct sk_buff *skb, struct nlattr *nla, const struct nf_conn *ct); /* convert nfnetlink attributes to protoinfo */ - int (*from_nfattr)(struct nlattr *tb[], struct nf_conn *ct); + int (*from_nlattr)(struct nlattr *tb[], struct nf_conn *ct); - int (*tuple_to_nfattr)(struct sk_buff *skb, + int (*tuple_to_nlattr)(struct sk_buff *skb, const struct nf_conntrack_tuple *t); - int (*nfattr_to_tuple)(struct nlattr *tb[], + int (*nlattr_to_tuple)(struct nlattr *tb[], struct nf_conntrack_tuple *t); #ifdef CONFIG_SYSCTL @@ -111,9 +111,9 @@ extern int nf_conntrack_l4proto_register(struct nf_conntrack_l4proto *proto); extern void nf_conntrack_l4proto_unregister(struct nf_conntrack_l4proto *proto); /* Generic netlink helpers */ -extern int nf_ct_port_tuple_to_nfattr(struct sk_buff *skb, +extern int nf_ct_port_tuple_to_nlattr(struct sk_buff *skb, const struct nf_conntrack_tuple *tuple); -extern int nf_ct_port_nfattr_to_tuple(struct nlattr *tb[], +extern int nf_ct_port_nlattr_to_tuple(struct nlattr *tb[], struct nf_conntrack_tuple *t); /* Log invalid packets */ diff --git a/include/net/netfilter/nf_nat_protocol.h b/include/net/netfilter/nf_nat_protocol.h index 90a82de7e7e0..14c7b2d7263c 100644 --- a/include/net/netfilter/nf_nat_protocol.h +++ b/include/net/netfilter/nf_nat_protocol.h @@ -38,10 +38,10 @@ struct nf_nat_protocol enum nf_nat_manip_type maniptype, const struct nf_conn *ct); - int (*range_to_nfattr)(struct sk_buff *skb, + int (*range_to_nlattr)(struct sk_buff *skb, const struct nf_nat_range *range); - int (*nfattr_to_range)(struct nlattr *tb[], + int (*nlattr_to_range)(struct nlattr *tb[], struct nf_nat_range *range); }; @@ -62,9 +62,9 @@ extern int init_protocols(void) __init; extern void cleanup_protocols(void); extern struct nf_nat_protocol *find_nat_proto(u_int16_t protonum); -extern int nf_nat_port_range_to_nfattr(struct sk_buff *skb, +extern int nf_nat_port_range_to_nlattr(struct sk_buff *skb, const struct nf_nat_range *range); -extern int nf_nat_port_nfattr_to_range(struct nlattr *tb[], +extern int nf_nat_port_nlattr_to_range(struct nlattr *tb[], struct nf_nat_range *range); #endif /*_NF_NAT_PROTO_H*/ diff --git a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c index f8771e058b9e..77ca556aad91 100644 --- a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c +++ b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c @@ -360,7 +360,7 @@ getorigdst(struct sock *sk, int optval, void __user *user, int *len) #include #include -static int ipv4_tuple_to_nfattr(struct sk_buff *skb, +static int ipv4_tuple_to_nlattr(struct sk_buff *skb, const struct nf_conntrack_tuple *tuple) { NLA_PUT(skb, CTA_IP_V4_SRC, sizeof(u_int32_t), @@ -378,13 +378,13 @@ static const size_t cta_min_ip[CTA_IP_MAX+1] = { [CTA_IP_V4_DST] = sizeof(u_int32_t), }; -static int ipv4_nfattr_to_tuple(struct nlattr *tb[], +static int ipv4_nlattr_to_tuple(struct nlattr *tb[], struct nf_conntrack_tuple *t) { if (!tb[CTA_IP_V4_SRC] || !tb[CTA_IP_V4_DST]) return -EINVAL; - if (nfattr_bad_size(tb, CTA_IP_MAX, cta_min_ip)) + if (nlattr_bad_size(tb, CTA_IP_MAX, cta_min_ip)) return -EINVAL; t->src.u3.ip = *(__be32 *)nla_data(tb[CTA_IP_V4_SRC]); @@ -411,8 +411,8 @@ struct nf_conntrack_l3proto nf_conntrack_l3proto_ipv4 __read_mostly = { .print_conntrack = ipv4_print_conntrack, .get_l4proto = ipv4_get_l4proto, #if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE) - .tuple_to_nfattr = ipv4_tuple_to_nfattr, - .nfattr_to_tuple = ipv4_nfattr_to_tuple, + .tuple_to_nlattr = ipv4_tuple_to_nlattr, + .nlattr_to_tuple = ipv4_nlattr_to_tuple, #endif #if defined(CONFIG_SYSCTL) && defined(CONFIG_NF_CONNTRACK_PROC_COMPAT) .ctl_table_path = nf_net_ipv4_netfilter_sysctl_path, diff --git a/net/ipv4/netfilter/nf_conntrack_proto_icmp.c b/net/ipv4/netfilter/nf_conntrack_proto_icmp.c index 714332b8869e..ca7252c10758 100644 --- a/net/ipv4/netfilter/nf_conntrack_proto_icmp.c +++ b/net/ipv4/netfilter/nf_conntrack_proto_icmp.c @@ -232,7 +232,7 @@ icmp_error(struct sk_buff *skb, unsigned int dataoff, #include #include -static int icmp_tuple_to_nfattr(struct sk_buff *skb, +static int icmp_tuple_to_nlattr(struct sk_buff *skb, const struct nf_conntrack_tuple *t) { NLA_PUT(skb, CTA_PROTO_ICMP_ID, sizeof(u_int16_t), @@ -254,7 +254,7 @@ static const size_t cta_min_proto[CTA_PROTO_MAX+1] = { [CTA_PROTO_ICMP_ID] = sizeof(u_int16_t) }; -static int icmp_nfattr_to_tuple(struct nlattr *tb[], +static int icmp_nlattr_to_tuple(struct nlattr *tb[], struct nf_conntrack_tuple *tuple) { if (!tb[CTA_PROTO_ICMP_TYPE] @@ -262,7 +262,7 @@ static int icmp_nfattr_to_tuple(struct nlattr *tb[], || !tb[CTA_PROTO_ICMP_ID]) return -EINVAL; - if (nfattr_bad_size(tb, CTA_PROTO_MAX, cta_min_proto)) + if (nlattr_bad_size(tb, CTA_PROTO_MAX, cta_min_proto)) return -EINVAL; tuple->dst.u.icmp.type = @@ -327,8 +327,8 @@ struct nf_conntrack_l4proto nf_conntrack_l4proto_icmp __read_mostly = .destroy = NULL, .me = NULL, #if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE) - .tuple_to_nfattr = icmp_tuple_to_nfattr, - .nfattr_to_tuple = icmp_nfattr_to_tuple, + .tuple_to_nlattr = icmp_tuple_to_nlattr, + .nlattr_to_tuple = icmp_nlattr_to_tuple, #endif #ifdef CONFIG_SYSCTL .ctl_table_header = &icmp_sysctl_header, diff --git a/net/ipv4/netfilter/nf_nat_core.c b/net/ipv4/netfilter/nf_nat_core.c index 4bdbb128fe50..7221aa20e6ff 100644 --- a/net/ipv4/netfilter/nf_nat_core.c +++ b/net/ipv4/netfilter/nf_nat_core.c @@ -544,7 +544,7 @@ EXPORT_SYMBOL(nf_nat_protocol_unregister); #if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE) int -nf_nat_port_range_to_nfattr(struct sk_buff *skb, +nf_nat_port_range_to_nlattr(struct sk_buff *skb, const struct nf_nat_range *range) { NLA_PUT(skb, CTA_PROTONAT_PORT_MIN, sizeof(__be16), @@ -557,10 +557,10 @@ nf_nat_port_range_to_nfattr(struct sk_buff *skb, nla_put_failure: return -1; } -EXPORT_SYMBOL_GPL(nf_nat_port_nfattr_to_range); +EXPORT_SYMBOL_GPL(nf_nat_port_nlattr_to_range); int -nf_nat_port_nfattr_to_range(struct nlattr *tb[], struct nf_nat_range *range) +nf_nat_port_nlattr_to_range(struct nlattr *tb[], struct nf_nat_range *range) { int ret = 0; @@ -583,7 +583,7 @@ nf_nat_port_nfattr_to_range(struct nlattr *tb[], struct nf_nat_range *range) return ret; } -EXPORT_SYMBOL_GPL(nf_nat_port_range_to_nfattr); +EXPORT_SYMBOL_GPL(nf_nat_port_range_to_nlattr); #endif /* Noone using conntrack by the time this called. */ diff --git a/net/ipv4/netfilter/nf_nat_proto_gre.c b/net/ipv4/netfilter/nf_nat_proto_gre.c index 2e40cc83526a..d562290b1820 100644 --- a/net/ipv4/netfilter/nf_nat_proto_gre.c +++ b/net/ipv4/netfilter/nf_nat_proto_gre.c @@ -142,8 +142,8 @@ static struct nf_nat_protocol gre __read_mostly = { .in_range = gre_in_range, .unique_tuple = gre_unique_tuple, #if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE) - .range_to_nfattr = nf_nat_port_range_to_nfattr, - .nfattr_to_range = nf_nat_port_nfattr_to_range, + .range_to_nlattr = nf_nat_port_range_to_nlattr, + .nlattr_to_range = nf_nat_port_nlattr_to_range, #endif }; diff --git a/net/ipv4/netfilter/nf_nat_proto_icmp.c b/net/ipv4/netfilter/nf_nat_proto_icmp.c index f71ef9b5f428..898d73771155 100644 --- a/net/ipv4/netfilter/nf_nat_proto_icmp.c +++ b/net/ipv4/netfilter/nf_nat_proto_icmp.c @@ -79,7 +79,7 @@ struct nf_nat_protocol nf_nat_protocol_icmp = { .in_range = icmp_in_range, .unique_tuple = icmp_unique_tuple, #if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE) - .range_to_nfattr = nf_nat_port_range_to_nfattr, - .nfattr_to_range = nf_nat_port_nfattr_to_range, + .range_to_nlattr = nf_nat_port_range_to_nlattr, + .nlattr_to_range = nf_nat_port_nlattr_to_range, #endif }; diff --git a/net/ipv4/netfilter/nf_nat_proto_tcp.c b/net/ipv4/netfilter/nf_nat_proto_tcp.c index 123c95913f28..5bbbb2acdc70 100644 --- a/net/ipv4/netfilter/nf_nat_proto_tcp.c +++ b/net/ipv4/netfilter/nf_nat_proto_tcp.c @@ -145,7 +145,7 @@ struct nf_nat_protocol nf_nat_protocol_tcp = { .in_range = tcp_in_range, .unique_tuple = tcp_unique_tuple, #if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE) - .range_to_nfattr = nf_nat_port_range_to_nfattr, - .nfattr_to_range = nf_nat_port_nfattr_to_range, + .range_to_nlattr = nf_nat_port_range_to_nlattr, + .nlattr_to_range = nf_nat_port_nlattr_to_range, #endif }; diff --git a/net/ipv4/netfilter/nf_nat_proto_udp.c b/net/ipv4/netfilter/nf_nat_proto_udp.c index 1c4c70e25cd4..a0af4fd95584 100644 --- a/net/ipv4/netfilter/nf_nat_proto_udp.c +++ b/net/ipv4/netfilter/nf_nat_proto_udp.c @@ -135,7 +135,7 @@ struct nf_nat_protocol nf_nat_protocol_udp = { .in_range = udp_in_range, .unique_tuple = udp_unique_tuple, #if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE) - .range_to_nfattr = nf_nat_port_range_to_nfattr, - .nfattr_to_range = nf_nat_port_nfattr_to_range, + .range_to_nlattr = nf_nat_port_range_to_nlattr, + .nlattr_to_range = nf_nat_port_nlattr_to_range, #endif }; diff --git a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c index f0ea3fb51670..567fbe230ce6 100644 --- a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c +++ b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c @@ -337,7 +337,7 @@ static ctl_table nf_ct_ipv6_sysctl_table[] = { #include #include -static int ipv6_tuple_to_nfattr(struct sk_buff *skb, +static int ipv6_tuple_to_nlattr(struct sk_buff *skb, const struct nf_conntrack_tuple *tuple) { NLA_PUT(skb, CTA_IP_V6_SRC, sizeof(u_int32_t) * 4, @@ -355,13 +355,13 @@ static const size_t cta_min_ip[CTA_IP_MAX+1] = { [CTA_IP_V6_DST] = sizeof(u_int32_t)*4, }; -static int ipv6_nfattr_to_tuple(struct nlattr *tb[], +static int ipv6_nlattr_to_tuple(struct nlattr *tb[], struct nf_conntrack_tuple *t) { if (!tb[CTA_IP_V6_SRC] || !tb[CTA_IP_V6_DST]) return -EINVAL; - if (nfattr_bad_size(tb, CTA_IP_MAX, cta_min_ip)) + if (nlattr_bad_size(tb, CTA_IP_MAX, cta_min_ip)) return -EINVAL; memcpy(&t->src.u3.ip6, nla_data(tb[CTA_IP_V6_SRC]), @@ -382,8 +382,8 @@ struct nf_conntrack_l3proto nf_conntrack_l3proto_ipv6 __read_mostly = { .print_conntrack = ipv6_print_conntrack, .get_l4proto = ipv6_get_l4proto, #if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE) - .tuple_to_nfattr = ipv6_tuple_to_nfattr, - .nfattr_to_tuple = ipv6_nfattr_to_tuple, + .tuple_to_nlattr = ipv6_tuple_to_nlattr, + .nlattr_to_tuple = ipv6_nlattr_to_tuple, #endif #ifdef CONFIG_SYSCTL .ctl_table_path = nf_net_netfilter_sysctl_path, diff --git a/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c b/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c index c18183823faf..238ea6bc864e 100644 --- a/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c +++ b/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c @@ -210,7 +210,7 @@ icmpv6_error(struct sk_buff *skb, unsigned int dataoff, #include #include -static int icmpv6_tuple_to_nfattr(struct sk_buff *skb, +static int icmpv6_tuple_to_nlattr(struct sk_buff *skb, const struct nf_conntrack_tuple *t) { NLA_PUT(skb, CTA_PROTO_ICMPV6_ID, sizeof(u_int16_t), @@ -232,7 +232,7 @@ static const size_t cta_min_proto[CTA_PROTO_MAX+1] = { [CTA_PROTO_ICMPV6_ID] = sizeof(u_int16_t) }; -static int icmpv6_nfattr_to_tuple(struct nlattr *tb[], +static int icmpv6_nlattr_to_tuple(struct nlattr *tb[], struct nf_conntrack_tuple *tuple) { if (!tb[CTA_PROTO_ICMPV6_TYPE] @@ -240,7 +240,7 @@ static int icmpv6_nfattr_to_tuple(struct nlattr *tb[], || !tb[CTA_PROTO_ICMPV6_ID]) return -EINVAL; - if (nfattr_bad_size(tb, CTA_PROTO_MAX, cta_min_proto)) + if (nlattr_bad_size(tb, CTA_PROTO_MAX, cta_min_proto)) return -EINVAL; tuple->dst.u.icmp.type = @@ -289,8 +289,8 @@ struct nf_conntrack_l4proto nf_conntrack_l4proto_icmpv6 __read_mostly = .new = icmpv6_new, .error = icmpv6_error, #if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE) - .tuple_to_nfattr = icmpv6_tuple_to_nfattr, - .nfattr_to_tuple = icmpv6_nfattr_to_tuple, + .tuple_to_nlattr = icmpv6_tuple_to_nlattr, + .nlattr_to_tuple = icmpv6_nlattr_to_tuple, #endif #ifdef CONFIG_SYSCTL .ctl_table_header = &icmpv6_sysctl_header, diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c index b64656abc4e0..9edaaf2d57e7 100644 --- a/net/netfilter/nf_conntrack_core.c +++ b/net/netfilter/nf_conntrack_core.c @@ -830,7 +830,7 @@ EXPORT_SYMBOL_GPL(__nf_ct_refresh_acct); /* Generic function for tcp/udp/sctp/dccp and alike. This needs to be * in ip_conntrack_core, since we don't want the protocols to autoload * or depend on ctnetlink */ -int nf_ct_port_tuple_to_nfattr(struct sk_buff *skb, +int nf_ct_port_tuple_to_nlattr(struct sk_buff *skb, const struct nf_conntrack_tuple *tuple) { NLA_PUT(skb, CTA_PROTO_SRC_PORT, sizeof(u_int16_t), @@ -842,20 +842,20 @@ int nf_ct_port_tuple_to_nfattr(struct sk_buff *skb, nla_put_failure: return -1; } -EXPORT_SYMBOL_GPL(nf_ct_port_tuple_to_nfattr); +EXPORT_SYMBOL_GPL(nf_ct_port_tuple_to_nlattr); static const size_t cta_min_proto[CTA_PROTO_MAX+1] = { [CTA_PROTO_SRC_PORT] = sizeof(u_int16_t), [CTA_PROTO_DST_PORT] = sizeof(u_int16_t) }; -int nf_ct_port_nfattr_to_tuple(struct nlattr *tb[], +int nf_ct_port_nlattr_to_tuple(struct nlattr *tb[], struct nf_conntrack_tuple *t) { if (!tb[CTA_PROTO_SRC_PORT] || !tb[CTA_PROTO_DST_PORT]) return -EINVAL; - if (nfattr_bad_size(tb, CTA_PROTO_MAX, cta_min_proto)) + if (nlattr_bad_size(tb, CTA_PROTO_MAX, cta_min_proto)) return -EINVAL; t->src.u.tcp.port = *(__be16 *)nla_data(tb[CTA_PROTO_SRC_PORT]); @@ -863,7 +863,7 @@ int nf_ct_port_nfattr_to_tuple(struct nlattr *tb[], return 0; } -EXPORT_SYMBOL_GPL(nf_ct_port_nfattr_to_tuple); +EXPORT_SYMBOL_GPL(nf_ct_port_nlattr_to_tuple); #endif /* Used by ipt_REJECT and ip6t_REJECT. */ diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c index 221c38f889bf..9f9bef2446a1 100644 --- a/net/netfilter/nf_conntrack_netlink.c +++ b/net/netfilter/nf_conntrack_netlink.c @@ -61,8 +61,8 @@ ctnetlink_dump_tuples_proto(struct sk_buff *skb, goto nla_put_failure; NLA_PUT(skb, CTA_PROTO_NUM, sizeof(u_int8_t), &tuple->dst.protonum); - if (likely(l4proto->tuple_to_nfattr)) - ret = l4proto->tuple_to_nfattr(skb, tuple); + if (likely(l4proto->tuple_to_nlattr)) + ret = l4proto->tuple_to_nlattr(skb, tuple); nla_nest_end(skb, nest_parms); @@ -84,8 +84,8 @@ ctnetlink_dump_tuples_ip(struct sk_buff *skb, if (!nest_parms) goto nla_put_failure; - if (likely(l3proto->tuple_to_nfattr)) - ret = l3proto->tuple_to_nfattr(skb, tuple); + if (likely(l3proto->tuple_to_nlattr)) + ret = l3proto->tuple_to_nlattr(skb, tuple); nla_nest_end(skb, nest_parms); @@ -153,7 +153,7 @@ ctnetlink_dump_protoinfo(struct sk_buff *skb, const struct nf_conn *ct) struct nlattr *nest_proto; int ret; - if (!l4proto->to_nfattr) { + if (!l4proto->to_nlattr) { nf_ct_l4proto_put(l4proto); return 0; } @@ -162,7 +162,7 @@ ctnetlink_dump_protoinfo(struct sk_buff *skb, const struct nf_conn *ct) if (!nest_proto) goto nla_put_failure; - ret = l4proto->to_nfattr(skb, nest_proto, ct); + ret = l4proto->to_nlattr(skb, nest_proto, ct); nf_ct_l4proto_put(l4proto); @@ -195,8 +195,8 @@ ctnetlink_dump_helpinfo(struct sk_buff *skb, const struct nf_conn *ct) goto nla_put_failure; NLA_PUT(skb, CTA_HELP_NAME, strlen(helper->name), helper->name); - if (helper->to_nfattr) - helper->to_nfattr(skb, ct); + if (helper->to_nlattr) + helper->to_nlattr(skb, ct); nla_nest_end(skb, nest_helper); out: @@ -512,8 +512,8 @@ ctnetlink_parse_tuple_ip(struct nlattr *attr, struct nf_conntrack_tuple *tuple) l3proto = nf_ct_l3proto_find_get(tuple->src.l3num); - if (likely(l3proto->nfattr_to_tuple)) - ret = l3proto->nfattr_to_tuple(tb, tuple); + if (likely(l3proto->nlattr_to_tuple)) + ret = l3proto->nlattr_to_tuple(tb, tuple); nf_ct_l3proto_put(l3proto); @@ -534,7 +534,7 @@ ctnetlink_parse_tuple_proto(struct nlattr *attr, nla_parse_nested(tb, CTA_PROTO_MAX, attr, NULL); - if (nfattr_bad_size(tb, CTA_PROTO_MAX, cta_min_proto)) + if (nlattr_bad_size(tb, CTA_PROTO_MAX, cta_min_proto)) return -EINVAL; if (!tb[CTA_PROTO_NUM]) @@ -543,8 +543,8 @@ ctnetlink_parse_tuple_proto(struct nlattr *attr, l4proto = nf_ct_l4proto_find_get(tuple->src.l3num, tuple->dst.protonum); - if (likely(l4proto->nfattr_to_tuple)) - ret = l4proto->nfattr_to_tuple(tb, tuple); + if (likely(l4proto->nlattr_to_tuple)) + ret = l4proto->nlattr_to_tuple(tb, tuple); nf_ct_l4proto_put(l4proto); @@ -602,18 +602,18 @@ static int nfnetlink_parse_nat_proto(struct nlattr *attr, nla_parse_nested(tb, CTA_PROTONAT_MAX, attr, NULL); - if (nfattr_bad_size(tb, CTA_PROTONAT_MAX, cta_min_protonat)) + if (nlattr_bad_size(tb, CTA_PROTONAT_MAX, cta_min_protonat)) return -EINVAL; npt = nf_nat_proto_find_get(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum); - if (!npt->nfattr_to_range) { + if (!npt->nlattr_to_range) { nf_nat_proto_put(npt); return 0; } - /* nfattr_to_range returns 1 if it parsed, 0 if not, neg. on error */ - if (npt->nfattr_to_range(tb, range) > 0) + /* nlattr_to_range returns 1 if it parsed, 0 if not, neg. on error */ + if (npt->nlattr_to_range(tb, range) > 0) range->flags |= IP_NAT_RANGE_PROTO_SPECIFIED; nf_nat_proto_put(npt); @@ -637,7 +637,7 @@ nfnetlink_parse_nat(struct nlattr *nat, nla_parse_nested(tb, CTA_NAT_MAX, nat, NULL); - if (nfattr_bad_size(tb, CTA_NAT_MAX, cta_min_nat)) + if (nlattr_bad_size(tb, CTA_NAT_MAX, cta_min_nat)) return -EINVAL; if (tb[CTA_NAT_MINIP]) @@ -696,7 +696,7 @@ ctnetlink_del_conntrack(struct sock *ctnl, struct sk_buff *skb, u_int8_t u3 = nfmsg->nfgen_family; int err = 0; - if (nfattr_bad_size(cda, CTA_MAX, cta_min)) + if (nlattr_bad_size(cda, CTA_MAX, cta_min)) return -EINVAL; if (cda[CTA_TUPLE_ORIG]) @@ -754,7 +754,7 @@ ctnetlink_get_conntrack(struct sock *ctnl, struct sk_buff *skb, ctnetlink_done); } - if (nfattr_bad_size(cda, CTA_MAX, cta_min)) + if (nlattr_bad_size(cda, CTA_MAX, cta_min)) return -EINVAL; if (cda[CTA_TUPLE_ORIG]) @@ -928,8 +928,8 @@ ctnetlink_change_protoinfo(struct nf_conn *ct, struct nlattr *cda[]) l4proto = nf_ct_l4proto_find_get(l3num, npt); - if (l4proto->from_nfattr) - err = l4proto->from_nfattr(tb, ct); + if (l4proto->from_nlattr) + err = l4proto->from_nlattr(tb, ct); nf_ct_l4proto_put(l4proto); return err; @@ -1045,7 +1045,7 @@ ctnetlink_new_conntrack(struct sock *ctnl, struct sk_buff *skb, u_int8_t u3 = nfmsg->nfgen_family; int err = 0; - if (nfattr_bad_size(cda, CTA_MAX, cta_min)) + if (nlattr_bad_size(cda, CTA_MAX, cta_min)) return -EINVAL; if (cda[CTA_TUPLE_ORIG]) { @@ -1329,7 +1329,7 @@ ctnetlink_get_expect(struct sock *ctnl, struct sk_buff *skb, u_int8_t u3 = nfmsg->nfgen_family; int err = 0; - if (nfattr_bad_size(cda, CTA_EXPECT_MAX, cta_min_exp)) + if (nlattr_bad_size(cda, CTA_EXPECT_MAX, cta_min_exp)) return -EINVAL; if (nlh->nlmsg_flags & NLM_F_DUMP) { @@ -1393,7 +1393,7 @@ ctnetlink_del_expect(struct sock *ctnl, struct sk_buff *skb, unsigned int i; int err; - if (nfattr_bad_size(cda, CTA_EXPECT_MAX, cta_min_exp)) + if (nlattr_bad_size(cda, CTA_EXPECT_MAX, cta_min_exp)) return -EINVAL; if (cda[CTA_EXPECT_TUPLE]) { @@ -1534,7 +1534,7 @@ ctnetlink_new_expect(struct sock *ctnl, struct sk_buff *skb, u_int8_t u3 = nfmsg->nfgen_family; int err = 0; - if (nfattr_bad_size(cda, CTA_EXPECT_MAX, cta_min_exp)) + if (nlattr_bad_size(cda, CTA_EXPECT_MAX, cta_min_exp)) return -EINVAL; if (!cda[CTA_EXPECT_TUPLE] diff --git a/net/netfilter/nf_conntrack_proto_gre.c b/net/netfilter/nf_conntrack_proto_gre.c index bdbead8a7a83..ff8d03b88402 100644 --- a/net/netfilter/nf_conntrack_proto_gre.c +++ b/net/netfilter/nf_conntrack_proto_gre.c @@ -274,8 +274,8 @@ static struct nf_conntrack_l4proto nf_conntrack_l4proto_gre4 __read_mostly = { .destroy = gre_destroy, .me = THIS_MODULE, #if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE) - .tuple_to_nfattr = nf_ct_port_tuple_to_nfattr, - .nfattr_to_tuple = nf_ct_port_nfattr_to_tuple, + .tuple_to_nlattr = nf_ct_port_tuple_to_nlattr, + .nlattr_to_tuple = nf_ct_port_nlattr_to_tuple, #endif }; diff --git a/net/netfilter/nf_conntrack_proto_tcp.c b/net/netfilter/nf_conntrack_proto_tcp.c index 1d167e61cc44..84f47bc90f63 100644 --- a/net/netfilter/nf_conntrack_proto_tcp.c +++ b/net/netfilter/nf_conntrack_proto_tcp.c @@ -1067,7 +1067,7 @@ static int tcp_new(struct nf_conn *conntrack, #include #include -static int tcp_to_nfattr(struct sk_buff *skb, struct nlattr *nla, +static int tcp_to_nlattr(struct sk_buff *skb, struct nlattr *nla, const struct nf_conn *ct) { struct nlattr *nest_parms; @@ -1113,7 +1113,7 @@ static const size_t cta_min_tcp[CTA_PROTOINFO_TCP_MAX+1] = { [CTA_PROTOINFO_TCP_FLAGS_REPLY] = sizeof(struct nf_ct_tcp_flags) }; -static int nfattr_to_tcp(struct nlattr *cda[], struct nf_conn *ct) +static int nlattr_to_tcp(struct nlattr *cda[], struct nf_conn *ct) { struct nlattr *attr = cda[CTA_PROTOINFO_TCP]; struct nlattr *tb[CTA_PROTOINFO_TCP_MAX+1]; @@ -1125,7 +1125,7 @@ static int nfattr_to_tcp(struct nlattr *cda[], struct nf_conn *ct) nla_parse_nested(tb, CTA_PROTOINFO_TCP_MAX, attr, NULL); - if (nfattr_bad_size(tb, CTA_PROTOINFO_TCP_MAX, cta_min_tcp)) + if (nlattr_bad_size(tb, CTA_PROTOINFO_TCP_MAX, cta_min_tcp)) return -EINVAL; if (!tb[CTA_PROTOINFO_TCP_STATE]) @@ -1387,10 +1387,10 @@ struct nf_conntrack_l4proto nf_conntrack_l4proto_tcp4 __read_mostly = .new = tcp_new, .error = tcp_error, #if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE) - .to_nfattr = tcp_to_nfattr, - .from_nfattr = nfattr_to_tcp, - .tuple_to_nfattr = nf_ct_port_tuple_to_nfattr, - .nfattr_to_tuple = nf_ct_port_nfattr_to_tuple, + .to_nlattr = tcp_to_nlattr, + .from_nlattr = nlattr_to_tcp, + .tuple_to_nlattr = nf_ct_port_tuple_to_nlattr, + .nlattr_to_tuple = nf_ct_port_nlattr_to_tuple, #endif #ifdef CONFIG_SYSCTL .ctl_table_users = &tcp_sysctl_table_users, @@ -1416,10 +1416,10 @@ struct nf_conntrack_l4proto nf_conntrack_l4proto_tcp6 __read_mostly = .new = tcp_new, .error = tcp_error, #if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE) - .to_nfattr = tcp_to_nfattr, - .from_nfattr = nfattr_to_tcp, - .tuple_to_nfattr = nf_ct_port_tuple_to_nfattr, - .nfattr_to_tuple = nf_ct_port_nfattr_to_tuple, + .to_nlattr = tcp_to_nlattr, + .from_nlattr = nlattr_to_tcp, + .tuple_to_nlattr = nf_ct_port_tuple_to_nlattr, + .nlattr_to_tuple = nf_ct_port_nlattr_to_tuple, #endif #ifdef CONFIG_SYSCTL .ctl_table_users = &tcp_sysctl_table_users, diff --git a/net/netfilter/nf_conntrack_proto_udp.c b/net/netfilter/nf_conntrack_proto_udp.c index 2a2fd1a764ea..751ff7e2a0d9 100644 --- a/net/netfilter/nf_conntrack_proto_udp.c +++ b/net/netfilter/nf_conntrack_proto_udp.c @@ -203,8 +203,8 @@ struct nf_conntrack_l4proto nf_conntrack_l4proto_udp4 __read_mostly = .new = udp_new, .error = udp_error, #if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE) - .tuple_to_nfattr = nf_ct_port_tuple_to_nfattr, - .nfattr_to_tuple = nf_ct_port_nfattr_to_tuple, + .tuple_to_nlattr = nf_ct_port_tuple_to_nlattr, + .nlattr_to_tuple = nf_ct_port_nlattr_to_tuple, #endif #ifdef CONFIG_SYSCTL .ctl_table_users = &udp_sysctl_table_users, @@ -230,8 +230,8 @@ struct nf_conntrack_l4proto nf_conntrack_l4proto_udp6 __read_mostly = .new = udp_new, .error = udp_error, #if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE) - .tuple_to_nfattr = nf_ct_port_tuple_to_nfattr, - .nfattr_to_tuple = nf_ct_port_nfattr_to_tuple, + .tuple_to_nlattr = nf_ct_port_tuple_to_nlattr, + .nlattr_to_tuple = nf_ct_port_nlattr_to_tuple, #endif #ifdef CONFIG_SYSCTL .ctl_table_users = &udp_sysctl_table_users, diff --git a/net/netfilter/nf_conntrack_proto_udplite.c b/net/netfilter/nf_conntrack_proto_udplite.c index b906b413997c..4209ddb8fbaf 100644 --- a/net/netfilter/nf_conntrack_proto_udplite.c +++ b/net/netfilter/nf_conntrack_proto_udplite.c @@ -203,8 +203,8 @@ static struct nf_conntrack_l4proto nf_conntrack_l4proto_udplite4 __read_mostly = .new = udplite_new, .error = udplite_error, #if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE) - .tuple_to_nfattr = nf_ct_port_tuple_to_nfattr, - .nfattr_to_tuple = nf_ct_port_nfattr_to_tuple, + .tuple_to_nlattr = nf_ct_port_tuple_to_nlattr, + .nlattr_to_tuple = nf_ct_port_nlattr_to_tuple, #endif #ifdef CONFIG_SYSCTL .ctl_table_users = &udplite_sysctl_table_users, @@ -226,8 +226,8 @@ static struct nf_conntrack_l4proto nf_conntrack_l4proto_udplite6 __read_mostly = .new = udplite_new, .error = udplite_error, #if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE) - .tuple_to_nfattr = nf_ct_port_tuple_to_nfattr, - .nfattr_to_tuple = nf_ct_port_nfattr_to_tuple, + .tuple_to_nlattr = nf_ct_port_tuple_to_nlattr, + .nlattr_to_tuple = nf_ct_port_nlattr_to_tuple, #endif #ifdef CONFIG_SYSCTL .ctl_table_users = &udplite_sysctl_table_users, diff --git a/net/netfilter/nfnetlink_log.c b/net/netfilter/nfnetlink_log.c index c7fd82f6cb7d..b656648537c6 100644 --- a/net/netfilter/nfnetlink_log.c +++ b/net/netfilter/nfnetlink_log.c @@ -769,7 +769,7 @@ nfulnl_recv_config(struct sock *ctnl, struct sk_buff *skb, UDEBUG("entering for msg %u\n", NFNL_MSG_TYPE(nlh->nlmsg_type)); - if (nfattr_bad_size(nfula, NFULA_CFG_MAX, nfula_cfg_min)) { + if (nlattr_bad_size(nfula, NFULA_CFG_MAX, nfula_cfg_min)) { UDEBUG("bad attribute size\n"); return -EINVAL; } diff --git a/net/netfilter/nfnetlink_queue.c b/net/netfilter/nfnetlink_queue.c index 068e88b46ba0..1c34668588f1 100644 --- a/net/netfilter/nfnetlink_queue.c +++ b/net/netfilter/nfnetlink_queue.c @@ -796,7 +796,7 @@ nfqnl_recv_verdict(struct sock *ctnl, struct sk_buff *skb, struct nfqnl_queue_entry *entry; int err; - if (nfattr_bad_size(nfqa, NFQA_MAX, nfqa_verdict_min)) { + if (nlattr_bad_size(nfqa, NFQA_MAX, nfqa_verdict_min)) { QDEBUG("bad attribute size\n"); return -EINVAL; } @@ -876,7 +876,7 @@ nfqnl_recv_config(struct sock *ctnl, struct sk_buff *skb, QDEBUG("entering for msg %u\n", NFNL_MSG_TYPE(nlh->nlmsg_type)); - if (nfattr_bad_size(nfqa, NFQA_CFG_MAX, nfqa_cfg_min)) { + if (nlattr_bad_size(nfqa, NFQA_CFG_MAX, nfqa_cfg_min)) { QDEBUG("bad attribute size\n"); return -EINVAL; } -- cgit v1.2.3 From e3730578285fcf0c628f08b0dc89425cfeafd4ba Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Fri, 28 Sep 2007 14:38:52 -0700 Subject: [NETFILTER]: nfnetlink: support attribute policies Add support for automatic checking of per-callback attribute policies. Signed-off-by: Patrick McHardy Signed-off-by: David S. Miller --- include/linux/netfilter/nfnetlink.h | 3 ++- net/netfilter/nfnetlink.c | 48 ++++++++++--------------------------- 2 files changed, 15 insertions(+), 36 deletions(-) (limited to 'include/linux') diff --git a/include/linux/netfilter/nfnetlink.h b/include/linux/netfilter/nfnetlink.h index e61a8a5fcaff..cd8fded36550 100644 --- a/include/linux/netfilter/nfnetlink.h +++ b/include/linux/netfilter/nfnetlink.h @@ -58,7 +58,8 @@ struct nfnl_callback { int (*call)(struct sock *nl, struct sk_buff *skb, struct nlmsghdr *nlh, struct nlattr *cda[]); - u_int16_t attr_count; /* number of nlattr's */ + const struct nla_policy *policy; /* netlink attribute policy */ + const u_int16_t attr_count; /* number of nlattr's */ }; struct nfnetlink_subsystem diff --git a/net/netfilter/nfnetlink.c b/net/netfilter/nfnetlink.c index e212102b0e4a..cb41990f92e0 100644 --- a/net/netfilter/nfnetlink.c +++ b/net/netfilter/nfnetlink.c @@ -111,35 +111,6 @@ nfnetlink_find_client(u_int16_t type, const struct nfnetlink_subsystem *ss) return &ss->cb[cb_id]; } -/** - * nfnetlink_check_attributes - check and parse nfnetlink attributes - * - * subsys: nfnl subsystem for which this message is to be parsed - * nlmsghdr: netlink message to be checked/parsed - * cda: array of pointers, needs to be at least subsys->attr_count+1 big - * - */ -static int -nfnetlink_check_attributes(const struct nfnetlink_subsystem *subsys, - struct nlmsghdr *nlh, struct nlattr *cda[]) -{ - int min_len = NLMSG_SPACE(sizeof(struct nfgenmsg)); - u_int8_t cb_id = NFNL_MSG_TYPE(nlh->nlmsg_type); - u_int16_t attr_count = subsys->cb[cb_id].attr_count; - - /* check attribute lengths. */ - if (likely(nlh->nlmsg_len > min_len)) { - struct nlattr *attr = (void *)nlh + NLMSG_ALIGN(min_len); - int attrlen = nlh->nlmsg_len - NLMSG_ALIGN(min_len); - nla_parse(cda, attr_count, attr, attrlen, NULL); - } - - /* implicit: if nlmsg_len == min_len, we return 0, and an empty - * (zeroed) cda[] array. The message is valid, but empty. */ - - return 0; -} - int nfnetlink_has_listeners(unsigned int group) { return netlink_has_listeners(nfnl, group); @@ -192,15 +163,22 @@ static int nfnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) return -EINVAL; { - u_int16_t attr_count = - ss->cb[NFNL_MSG_TYPE(nlh->nlmsg_type)].attr_count; + int min_len = NLMSG_SPACE(sizeof(struct nfgenmsg)); + u_int8_t cb_id = NFNL_MSG_TYPE(nlh->nlmsg_type); + u_int16_t attr_count = ss->cb[cb_id].attr_count; struct nlattr *cda[attr_count+1]; - memset(cda, 0, sizeof(struct nlattr *) * attr_count); + if (likely(nlh->nlmsg_len >= min_len)) { + struct nlattr *attr = (void *)nlh + NLMSG_ALIGN(min_len); + int attrlen = nlh->nlmsg_len - NLMSG_ALIGN(min_len); + + err = nla_parse(cda, attr_count, attr, attrlen, + ss->cb[cb_id].policy); + if (err < 0) + return err; + } else + return -EINVAL; - err = nfnetlink_check_attributes(ss, nlh, cda); - if (err < 0) - return err; return nc->call(nfnl, skb, nlh, cda); } } -- cgit v1.2.3 From 2b5c841f2c41c023809e3b6b95a8320246cf7f5a Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Fri, 28 Sep 2007 14:40:56 -0700 Subject: [NETFILTER]: nfnetlink: kill nlattr_bad_size Signed-off-by: Patrick McHardy Signed-off-by: David S. Miller --- include/linux/netfilter/nfnetlink.h | 13 ------------- 1 file changed, 13 deletions(-) (limited to 'include/linux') diff --git a/include/linux/netfilter/nfnetlink.h b/include/linux/netfilter/nfnetlink.h index cd8fded36550..0d8424f76899 100644 --- a/include/linux/netfilter/nfnetlink.h +++ b/include/linux/netfilter/nfnetlink.h @@ -73,19 +73,6 @@ struct nfnetlink_subsystem extern int nfnetlink_subsys_register(const struct nfnetlink_subsystem *n); extern int nfnetlink_subsys_unregister(const struct nfnetlink_subsystem *n); -#define nlattr_bad_size(tb, max, cta_min) \ -({ int __i, __res = 0; \ - for (__i=1; __i <= max; __i++) { \ - if (!cta_min[__i]) \ - continue; \ - if (tb[__i] && nla_len(tb[__i]) < cta_min[__i]){ \ - __res = 1; \ - break; \ - } \ - } \ - __res; \ -}) - extern int nfnetlink_has_listeners(unsigned int group); extern int nfnetlink_send(struct sk_buff *skb, u32 pid, unsigned group, int echo); -- cgit v1.2.3 From 5faa1f4cb5a1f124f76172d775467f4a9db5b452 Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Fri, 28 Sep 2007 14:43:53 -0700 Subject: [NETFILTER]: nf_conntrack_netlink: add support to related connections This patch adds support to relate a connection to an existing master connection. This patch is used by conntrackd to correctly replicate related connections. Signed-off-by: Pablo Neira Ayuso Signed-off-by: Patrick McHardy Signed-off-by: David S. Miller --- include/linux/netfilter/nfnetlink_conntrack.h | 1 + net/netfilter/nf_conntrack_netlink.c | 43 +++++++++++++++++++++++++-- 2 files changed, 41 insertions(+), 3 deletions(-) (limited to 'include/linux') diff --git a/include/linux/netfilter/nfnetlink_conntrack.h b/include/linux/netfilter/nfnetlink_conntrack.h index d7c35039721e..4affa3fe78e0 100644 --- a/include/linux/netfilter/nfnetlink_conntrack.h +++ b/include/linux/netfilter/nfnetlink_conntrack.h @@ -36,6 +36,7 @@ enum ctattr_type { CTA_USE, CTA_ID, CTA_NAT_DST, + CTA_TUPLE_MASTER, __CTA_MAX }; #define CTA_MAX (__CTA_MAX - 1) diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c index 2abd648f7d6f..9be1826e6cdd 100644 --- a/net/netfilter/nf_conntrack_netlink.c +++ b/net/netfilter/nf_conntrack_netlink.c @@ -4,7 +4,7 @@ * (C) 2001 by Jay Schulist * (C) 2002-2006 by Harald Welte * (C) 2003 by Patrick Mchardy - * (C) 2005-2006 by Pablo Neira Ayuso + * (C) 2005-2007 by Pablo Neira Ayuso * * Initial connection tracking via netlink development funded and * generally made possible by Network Robots, Inc. (www.networkrobots.com) @@ -975,7 +975,8 @@ ctnetlink_change_conntrack(struct nf_conn *ct, struct nlattr *cda[]) static int ctnetlink_create_conntrack(struct nlattr *cda[], struct nf_conntrack_tuple *otuple, - struct nf_conntrack_tuple *rtuple) + struct nf_conntrack_tuple *rtuple, + struct nf_conn *master_ct) { struct nf_conn *ct; int err = -EINVAL; @@ -1022,6 +1023,10 @@ ctnetlink_create_conntrack(struct nlattr *cda[], rcu_assign_pointer(help->helper, helper); } + /* setup master conntrack: this is a confirmed expectation */ + if (master_ct) + ct->master = master_ct; + add_timer(&ct->timeout); nf_conntrack_hash_insert(ct); @@ -1064,10 +1069,37 @@ ctnetlink_new_conntrack(struct sock *ctnl, struct sk_buff *skb, h = __nf_conntrack_find(&rtuple, NULL); if (h == NULL) { + struct nf_conntrack_tuple master; + struct nf_conntrack_tuple_hash *master_h = NULL; + struct nf_conn *master_ct = NULL; + + if (cda[CTA_TUPLE_MASTER]) { + err = ctnetlink_parse_tuple(cda, + &master, + CTA_TUPLE_MASTER, + u3); + if (err < 0) + return err; + + master_h = __nf_conntrack_find(&master, NULL); + if (master_h == NULL) { + err = -ENOENT; + goto out_unlock; + } + master_ct = nf_ct_tuplehash_to_ctrack(master_h); + atomic_inc(&master_ct->ct_general.use); + } + write_unlock_bh(&nf_conntrack_lock); err = -ENOENT; if (nlh->nlmsg_flags & NLM_F_CREATE) - err = ctnetlink_create_conntrack(cda, &otuple, &rtuple); + err = ctnetlink_create_conntrack(cda, + &otuple, + &rtuple, + master_ct); + if (err < 0 && master_ct) + nf_ct_put(master_ct); + return err; } /* implicit 'else' */ @@ -1081,6 +1113,11 @@ ctnetlink_new_conntrack(struct sock *ctnl, struct sk_buff *skb, err = -EINVAL; goto out_unlock; } + /* can't link an existing conntrack to a master */ + if (cda[CTA_TUPLE_MASTER]) { + err = -EINVAL; + goto out_unlock; + } err = ctnetlink_change_conntrack(nf_ct_tuplehash_to_ctrack(h), cda); } -- cgit v1.2.3 From ee4411a1b1e0b679c99686629b5eab5a072ce49f Mon Sep 17 00:00:00 2001 From: Jan Engelhardt Date: Fri, 28 Sep 2007 14:46:43 -0700 Subject: [NETFILTER]: x_tables: add xt_time match This is ipt_time from POM-ng enhanced by the following: * xtables/ipv6 support * second granularity for daytime * day-of-month support (for example "match on the 15th of each month") * match against UTC or local timezone Signed-off-by: Jan Engelhardt Signed-off-by: Patrick McHardy Signed-off-by: David S. Miller --- include/linux/netfilter/xt_time.h | 25 ++++ net/netfilter/Kconfig | 14 ++ net/netfilter/Makefile | 1 + net/netfilter/xt_time.c | 269 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 309 insertions(+) create mode 100644 include/linux/netfilter/xt_time.h create mode 100644 net/netfilter/xt_time.c (limited to 'include/linux') diff --git a/include/linux/netfilter/xt_time.h b/include/linux/netfilter/xt_time.h new file mode 100644 index 000000000000..14b6df412c9f --- /dev/null +++ b/include/linux/netfilter/xt_time.h @@ -0,0 +1,25 @@ +#ifndef _XT_TIME_H +#define _XT_TIME_H 1 + +struct xt_time_info { + u_int32_t date_start; + u_int32_t date_stop; + u_int32_t daytime_start; + u_int32_t daytime_stop; + u_int32_t monthdays_match; + u_int8_t weekdays_match; + u_int8_t flags; +}; + +enum { + /* Match against local time (instead of UTC) */ + XT_TIME_LOCAL_TZ = 1 << 0, + + /* Shortcuts */ + XT_TIME_ALL_MONTHDAYS = 0xFFFFFFFE, + XT_TIME_ALL_WEEKDAYS = 0xFE, + XT_TIME_MIN_DAYTIME = 0, + XT_TIME_MAX_DAYTIME = 24 * 60 * 60 - 1, +}; + +#endif /* _XT_TIME_H */ diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig index 3599770a2473..d7a600a5720a 100644 --- a/net/netfilter/Kconfig +++ b/net/netfilter/Kconfig @@ -665,6 +665,20 @@ config NETFILTER_XT_MATCH_TCPMSS To compile it as a module, choose M here. If unsure, say N. +config NETFILTER_XT_MATCH_TIME + tristate '"time" match support' + depends on NETFILTER_XTABLES + ---help--- + This option adds a "time" match, which allows you to match based on + the packet arrival time (at the machine which netfilter is running) + on) or departure time/date (for locally generated packets). + + If you say Y here, try `iptables -m time --help` for + more information. + + If you want to compile it as a module, say M here. + If unsure, say N. + config NETFILTER_XT_MATCH_U32 tristate '"u32" match support' depends on NETFILTER_XTABLES diff --git a/net/netfilter/Makefile b/net/netfilter/Makefile index 0c054bf27973..93c58f973831 100644 --- a/net/netfilter/Makefile +++ b/net/netfilter/Makefile @@ -73,6 +73,7 @@ obj-$(CONFIG_NETFILTER_XT_MATCH_SCTP) += xt_sctp.o obj-$(CONFIG_NETFILTER_XT_MATCH_STATE) += xt_state.o obj-$(CONFIG_NETFILTER_XT_MATCH_STATISTIC) += xt_statistic.o obj-$(CONFIG_NETFILTER_XT_MATCH_STRING) += xt_string.o +obj-$(CONFIG_NETFILTER_XT_MATCH_TIME) += xt_time.o obj-$(CONFIG_NETFILTER_XT_MATCH_TCPMSS) += xt_tcpmss.o obj-$(CONFIG_NETFILTER_XT_MATCH_PHYSDEV) += xt_physdev.o obj-$(CONFIG_NETFILTER_XT_MATCH_U32) += xt_u32.o diff --git a/net/netfilter/xt_time.c b/net/netfilter/xt_time.c new file mode 100644 index 000000000000..ef48bbd93573 --- /dev/null +++ b/net/netfilter/xt_time.c @@ -0,0 +1,269 @@ +/* + * xt_time + * Copyright © Jan Engelhardt , 2007 + * + * based on ipt_time by Fabrice MARIE + * This is a module which is used for time matching + * It is using some modified code from dietlibc (localtime() function) + * that you can find at http://www.fefe.de/dietlibc/ + * This file is distributed under the terms of the GNU General Public + * License (GPL). Copies of the GPL can be obtained from gnu.org/gpl. + */ +#include +#include +#include +#include +#include +#include + +struct xtm { + u_int8_t month; /* (1-12) */ + u_int8_t monthday; /* (1-31) */ + u_int8_t weekday; /* (1-7) */ + u_int8_t hour; /* (0-23) */ + u_int8_t minute; /* (0-59) */ + u_int8_t second; /* (0-59) */ + unsigned int dse; +}; + +extern struct timezone sys_tz; /* ouch */ + +static const u_int16_t days_since_year[] = { + 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, +}; + +static const u_int16_t days_since_leapyear[] = { + 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, +}; + +/* + * Since time progresses forward, it is best to organize this array in reverse, + * to minimize lookup time. + */ +enum { + DSE_FIRST = 2039, +}; +static const u_int16_t days_since_epoch[] = { + /* 2039 - 2030 */ + 25202, 24837, 24472, 24106, 23741, 23376, 23011, 22645, 22280, 21915, + /* 2029 - 2020 */ + 21550, 21184, 20819, 20454, 20089, 19723, 19358, 18993, 18628, 18262, + /* 2019 - 2010 */ + 17897, 17532, 17167, 16801, 16436, 16071, 15706, 15340, 14975, 14610, + /* 2009 - 2000 */ + 14245, 13879, 13514, 13149, 12784, 12418, 12053, 11688, 11323, 10957, + /* 1999 - 1990 */ + 10592, 10227, 9862, 9496, 9131, 8766, 8401, 8035, 7670, 7305, + /* 1989 - 1980 */ + 6940, 6574, 6209, 5844, 5479, 5113, 4748, 4383, 4018, 3652, + /* 1979 - 1970 */ + 3287, 2922, 2557, 2191, 1826, 1461, 1096, 730, 365, 0, +}; + +static inline bool is_leap(unsigned int y) +{ + return y % 4 == 0 && (y % 100 != 0 || y % 400 == 0); +} + +/* + * Each network packet has a (nano)seconds-since-the-epoch (SSTE) timestamp. + * Since we match against days and daytime, the SSTE value needs to be + * computed back into human-readable dates. + * + * This is done in three separate functions so that the most expensive + * calculations are done last, in case a "simple match" can be found earlier. + */ +static inline unsigned int localtime_1(struct xtm *r, time_t time) +{ + unsigned int v, w; + + /* Each day has 86400s, so finding the hour/minute is actually easy. */ + v = time % 86400; + r->second = v % 60; + w = v / 60; + r->minute = w % 60; + r->hour = w / 60; + return v; +} + +static inline void localtime_2(struct xtm *r, time_t time) +{ + /* + * Here comes the rest (weekday, monthday). First, divide the SSTE + * by seconds-per-day to get the number of _days_ since the epoch. + */ + r->dse = time / 86400; + + /* 1970-01-01 (w=0) was a Thursday (4). */ + r->weekday = (4 + r->dse) % 7; +} + +static void localtime_3(struct xtm *r, time_t time) +{ + unsigned int year, i, w = r->dse; + + /* + * In each year, a certain number of days-since-the-epoch have passed. + * Find the year that is closest to said days. + * + * Consider, for example, w=21612 (2029-03-04). Loop will abort on + * dse[i] <= w, which happens when dse[i] == 21550. This implies + * year == 2009. w will then be 62. + */ + for (i = 0, year = DSE_FIRST; days_since_epoch[i] > w; + ++i, --year) + /* just loop */; + + w -= days_since_epoch[i]; + + /* + * By now we have the current year, and the day of the year. + * r->yearday = w; + * + * On to finding the month (like above). In each month, a certain + * number of days-since-New Year have passed, and find the closest + * one. + * + * Consider w=62 (in a non-leap year). Loop will abort on + * dsy[i] < w, which happens when dsy[i] == 31+28 (i == 2). + * Concludes i == 2, i.e. 3rd month => March. + * + * (A different approach to use would be to subtract a monthlength + * from w repeatedly while counting.) + */ + if (is_leap(year)) { + for (i = ARRAY_SIZE(days_since_leapyear) - 1; + i > 0 && days_since_year[i] > w; --i) + /* just loop */; + } else { + for (i = ARRAY_SIZE(days_since_year) - 1; + i > 0 && days_since_year[i] > w; --i) + /* just loop */; + } + + r->month = i + 1; + r->monthday = w - days_since_year[i] + 1; + return; +} + +static bool xt_time_match(const struct sk_buff *skb, + const struct net_device *in, + const struct net_device *out, + const struct xt_match *match, const void *matchinfo, + int offset, unsigned int protoff, bool *hotdrop) +{ + const struct xt_time_info *info = matchinfo; + unsigned int packet_time; + struct xtm current_time; + s64 stamp; + + /* + * We cannot use get_seconds() instead of __net_timestamp() here. + * Suppose you have two rules: + * 1. match before 13:00 + * 2. match after 13:00 + * If you match against processing time (get_seconds) it + * may happen that the same packet matches both rules if + * it arrived at the right moment before 13:00. + */ + if (skb->tstamp.tv64 == 0) + __net_timestamp((struct sk_buff *)skb); + + stamp = skb->tstamp.tv64; + do_div(stamp, NSEC_PER_SEC); + + if (info->flags & XT_TIME_LOCAL_TZ) + /* Adjust for local timezone */ + stamp -= 60 * sys_tz.tz_minuteswest; + + /* + * xt_time will match when _all_ of the following hold: + * - 'now' is in the global time range date_start..date_end + * - 'now' is in the monthday mask + * - 'now' is in the weekday mask + * - 'now' is in the daytime range time_start..time_end + * (and by default, libxt_time will set these so as to match) + */ + + if (stamp < info->date_start || stamp > info->date_stop) + return false; + + packet_time = localtime_1(¤t_time, stamp); + + if (info->daytime_start < info->daytime_stop) { + if (packet_time < info->daytime_start || + packet_time > info->daytime_stop) + return false; + } else { + if (packet_time < info->daytime_start && + packet_time > info->daytime_stop) + return false; + } + + localtime_2(¤t_time, stamp); + + if (!(info->weekdays_match & (1 << current_time.weekday))) + return false; + + /* Do not spend time computing monthday if all days match anyway */ + if (info->monthdays_match != XT_TIME_ALL_MONTHDAYS) { + localtime_3(¤t_time, stamp); + if (!(info->monthdays_match & (1 << current_time.monthday))) + return false; + } + + return true; +} + +static bool xt_time_check(const char *tablename, const void *ip, + const struct xt_match *match, void *matchinfo, + unsigned int hook_mask) +{ + struct xt_time_info *info = matchinfo; + + if (info->daytime_start > XT_TIME_MAX_DAYTIME || + info->daytime_stop > XT_TIME_MAX_DAYTIME) { + printk(KERN_WARNING "xt_time: invalid argument - start or " + "stop time greater than 23:59:59\n"); + return false; + } + + return true; +} + +static struct xt_match xt_time_reg[] __read_mostly = { + { + .name = "time", + .family = AF_INET, + .match = xt_time_match, + .matchsize = sizeof(struct xt_time_info), + .checkentry = xt_time_check, + .me = THIS_MODULE, + }, + { + .name = "time", + .family = AF_INET6, + .match = xt_time_match, + .matchsize = sizeof(struct xt_time_info), + .checkentry = xt_time_check, + .me = THIS_MODULE, + }, +}; + +static int __init xt_time_init(void) +{ + return xt_register_matches(xt_time_reg, ARRAY_SIZE(xt_time_reg)); +} + +static void __exit xt_time_exit(void) +{ + xt_unregister_matches(xt_time_reg, ARRAY_SIZE(xt_time_reg)); +} + +module_init(xt_time_init); +module_exit(xt_time_exit); +MODULE_AUTHOR("Jan Engelhardt "); +MODULE_DESCRIPTION("netfilter time match"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("ipt_time"); +MODULE_ALIAS("ip6t_time"); -- cgit v1.2.3 From 7c32f470f4f6a0fdc6944cefcd22f288e59a0ae2 Mon Sep 17 00:00:00 2001 From: Vitaly Bordug Date: Fri, 10 Aug 2007 14:05:16 -0700 Subject: PHY fixed driver: rework release path and update phy_id notation device_bind_driver() error code returning has been fixed. release() function has been written, so that to free resources in correct way; the release path is now clean. Before the rework, it used to cause Device 'fixed@100:1' does not have a release() function, it is broken and must be fixed. BUG: at drivers/base/core.c:104 device_release() Call Trace: [] kobject_cleanup+0x53/0x7e [] kobject_release+0x0/0x9 [] kref_put+0x74/0x81 [] fixed_mdio_register_device+0x230/0x265 [] fixed_init+0x1f/0x35 [] init+0x147/0x2fb [] schedule_tail+0x36/0x92 [] child_rip+0xa/0x12 [] acpi_ds_init_one_object+0x0/0x83 [] init+0x0/0x2fb [] child_rip+0x0/0x12 Also changed the notation of the fixed phy definition on mdio bus to the form of + to make it able to be used by gianfar and ucc_geth that define phy_id strictly as "%d:%d" and cleaned up the whitespace issues. Signed-off-by: Vitaly Bordug Signed-off-by: Andrew Morton Signed-off-by: Jeff Garzik --- drivers/net/phy/Kconfig | 14 +++ drivers/net/phy/fixed.c | 310 +++++++++++++++++++++++----------------------- include/linux/phy_fixed.h | 38 ++++++ 3 files changed, 207 insertions(+), 155 deletions(-) create mode 100644 include/linux/phy_fixed.h (limited to 'include/linux') diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig index dd09011c7ee5..432c210513be 100644 --- a/drivers/net/phy/Kconfig +++ b/drivers/net/phy/Kconfig @@ -76,4 +76,18 @@ config FIXED_MII_100_FDX bool "Emulation for 100M Fdx fixed PHY behavior" depends on FIXED_PHY +config FIXED_MII_1000_FDX + bool "Emulation for 1000M Fdx fixed PHY behavior" + depends on FIXED_PHY + +config FIXED_MII_AMNT + int "Number of emulated PHYs to allocate " + depends on FIXED_PHY + default "1" + ---help--- + Sometimes it is required to have several independent emulated + PHYs on the bus (in case of multi-eth but phy-less HW for instance). + This control will have specified number allocated for each fixed + PHY type enabled. + endif # PHYLIB diff --git a/drivers/net/phy/fixed.c b/drivers/net/phy/fixed.c index bb966911a137..56191822fa26 100644 --- a/drivers/net/phy/fixed.c +++ b/drivers/net/phy/fixed.c @@ -30,53 +30,31 @@ #include #include #include +#include #include #include #include -#define MII_REGS_NUM 7 - -/* - The idea is to emulate normal phy behavior by responding with - pre-defined values to mii BMCR read, so that read_status hook could - take all the needed info. -*/ - -struct fixed_phy_status { - u8 link; - u16 speed; - u8 duplex; -}; - -/*----------------------------------------------------------------------------- - * Private information hoder for mii_bus - *-----------------------------------------------------------------------------*/ -struct fixed_info { - u16 *regs; - u8 regs_num; - struct fixed_phy_status phy_status; - struct phy_device *phydev; /* pointer to the container */ - /* link & speed cb */ - int(*link_update)(struct net_device*, struct fixed_phy_status*); - -}; +/* we need to track the allocated pointers in order to free them on exit */ +static struct fixed_info *fixed_phy_ptrs[CONFIG_FIXED_MII_AMNT*MAX_PHY_AMNT]; /*----------------------------------------------------------------------------- * If something weird is required to be done with link/speed, * network driver is able to assign a function to implement this. * May be useful for PHY's that need to be software-driven. *-----------------------------------------------------------------------------*/ -int fixed_mdio_set_link_update(struct phy_device* phydev, - int(*link_update)(struct net_device*, struct fixed_phy_status*)) +int fixed_mdio_set_link_update(struct phy_device *phydev, + int (*link_update) (struct net_device *, + struct fixed_phy_status *)) { struct fixed_info *fixed; - if(link_update == NULL) + if (link_update == NULL) return -EINVAL; - if(phydev) { - if(phydev->bus) { + if (phydev) { + if (phydev->bus) { fixed = phydev->bus->priv; fixed->link_update = link_update; return 0; @@ -84,54 +62,64 @@ int fixed_mdio_set_link_update(struct phy_device* phydev, } return -EINVAL; } + EXPORT_SYMBOL(fixed_mdio_set_link_update); +struct fixed_info *fixed_mdio_get_phydev (int phydev_ind) +{ + if (phydev_ind >= MAX_PHY_AMNT) + return NULL; + return fixed_phy_ptrs[phydev_ind]; +} + +EXPORT_SYMBOL(fixed_mdio_get_phydev); + /*----------------------------------------------------------------------------- * This is used for updating internal mii regs from the status *-----------------------------------------------------------------------------*/ -#if defined(CONFIG_FIXED_MII_100_FDX) || defined(CONFIG_FIXED_MII_10_FDX) +#if defined(CONFIG_FIXED_MII_100_FDX) || defined(CONFIG_FIXED_MII_10_FDX) || defined(CONFIG_FIXED_MII_1000_FDX) static int fixed_mdio_update_regs(struct fixed_info *fixed) { u16 *regs = fixed->regs; u16 bmsr = 0; u16 bmcr = 0; - if(!regs) { + if (!regs) { printk(KERN_ERR "%s: regs not set up", __FUNCTION__); return -EINVAL; } - if(fixed->phy_status.link) + if (fixed->phy_status.link) bmsr |= BMSR_LSTATUS; - if(fixed->phy_status.duplex) { + if (fixed->phy_status.duplex) { bmcr |= BMCR_FULLDPLX; - switch ( fixed->phy_status.speed ) { + switch (fixed->phy_status.speed) { case 100: bmsr |= BMSR_100FULL; bmcr |= BMCR_SPEED100; - break; + break; case 10: bmsr |= BMSR_10FULL; - break; + break; } } else { - switch ( fixed->phy_status.speed ) { + switch (fixed->phy_status.speed) { case 100: bmsr |= BMSR_100HALF; bmcr |= BMCR_SPEED100; - break; + break; case 10: bmsr |= BMSR_100HALF; - break; + break; } } - regs[MII_BMCR] = bmcr; - regs[MII_BMSR] = bmsr | 0x800; /*we are always capable of 10 hdx*/ + regs[MII_BMCR] = bmcr; + regs[MII_BMSR] = bmsr | 0x800; /*we are always capable of 10 hdx */ return 0; } @@ -141,29 +129,30 @@ static int fixed_mii_read(struct mii_bus *bus, int phy_id, int location) struct fixed_info *fixed = bus->priv; /* if user has registered link update callback, use it */ - if(fixed->phydev) - if(fixed->phydev->attached_dev) { - if(fixed->link_update) { + if (fixed->phydev) + if (fixed->phydev->attached_dev) { + if (fixed->link_update) { fixed->link_update(fixed->phydev->attached_dev, - &fixed->phy_status); + &fixed->phy_status); fixed_mdio_update_regs(fixed); } - } + } if ((unsigned int)location >= fixed->regs_num) return -1; return fixed->regs[location]; } -static int fixed_mii_write(struct mii_bus *bus, int phy_id, int location, u16 val) +static int fixed_mii_write(struct mii_bus *bus, int phy_id, int location, + u16 val) { - /* do nothing for now*/ + /* do nothing for now */ return 0; } static int fixed_mii_reset(struct mii_bus *bus) { - /*nothing here - no way/need to reset it*/ + /*nothing here - no way/need to reset it */ return 0; } #endif @@ -171,8 +160,8 @@ static int fixed_mii_reset(struct mii_bus *bus) static int fixed_config_aneg(struct phy_device *phydev) { /* :TODO:03/13/2006 09:45:37 PM:: - The full autoneg funcionality can be emulated, - but no need to have anything here for now + The full autoneg funcionality can be emulated, + but no need to have anything here for now */ return 0; } @@ -182,59 +171,79 @@ static int fixed_config_aneg(struct phy_device *phydev) * match will never return true... *-----------------------------------------------------------------------------*/ static struct phy_driver fixed_mdio_driver = { - .name = "Fixed PHY", - .features = PHY_BASIC_FEATURES, - .config_aneg = fixed_config_aneg, - .read_status = genphy_read_status, - .driver = { .owner = THIS_MODULE,}, + .name = "Fixed PHY", +#ifdef CONFIG_FIXED_MII_1000_FDX + .features = PHY_GBIT_FEATURES, +#else + .features = PHY_BASIC_FEATURES, +#endif + .config_aneg = fixed_config_aneg, + .read_status = genphy_read_status, + .driver = { .owner = THIS_MODULE, }, }; +static void fixed_mdio_release(struct device *dev) +{ + struct phy_device *phydev = container_of(dev, struct phy_device, dev); + struct mii_bus *bus = phydev->bus; + struct fixed_info *fixed = bus->priv; + + kfree(phydev); + kfree(bus->dev); + kfree(bus); + kfree(fixed->regs); + kfree(fixed); +} + /*----------------------------------------------------------------------------- * This func is used to create all the necessary stuff, bind * the fixed phy driver and register all it on the mdio_bus_type. - * speed is either 10 or 100, duplex is boolean. + * speed is either 10 or 100 or 1000, duplex is boolean. * number is used to create multiple fixed PHYs, so that several devices can * utilize them simultaneously. + * + * The device on mdio bus will look like [bus_id]:[phy_id], + * bus_id = number + * phy_id = speed+duplex. *-----------------------------------------------------------------------------*/ -#if defined(CONFIG_FIXED_MII_100_FDX) || defined(CONFIG_FIXED_MII_10_FDX) -static int fixed_mdio_register_device(int number, int speed, int duplex) +#if defined(CONFIG_FIXED_MII_100_FDX) || defined(CONFIG_FIXED_MII_10_FDX) || defined(CONFIG_FIXED_MII_1000_FDX) +struct fixed_info *fixed_mdio_register_device( + int bus_id, int speed, int duplex, u8 phy_id) { struct mii_bus *new_bus; struct fixed_info *fixed; struct phy_device *phydev; - int err = 0; + int err; - struct device* dev = kzalloc(sizeof(struct device), GFP_KERNEL); + struct device *dev = kzalloc(sizeof(struct device), GFP_KERNEL); - if (NULL == dev) - return -ENOMEM; + if (dev == NULL) + goto err_dev_alloc; new_bus = kzalloc(sizeof(struct mii_bus), GFP_KERNEL); - if (NULL == new_bus) { - kfree(dev); - return -ENOMEM; - } + if (new_bus == NULL) + goto err_bus_alloc; + fixed = kzalloc(sizeof(struct fixed_info), GFP_KERNEL); - if (NULL == fixed) { - kfree(dev); - kfree(new_bus); - return -ENOMEM; - } + if (fixed == NULL) + goto err_fixed_alloc; + + fixed->regs = kzalloc(MII_REGS_NUM * sizeof(int), GFP_KERNEL); + if (NULL == fixed->regs) + goto err_fixed_regs_alloc; - fixed->regs = kzalloc(MII_REGS_NUM*sizeof(int), GFP_KERNEL); fixed->regs_num = MII_REGS_NUM; fixed->phy_status.speed = speed; fixed->phy_status.duplex = duplex; fixed->phy_status.link = 1; - new_bus->name = "Fixed MII Bus", - new_bus->read = &fixed_mii_read, - new_bus->write = &fixed_mii_write, - new_bus->reset = &fixed_mii_reset, - - /*set up workspace*/ + new_bus->name = "Fixed MII Bus"; + new_bus->read = &fixed_mii_read; + new_bus->write = &fixed_mii_write; + new_bus->reset = &fixed_mii_reset; + /*set up workspace */ fixed_mdio_update_regs(fixed); new_bus->priv = fixed; @@ -243,119 +252,110 @@ static int fixed_mdio_register_device(int number, int speed, int duplex) /* create phy_device and register it on the mdio bus */ phydev = phy_device_create(new_bus, 0, 0); + if (phydev == NULL) + goto err_phy_dev_create; /* - Put the phydev pointer into the fixed pack so that bus read/write code could - be able to access for instance attached netdev. Well it doesn't have to do - so, only in case of utilizing user-specified link-update... + * Put the phydev pointer into the fixed pack so that bus read/write + * code could be able to access for instance attached netdev. Well it + * doesn't have to do so, only in case of utilizing user-specified + * link-update... */ - fixed->phydev = phydev; - if(NULL == phydev) { - err = -ENOMEM; - goto device_create_fail; - } + fixed->phydev = phydev; + phydev->speed = speed; + phydev->duplex = duplex; phydev->irq = PHY_IGNORE_INTERRUPT; phydev->dev.bus = &mdio_bus_type; - if(number) - snprintf(phydev->dev.bus_id, BUS_ID_SIZE, - "fixed_%d@%d:%d", number, speed, duplex); - else - snprintf(phydev->dev.bus_id, BUS_ID_SIZE, - "fixed@%d:%d", speed, duplex); - phydev->bus = new_bus; + snprintf(phydev->dev.bus_id, BUS_ID_SIZE, + PHY_ID_FMT, bus_id, phy_id); - err = device_register(&phydev->dev); - if(err) { - printk(KERN_ERR "Phy %s failed to register\n", - phydev->dev.bus_id); - goto bus_register_fail; - } + phydev->bus = new_bus; - /* - the mdio bus has phy_id match... In order not to do it - artificially, we are binding the driver here by hand; - it will be the same for all the fixed phys anyway. - */ phydev->dev.driver = &fixed_mdio_driver.driver; - + phydev->dev.release = fixed_mdio_release; err = phydev->dev.driver->probe(&phydev->dev); - if(err < 0) { - printk(KERN_ERR "Phy %s: problems with fixed driver\n",phydev->dev.bus_id); - goto probe_fail; + if (err < 0) { + printk(KERN_ERR "Phy %s: problems with fixed driver\n", + phydev->dev.bus_id); + goto err_out; } + err = device_register(&phydev->dev); + if (err) { + printk(KERN_ERR "Phy %s failed to register\n", + phydev->dev.bus_id); + goto err_out; + } + //phydev->state = PHY_RUNNING; /* make phy go up quick, but in 10Mbit/HDX + return fixed; - err = device_bind_driver(&phydev->dev); - if (err) - goto probe_fail; - - return 0; - -probe_fail: - device_unregister(&phydev->dev); -bus_register_fail: +err_out: kfree(phydev); -device_create_fail: - kfree(dev); - kfree(new_bus); +err_phy_dev_create: + kfree(fixed->regs); +err_fixed_regs_alloc: kfree(fixed); +err_fixed_alloc: + kfree(new_bus); +err_bus_alloc: + kfree(dev); +err_dev_alloc: + + return NULL; - return err; } #endif - MODULE_DESCRIPTION("Fixed PHY device & driver for PAL"); MODULE_AUTHOR("Vitaly Bordug"); MODULE_LICENSE("GPL"); static int __init fixed_init(void) { -#if 0 - int ret; - int duplex = 0; -#endif - - /* register on the bus... Not expected to be matched with anything there... */ + int cnt = 0; + int i; +/* register on the bus... Not expected to be matched + * with anything there... + * + */ phy_driver_register(&fixed_mdio_driver); - /* So let the fun begin... - We will create several mdio devices here, and will bound the upper - driver to them. - - Then the external software can lookup the phy bus by searching - fixed@speed:duplex, e.g. fixed@100:1, to be connected to the - virtual 100M Fdx phy. - - In case several virtual PHYs required, the bus_id will be in form - fixed_@:, which make it able even to define - driver-specific link control callback, if for instance PHY is completely - SW-driven. - - */ - -#ifdef CONFIG_FIXED_MII_DUPLEX -#if 0 - duplex = 1; -#endif +/* We will create several mdio devices here, and will bound the upper + * driver to them. + * + * Then the external software can lookup the phy bus by searching + * for 0:101, to be connected to the virtual 100M Fdx phy. + * + * In case several virtual PHYs required, the bus_id will be in form + * [num]:[duplex]+[speed], which make it able even to define + * driver-specific link control callback, if for instance PHY is + * completely SW-driven. + */ + for (i=1; i <= CONFIG_FIXED_MII_AMNT; i++) { +#ifdef CONFIG_FIXED_MII_1000_FDX + fixed_phy_ptrs[cnt++] = fixed_mdio_register_device(0, 1000, 1, i); #endif - #ifdef CONFIG_FIXED_MII_100_FDX - fixed_mdio_register_device(0, 100, 1); + fixed_phy_ptrs[cnt++] = fixed_mdio_register_device(1, 100, 1, i); #endif - #ifdef CONFIG_FIXED_MII_10_FDX - fixed_mdio_register_device(0, 10, 1); + fixed_phy_ptrs[cnt++] = fixed_mdio_register_device(2, 10, 1, i); #endif + } + return 0; } static void __exit fixed_exit(void) { + int i; + phy_driver_unregister(&fixed_mdio_driver); - /* :WARNING:02/18/2006 04:32:40 AM:: Cleanup all the created stuff */ + for (i=0; i < MAX_PHY_AMNT; i++) + if ( fixed_phy_ptrs[i] ) + device_unregister(&fixed_phy_ptrs[i]->phydev->dev); } module_init(fixed_init); diff --git a/include/linux/phy_fixed.h b/include/linux/phy_fixed.h new file mode 100644 index 000000000000..04ba70d49fb8 --- /dev/null +++ b/include/linux/phy_fixed.h @@ -0,0 +1,38 @@ +#ifndef __PHY_FIXED_H +#define __PHY_FIXED_H + +#define MII_REGS_NUM 29 + +/* max number of virtual phy stuff */ +#define MAX_PHY_AMNT 10 +/* + The idea is to emulate normal phy behavior by responding with + pre-defined values to mii BMCR read, so that read_status hook could + take all the needed info. +*/ + +struct fixed_phy_status { + u8 link; + u16 speed; + u8 duplex; +}; + +/*----------------------------------------------------------------------------- + * Private information hoder for mii_bus + *-----------------------------------------------------------------------------*/ +struct fixed_info { + u16 *regs; + u8 regs_num; + struct fixed_phy_status phy_status; + struct phy_device *phydev; /* pointer to the container */ + /* link & speed cb */ + int (*link_update) (struct net_device *, struct fixed_phy_status *); + +}; + + +int fixed_mdio_set_link_update(struct phy_device *, + int (*link_update) (struct net_device *, struct fixed_phy_status *)); +struct fixed_info *fixed_mdio_get_phydev (int phydev_ind); + +#endif /* __PHY_FIXED_H */ -- cgit v1.2.3 From 0ac49527318bc388a881152d60f49d7951606024 Mon Sep 17 00:00:00 2001 From: "Maciej W. Rozycki" Date: Fri, 28 Sep 2007 22:42:14 -0700 Subject: PHYLIB: IRQ event workqueue handling fixes Keep track of disable_irq_nosync() invocations and call enable_irq() the right number of times if work has been cancelled that would include them. Now that the call to flush_work_keventd() (problematic because of rtnl_mutex being held) has been replaced by cancel_work_sync() another issue has arisen and been left unresolved. As the MDIO bus cannot be accessed from the interrupt context the PHY interrupt handler uses disable_irq_nosync() to prevent from looping and schedules some work to be done as a softirq, which, apart from handling the state change of the originating PHY, is responsible for reenabling the interrupt. Now if the interrupt line is shared by another device and a call to the softirq handler has been cancelled, that call to enable_irq() never happens and the other device cannot use its interrupt anymore as its stuck disabled. I decided to use a counter rather than a flag because there may be more than one call to phy_change() cancelled in the queue -- a real one and a fake one triggered by free_irq() if DEBUG_SHIRQ is used, if nothing else. Therefore because of its nesting property enable_irq() has to be called the right number of times to match the number disable_irq_nosync() was called and restore the original state. This DEBUG_SHIRQ feature is also the reason why free_irq() has to be called before cancel_work_sync(). While at it I updated the comment about phy_stop_interrupts() being called from `keventd' -- this is no longer relevant as the use of cancel_work_sync() makes such an approach unnecessary. OTOH a similar comment referring to flush_scheduled_work() in phy_stop() still applies as using cancel_work_sync() there would be dangerous. Checked with checkpatch.pl and at the run time (with and without DEBUG_SHIRQ). Signed-off-by: Maciej W. Rozycki Cc: Andy Fleming Cc: Jeff Garzik Signed-off-by: Andrew Morton Signed-off-by: Jeff Garzik --- drivers/net/phy/phy.c | 24 +++++++++++++++++++----- include/linux/phy.h | 3 +++ 2 files changed, 22 insertions(+), 5 deletions(-) (limited to 'include/linux') diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c index 4da993dfcfd8..5a314edc2744 100644 --- a/drivers/net/phy/phy.c +++ b/drivers/net/phy/phy.c @@ -7,7 +7,7 @@ * Author: Andy Fleming * * Copyright (c) 2004 Freescale Semiconductor, Inc. - * Copyright (c) 2006 Maciej W. Rozycki + * Copyright (c) 2006, 2007 Maciej W. Rozycki * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -35,6 +35,7 @@ #include #include +#include #include #include #include @@ -562,6 +563,7 @@ static irqreturn_t phy_interrupt(int irq, void *phy_dat) * queue will write the PHY to disable and clear the * interrupt, and then reenable the irq line. */ disable_irq_nosync(irq); + atomic_inc(&phydev->irq_disable); schedule_work(&phydev->phy_queue); @@ -632,6 +634,7 @@ int phy_start_interrupts(struct phy_device *phydev) INIT_WORK(&phydev->phy_queue, phy_change); + atomic_set(&phydev->irq_disable, 0); if (request_irq(phydev->irq, phy_interrupt, IRQF_SHARED, "phy_interrupt", @@ -662,13 +665,22 @@ int phy_stop_interrupts(struct phy_device *phydev) if (err) phy_error(phydev); + free_irq(phydev->irq, phydev); + /* - * Finish any pending work; we might have been scheduled to be called - * from keventd ourselves, but cancel_work_sync() handles that. + * Cannot call flush_scheduled_work() here as desired because + * of rtnl_lock(), but we do not really care about what would + * be done, except from enable_irq(), so cancel any work + * possibly pending and take care of the matter below. */ cancel_work_sync(&phydev->phy_queue); - - free_irq(phydev->irq, phydev); + /* + * If work indeed has been cancelled, disable_irq() will have + * been left unbalanced from phy_interrupt() and enable_irq() + * has to be called so that other devices on the line work. + */ + while (atomic_dec_return(&phydev->irq_disable) >= 0) + enable_irq(phydev->irq); return err; } @@ -695,6 +707,7 @@ static void phy_change(struct work_struct *work) phydev->state = PHY_CHANGELINK; spin_unlock_bh(&phydev->lock); + atomic_dec(&phydev->irq_disable); enable_irq(phydev->irq); /* Reenable interrupts */ @@ -708,6 +721,7 @@ static void phy_change(struct work_struct *work) irq_enable_err: disable_irq(phydev->irq); + atomic_inc(&phydev->irq_disable); phy_err: phy_error(phydev); } diff --git a/include/linux/phy.h b/include/linux/phy.h index 2a659789f9ca..f0742b6aaa64 100644 --- a/include/linux/phy.h +++ b/include/linux/phy.h @@ -25,6 +25,8 @@ #include #include +#include + #define PHY_BASIC_FEATURES (SUPPORTED_10baseT_Half | \ SUPPORTED_10baseT_Full | \ SUPPORTED_100baseT_Half | \ @@ -281,6 +283,7 @@ struct phy_device { /* Interrupt and Polling infrastructure */ struct work_struct phy_queue; struct timer_list phy_timer; + atomic_t irq_disable; spinlock_t lock; -- cgit v1.2.3 From 89e536a190f90d038bae7905a0c582cb7089b739 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Fri, 28 Sep 2007 22:42:16 -0700 Subject: ax88796: add 93cx6 eeprom support Hook up the 93cx6 eeprom code to the ax88796 driver and modify the ax88796 driver to read out the mac address from the eeprom. We need this for the ax88796 on certain SuperH boards. The pin configuration used to connect the eeprom to the ax88796 on these boards is the same as pointed out by the ax88796 datasheet, so we can probably reuse this code for multiple platforms in the future. Signed-off-by: Magnus Damm Cc: Ben Dooks Cc: Paul Mundt Signed-off-by: Andrew Morton Signed-off-by: Jeff Garzik --- drivers/net/Kconfig | 7 +++++++ drivers/net/ax88796.c | 49 ++++++++++++++++++++++++++++++++++++++++++++ include/linux/eeprom_93cx6.h | 3 ++- include/net/ax88796.h | 1 + 4 files changed, 59 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 9ff1cf46eaee..45f6cf531566 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -240,6 +240,13 @@ config AX88796 AX88796 driver, using platform bus to provide chip detection and resources +config AX88796_93CX6 + bool "ASIX AX88796 external 93CX6 eeprom support" + depends on AX88796 + select EEPROM_93CX6 + help + Select this if your platform comes with an external 93CX6 eeprom. + config MACE tristate "MACE (Power Mac ethernet) support" depends on PPC_PMAC && PPC32 diff --git a/drivers/net/ax88796.c b/drivers/net/ax88796.c index 90e0734e6037..9fe0517cf893 100644 --- a/drivers/net/ax88796.c +++ b/drivers/net/ax88796.c @@ -24,6 +24,7 @@ #include #include #include +#include #include @@ -582,6 +583,37 @@ static const struct ethtool_ops ax_ethtool_ops = { .get_link = ax_get_link, }; +#ifdef CONFIG_AX88796_93CX6 +static void ax_eeprom_register_read(struct eeprom_93cx6 *eeprom) +{ + struct ei_device *ei_local = eeprom->data; + u8 reg = ei_inb(ei_local->mem + AX_MEMR); + + eeprom->reg_data_in = reg & AX_MEMR_EEI; + eeprom->reg_data_out = reg & AX_MEMR_EEO; /* Input pin */ + eeprom->reg_data_clock = reg & AX_MEMR_EECLK; + eeprom->reg_chip_select = reg & AX_MEMR_EECS; +} + +static void ax_eeprom_register_write(struct eeprom_93cx6 *eeprom) +{ + struct ei_device *ei_local = eeprom->data; + u8 reg = ei_inb(ei_local->mem + AX_MEMR); + + reg &= ~(AX_MEMR_EEI | AX_MEMR_EECLK | AX_MEMR_EECS); + + if (eeprom->reg_data_in) + reg |= AX_MEMR_EEI; + if (eeprom->reg_data_clock) + reg |= AX_MEMR_EECLK; + if (eeprom->reg_chip_select) + reg |= AX_MEMR_EECS; + + ei_outb(reg, ei_local->mem + AX_MEMR); + udelay(10); +} +#endif + /* setup code */ static void ax_initial_setup(struct net_device *dev, struct ei_device *ei_local) @@ -640,6 +672,23 @@ static int ax_init_dev(struct net_device *dev, int first_init) memcpy(dev->dev_addr, SA_prom, 6); } +#ifdef CONFIG_AX88796_93CX6 + if (first_init && ax->plat->flags & AXFLG_HAS_93CX6) { + unsigned char mac_addr[6]; + struct eeprom_93cx6 eeprom; + + eeprom.data = ei_local; + eeprom.register_read = ax_eeprom_register_read; + eeprom.register_write = ax_eeprom_register_write; + eeprom.width = PCI_EEPROM_WIDTH_93C56; + + eeprom_93cx6_multiread(&eeprom, 0, + (__le16 __force *)mac_addr, + sizeof(mac_addr) >> 1); + + memcpy(dev->dev_addr, mac_addr, 6); + } +#endif if (ax->plat->wordlength == 2) { /* We must set the 8390 for word mode. */ ei_outb(ax->plat->dcr_val, ei_local->mem + EN0_DCFG); diff --git a/include/linux/eeprom_93cx6.h b/include/linux/eeprom_93cx6.h index d774b7778c91..a55c873e8b66 100644 --- a/include/linux/eeprom_93cx6.h +++ b/include/linux/eeprom_93cx6.h @@ -21,13 +21,14 @@ /* Module: eeprom_93cx6 Abstract: EEPROM reader datastructures for 93cx6 chipsets. - Supported chipsets: 93c46 & 93c66. + Supported chipsets: 93c46, 93c56 and 93c66. */ /* * EEPROM operation defines. */ #define PCI_EEPROM_WIDTH_93C46 6 +#define PCI_EEPROM_WIDTH_93C56 8 #define PCI_EEPROM_WIDTH_93C66 8 #define PCI_EEPROM_WIDTH_OPCODE 3 #define PCI_EEPROM_WRITE_OPCODE 0x05 diff --git a/include/net/ax88796.h b/include/net/ax88796.h index ee786a043b3d..51329dae44e6 100644 --- a/include/net/ax88796.h +++ b/include/net/ax88796.h @@ -14,6 +14,7 @@ #define AXFLG_HAS_EEPROM (1<<0) #define AXFLG_MAC_FROMDEV (1<<1) /* device already has MAC */ +#define AXFLG_HAS_93CX6 (1<<2) /* use eeprom_93cx6 driver */ struct ax_plat_data { unsigned int flags; -- cgit v1.2.3 From 8336793baf962163c9fab5a3f39614295fdbab27 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Sun, 30 Sep 2007 17:56:49 -0700 Subject: [ZLIB]: Move bnx2 driver gzip unpacker into zlib. Signed-off-by: Denys Vlasenko Acked-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/bnx2.c | 48 +++-------------------------------- include/linux/zlib.h | 6 ++++- lib/zlib_inflate/inffast.c | 18 +++++++------- lib/zlib_inflate/inflate.c | 55 ++++++++++++++++++++++++++++++++++++++--- lib/zlib_inflate/inflate_syms.c | 1 + 5 files changed, 69 insertions(+), 59 deletions(-) (limited to 'include/linux') diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c index 73d4a579790c..6d6ea56fe384 100644 --- a/drivers/net/bnx2.c +++ b/drivers/net/bnx2.c @@ -2761,48 +2761,6 @@ bnx2_set_rx_mode(struct net_device *dev) spin_unlock_bh(&bp->phy_lock); } -/* To be moved to generic lib/ */ -static int -bnx2_gunzip(void *gunzip_buf, unsigned sz, u8 *zbuf, int len) -{ - struct z_stream_s *strm; - int rc; - - /* gzip header (1f,8b,08... 10 bytes total + possible asciz filename) - * is stripped */ - - rc = -ENOMEM; - strm = kmalloc(sizeof(*strm), GFP_KERNEL); - if (strm == NULL) - goto gunzip_nomem2; - strm->workspace = kmalloc(zlib_inflate_workspacesize(), GFP_KERNEL); - if (strm->workspace == NULL) - goto gunzip_nomem3; - - strm->next_in = zbuf; - strm->avail_in = len; - strm->next_out = gunzip_buf; - strm->avail_out = sz; - - rc = zlib_inflateInit2(strm, -MAX_WBITS); - if (rc == Z_OK) { - rc = zlib_inflate(strm, Z_FINISH); - /* after Z_FINISH, only Z_STREAM_END is "we unpacked it all" */ - if (rc == Z_STREAM_END) - rc = sz - strm->avail_out; - else - rc = -EINVAL; - zlib_inflateEnd(strm); - } else - rc = -EINVAL; - - kfree(strm->workspace); -gunzip_nomem3: - kfree(strm); -gunzip_nomem2: - return rc; -} - static void load_rv2p_fw(struct bnx2 *bp, u32 *rv2p_code, u32 rv2p_code_len, u32 rv2p_proc) @@ -2858,7 +2816,7 @@ load_cpu_fw(struct bnx2 *bp, struct cpu_reg *cpu_reg, struct fw_info *fw) text = vmalloc(FW_BUF_SIZE); if (!text) return -ENOMEM; - rc = bnx2_gunzip(text, FW_BUF_SIZE, fw->gz_text, fw->gz_text_len); + rc = zlib_inflate_blob(text, FW_BUF_SIZE, fw->gz_text, fw->gz_text_len); if (rc < 0) { vfree(text); return rc; @@ -2935,14 +2893,14 @@ bnx2_init_cpus(struct bnx2 *bp) text = vmalloc(FW_BUF_SIZE); if (!text) return -ENOMEM; - rc = bnx2_gunzip(text, FW_BUF_SIZE, bnx2_rv2p_proc1, sizeof(bnx2_rv2p_proc1)); + rc = zlib_inflate_blob(text, FW_BUF_SIZE, bnx2_rv2p_proc1, sizeof(bnx2_rv2p_proc1)); if (rc < 0) { vfree(text); goto init_cpu_err; } load_rv2p_fw(bp, text, rc /* == len */, RV2P_PROC1); - rc = bnx2_gunzip(text, FW_BUF_SIZE, bnx2_rv2p_proc2, sizeof(bnx2_rv2p_proc2)); + rc = zlib_inflate_blob(text, FW_BUF_SIZE, bnx2_rv2p_proc2, sizeof(bnx2_rv2p_proc2)); if (rc < 0) { vfree(text); goto init_cpu_err; diff --git a/include/linux/zlib.h b/include/linux/zlib.h index 9e3192a7dc6f..40c49cb3eb51 100644 --- a/include/linux/zlib.h +++ b/include/linux/zlib.h @@ -82,7 +82,7 @@ struct internal_state; typedef struct z_stream_s { - Byte *next_in; /* next input byte */ + const Byte *next_in; /* next input byte */ uInt avail_in; /* number of bytes available at next_in */ uLong total_in; /* total nb of input bytes read so far */ @@ -699,4 +699,8 @@ extern int zlib_inflateInit2(z_streamp strm, int windowBits); struct internal_state {int dummy;}; /* hack for buggy compilers */ #endif +/* Utility function: initialize zlib, unpack binary blob, clean up zlib, + * return len or negative error code. */ +extern int zlib_inflate_blob(void *dst, unsigned dst_sz, const void *src, unsigned src_sz); + #endif /* _ZLIB_H */ diff --git a/lib/zlib_inflate/inffast.c b/lib/zlib_inflate/inffast.c index d84560c076d8..8550b0c05d00 100644 --- a/lib/zlib_inflate/inffast.c +++ b/lib/zlib_inflate/inffast.c @@ -69,22 +69,22 @@ void inflate_fast(z_streamp strm, unsigned start) { struct inflate_state *state; - unsigned char *in; /* local strm->next_in */ - unsigned char *last; /* while in < last, enough input available */ - unsigned char *out; /* local strm->next_out */ - unsigned char *beg; /* inflate()'s initial strm->next_out */ - unsigned char *end; /* while out < end, enough space available */ + const unsigned char *in; /* local strm->next_in */ + const unsigned char *last; /* while in < last, enough input available */ + unsigned char *out; /* local strm->next_out */ + unsigned char *beg; /* inflate()'s initial strm->next_out */ + unsigned char *end; /* while out < end, enough space available */ #ifdef INFLATE_STRICT unsigned dmax; /* maximum distance from zlib header */ #endif unsigned wsize; /* window size or zero if not using window */ unsigned whave; /* valid bytes in the window */ unsigned write; /* window write index */ - unsigned char *window; /* allocated sliding window, if wsize != 0 */ + unsigned char *window; /* allocated sliding window, if wsize != 0 */ unsigned long hold; /* local strm->hold */ unsigned bits; /* local strm->bits */ - code const *lcode; /* local strm->lencode */ - code const *dcode; /* local strm->distcode */ + code const *lcode; /* local strm->lencode */ + code const *dcode; /* local strm->distcode */ unsigned lmask; /* mask for first level of length codes */ unsigned dmask; /* mask for first level of distance codes */ code this; /* retrieved table entry */ @@ -92,7 +92,7 @@ void inflate_fast(z_streamp strm, unsigned start) /* window position, window bytes to copy */ unsigned len; /* match length, unused bytes */ unsigned dist; /* match distance */ - unsigned char *from; /* where to copy match from */ + unsigned char *from; /* where to copy match from */ /* copy state to local variables */ state = (struct inflate_state *)strm->state; diff --git a/lib/zlib_inflate/inflate.c b/lib/zlib_inflate/inflate.c index 7e1e3114a73e..0ad1ebf00947 100644 --- a/lib/zlib_inflate/inflate.c +++ b/lib/zlib_inflate/inflate.c @@ -332,14 +332,14 @@ static int zlib_inflateSyncPacket(z_streamp strm) int zlib_inflate(z_streamp strm, int flush) { struct inflate_state *state; - unsigned char *next; /* next input */ - unsigned char *put; /* next output */ + const unsigned char *next; /* next input */ + unsigned char *put; /* next output */ unsigned have, left; /* available input and output */ unsigned long hold; /* bit buffer */ unsigned bits; /* bits in bit buffer */ unsigned in, out; /* save starting available input and output */ unsigned copy; /* number of stored or match bytes to copy */ - unsigned char *from; /* where to copy match bytes from */ + unsigned char *from; /* where to copy match bytes from */ code this; /* current decoding table entry */ code last; /* parent table entry */ unsigned len; /* length to copy for repeats, bits to drop */ @@ -897,7 +897,7 @@ int zlib_inflateIncomp(z_stream *z) /* Setup some variables to allow misuse of updateWindow */ z->avail_out = 0; - z->next_out = z->next_in + z->avail_in; + z->next_out = (unsigned char*)z->next_in + z->avail_in; zlib_updatewindow(z, z->avail_in); @@ -916,3 +916,50 @@ int zlib_inflateIncomp(z_stream *z) return Z_OK; } + +#include +#include +#include + +/* Utility function: initialize zlib, unpack binary blob, clean up zlib, + * return len or negative error code. */ +int zlib_inflate_blob(void *gunzip_buf, unsigned sz, const void *buf, unsigned len) +{ + const u8 *zbuf = buf; + struct z_stream_s *strm; + int rc; + + rc = -ENOMEM; + strm = kmalloc(sizeof(*strm), GFP_KERNEL); + if (strm == NULL) + goto gunzip_nomem1; + strm->workspace = kmalloc(zlib_inflate_workspacesize(), GFP_KERNEL); + if (strm->workspace == NULL) + goto gunzip_nomem2; + + /* gzip header (1f,8b,08... 10 bytes total + possible asciz filename) + * expected to be stripped from input */ + + strm->next_in = zbuf; + strm->avail_in = len; + strm->next_out = gunzip_buf; + strm->avail_out = sz; + + rc = zlib_inflateInit2(strm, -MAX_WBITS); + if (rc == Z_OK) { + rc = zlib_inflate(strm, Z_FINISH); + /* after Z_FINISH, only Z_STREAM_END is "we unpacked it all" */ + if (rc == Z_STREAM_END) + rc = sz - strm->avail_out; + else + rc = -EINVAL; + zlib_inflateEnd(strm); + } else + rc = -EINVAL; + + kfree(strm->workspace); +gunzip_nomem2: + kfree(strm); +gunzip_nomem1: + return rc; /* returns Z_OK (0) if successful */ +} diff --git a/lib/zlib_inflate/inflate_syms.c b/lib/zlib_inflate/inflate_syms.c index 2061d4f06765..67329fe9907e 100644 --- a/lib/zlib_inflate/inflate_syms.c +++ b/lib/zlib_inflate/inflate_syms.c @@ -16,4 +16,5 @@ EXPORT_SYMBOL(zlib_inflateInit2); EXPORT_SYMBOL(zlib_inflateEnd); EXPORT_SYMBOL(zlib_inflateReset); EXPORT_SYMBOL(zlib_inflateIncomp); +EXPORT_SYMBOL(zlib_inflate_blob); MODULE_LICENSE("GPL"); -- cgit v1.2.3 From b7336d3d886aaab6971773864c477210ef9b995a Mon Sep 17 00:00:00 2001 From: Scott Wood Date: Mon, 1 Oct 2007 14:20:49 -0500 Subject: fs_enet: Include linux/string.h from linux/fs_enet_pd.h It is needed for strstr(). Signed-off-by: Scott Wood Signed-off-by: Jeff Garzik --- include/linux/fs_enet_pd.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/fs_enet_pd.h b/include/linux/fs_enet_pd.h index 543cd3cd9e77..815c6f94378b 100644 --- a/include/linux/fs_enet_pd.h +++ b/include/linux/fs_enet_pd.h @@ -16,6 +16,7 @@ #ifndef FS_ENET_PD_H #define FS_ENET_PD_H +#include #include #define FS_ENET_NAME "fs_enet" -- cgit v1.2.3 From 976de6a8c304dcc43e38efcb8a0bace7866b6242 Mon Sep 17 00:00:00 2001 From: Scott Wood Date: Tue, 2 Oct 2007 10:55:58 -0500 Subject: fs_enet: Be an of_platform device when CONFIG_PPC_CPM_NEW_BINDING is set. The existing OF glue code was crufty and broken. Rather than fix it, it will be removed, and the ethernet driver now talks to the device tree directly. The old, non-CONFIG_PPC_CPM_NEW_BINDING code can go away once CPM platforms are dropped from arch/ppc (which will hopefully be soon), and existing arch/powerpc boards that I wasn't able to test on for this patchset get converted (which should be even sooner). Signed-off-by: Scott Wood Signed-off-by: Jeff Garzik --- drivers/net/fs_enet/Kconfig | 1 + drivers/net/fs_enet/fs_enet-main.c | 258 ++++++++++++++++++++++++++++++++--- drivers/net/fs_enet/fs_enet.h | 55 +------- drivers/net/fs_enet/mac-fcc.c | 89 ++++++++---- drivers/net/fs_enet/mac-fec.c | 19 ++- drivers/net/fs_enet/mac-scc.c | 53 +++++--- drivers/net/fs_enet/mii-bitbang.c | 269 ++++++++++++++++++++++++++++--------- drivers/net/fs_enet/mii-fec.c | 143 +++++++++++++++++++- include/linux/fs_enet_pd.h | 5 + 9 files changed, 714 insertions(+), 178 deletions(-) (limited to 'include/linux') diff --git a/drivers/net/fs_enet/Kconfig b/drivers/net/fs_enet/Kconfig index e27ee210b605..2765e49e07df 100644 --- a/drivers/net/fs_enet/Kconfig +++ b/drivers/net/fs_enet/Kconfig @@ -11,6 +11,7 @@ config FS_ENET_HAS_SCC config FS_ENET_HAS_FCC bool "Chip has an FCC usable for ethernet" depends on FS_ENET && CPM2 + select MDIO_BITBANG default y config FS_ENET_HAS_FEC diff --git a/drivers/net/fs_enet/fs_enet-main.c b/drivers/net/fs_enet/fs_enet-main.c index 7a0298687875..fc4fda805d44 100644 --- a/drivers/net/fs_enet/fs_enet-main.c +++ b/drivers/net/fs_enet/fs_enet-main.c @@ -42,12 +42,18 @@ #include #include +#ifdef CONFIG_PPC_CPM_NEW_BINDING +#include +#endif + #include "fs_enet.h" /*************************************************/ +#ifndef CONFIG_PPC_CPM_NEW_BINDING static char version[] __devinitdata = DRV_MODULE_NAME ".c:v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")" "\n"; +#endif MODULE_AUTHOR("Pantelis Antoniou "); MODULE_DESCRIPTION("Freescale Ethernet Driver"); @@ -948,6 +954,7 @@ static int fs_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) extern int fs_mii_connect(struct net_device *dev); extern void fs_mii_disconnect(struct net_device *dev); +#ifndef CONFIG_PPC_CPM_NEW_BINDING static struct net_device *fs_init_instance(struct device *dev, struct fs_platform_info *fpi) { @@ -1129,6 +1136,7 @@ static int fs_cleanup_instance(struct net_device *ndev) return 0; } +#endif /**************************************************************************************/ @@ -1137,35 +1145,250 @@ void *fs_enet_immap = NULL; static int setup_immap(void) { - phys_addr_t paddr = 0; - unsigned long size = 0; - #ifdef CONFIG_CPM1 - paddr = IMAP_ADDR; - size = 0x10000; /* map 64K */ -#endif - -#ifdef CONFIG_CPM2 - paddr = CPM_MAP_ADDR; - size = 0x40000; /* map 256 K */ + fs_enet_immap = ioremap(IMAP_ADDR, 0x4000); + WARN_ON(!fs_enet_immap); +#elif defined(CONFIG_CPM2) + fs_enet_immap = cpm2_immr; #endif - fs_enet_immap = ioremap(paddr, size); - if (fs_enet_immap == NULL) - return -EBADF; /* XXX ahem; maybe just BUG_ON? */ return 0; } static void cleanup_immap(void) { - if (fs_enet_immap != NULL) { - iounmap(fs_enet_immap); - fs_enet_immap = NULL; - } +#if defined(CONFIG_CPM1) + iounmap(fs_enet_immap); +#endif } /**************************************************************************************/ +#ifdef CONFIG_PPC_CPM_NEW_BINDING +static int __devinit find_phy(struct device_node *np, + struct fs_platform_info *fpi) +{ + struct device_node *phynode, *mdionode; + struct resource res; + int ret = 0, len; + + const u32 *data = of_get_property(np, "phy-handle", &len); + if (!data || len != 4) + return -EINVAL; + + phynode = of_find_node_by_phandle(*data); + if (!phynode) + return -EINVAL; + + mdionode = of_get_parent(phynode); + if (!mdionode) + goto out_put_phy; + + ret = of_address_to_resource(mdionode, 0, &res); + if (ret) + goto out_put_mdio; + + data = of_get_property(phynode, "reg", &len); + if (!data || len != 4) + goto out_put_mdio; + + snprintf(fpi->bus_id, 16, PHY_ID_FMT, res.start, *data); + +out_put_mdio: + of_node_put(mdionode); +out_put_phy: + of_node_put(phynode); + return ret; +} + +#ifdef CONFIG_FS_ENET_HAS_FEC +#define IS_FEC(match) ((match)->data == &fs_fec_ops) +#else +#define IS_FEC(match) 0 +#endif + +static int __devinit fs_enet_probe(struct of_device *ofdev, + const struct of_device_id *match) +{ + struct net_device *ndev; + struct fs_enet_private *fep; + struct fs_platform_info *fpi; + const u32 *data; + const u8 *mac_addr; + int privsize, len, ret = -ENODEV; + + fpi = kzalloc(sizeof(*fpi), GFP_KERNEL); + if (!fpi) + return -ENOMEM; + + if (!IS_FEC(match)) { + data = of_get_property(ofdev->node, "fsl,cpm-command", &len); + if (!data || len != 4) + goto out_free_fpi; + + fpi->cp_command = *data; + } + + fpi->rx_ring = 32; + fpi->tx_ring = 32; + fpi->rx_copybreak = 240; + fpi->use_napi = 0; + fpi->napi_weight = 17; + + ret = find_phy(ofdev->node, fpi); + if (ret) + goto out_free_fpi; + + privsize = sizeof(*fep) + + sizeof(struct sk_buff **) * + (fpi->rx_ring + fpi->tx_ring); + + ndev = alloc_etherdev(privsize); + if (!ndev) { + ret = -ENOMEM; + goto out_free_fpi; + } + + SET_MODULE_OWNER(ndev); + dev_set_drvdata(&ofdev->dev, ndev); + + fep = netdev_priv(ndev); + fep->dev = &ofdev->dev; + fep->fpi = fpi; + fep->ops = match->data; + + ret = fep->ops->setup_data(ndev); + if (ret) + goto out_free_dev; + + fep->rx_skbuff = (struct sk_buff **)&fep[1]; + fep->tx_skbuff = fep->rx_skbuff + fpi->rx_ring; + + spin_lock_init(&fep->lock); + spin_lock_init(&fep->tx_lock); + + mac_addr = of_get_mac_address(ofdev->node); + if (mac_addr) + memcpy(ndev->dev_addr, mac_addr, 6); + + ret = fep->ops->allocate_bd(ndev); + if (ret) + goto out_cleanup_data; + + fep->rx_bd_base = fep->ring_base; + fep->tx_bd_base = fep->rx_bd_base + fpi->rx_ring; + + fep->tx_ring = fpi->tx_ring; + fep->rx_ring = fpi->rx_ring; + + ndev->open = fs_enet_open; + ndev->hard_start_xmit = fs_enet_start_xmit; + ndev->tx_timeout = fs_timeout; + ndev->watchdog_timeo = 2 * HZ; + ndev->stop = fs_enet_close; + ndev->get_stats = fs_enet_get_stats; + ndev->set_multicast_list = fs_set_multicast_list; + if (fpi->use_napi) { + ndev->poll = fs_enet_rx_napi; + ndev->weight = fpi->napi_weight; + } + ndev->ethtool_ops = &fs_ethtool_ops; + ndev->do_ioctl = fs_ioctl; + + init_timer(&fep->phy_timer_list); + + netif_carrier_off(ndev); + + ret = register_netdev(ndev); + if (ret) + goto out_free_bd; + + printk(KERN_INFO "%s: fs_enet: %02x:%02x:%02x:%02x:%02x:%02x\n", + ndev->name, + ndev->dev_addr[0], ndev->dev_addr[1], ndev->dev_addr[2], + ndev->dev_addr[3], ndev->dev_addr[4], ndev->dev_addr[5]); + + return 0; + +out_free_bd: + fep->ops->free_bd(ndev); +out_cleanup_data: + fep->ops->cleanup_data(ndev); +out_free_dev: + free_netdev(ndev); + dev_set_drvdata(&ofdev->dev, NULL); +out_free_fpi: + kfree(fpi); + return ret; +} + +static int fs_enet_remove(struct of_device *ofdev) +{ + struct net_device *ndev = dev_get_drvdata(&ofdev->dev); + struct fs_enet_private *fep = netdev_priv(ndev); + + unregister_netdev(ndev); + + fep->ops->free_bd(ndev); + fep->ops->cleanup_data(ndev); + dev_set_drvdata(fep->dev, NULL); + + free_netdev(ndev); + return 0; +} + +static struct of_device_id fs_enet_match[] = { +#ifdef CONFIG_FS_ENET_HAS_SCC + { + .compatible = "fsl,cpm1-scc-enet", + .data = (void *)&fs_scc_ops, + }, +#endif +#ifdef CONFIG_FS_ENET_HAS_FCC + { + .compatible = "fsl,cpm2-fcc-enet", + .data = (void *)&fs_fcc_ops, + }, +#endif +#ifdef CONFIG_FS_ENET_HAS_FEC + { + .compatible = "fsl,pq1-fec-enet", + .data = (void *)&fs_fec_ops, + }, +#endif + {} +}; + +static struct of_platform_driver fs_enet_driver = { + .name = "fs_enet", + .match_table = fs_enet_match, + .probe = fs_enet_probe, + .remove = fs_enet_remove, +}; + +static int __init fs_init(void) +{ + int r = setup_immap(); + if (r != 0) + return r; + + r = of_register_platform_driver(&fs_enet_driver); + if (r != 0) + goto out; + + return 0; + +out: + cleanup_immap(); + return r; +} + +static void __exit fs_cleanup(void) +{ + of_unregister_platform_driver(&fs_enet_driver); + cleanup_immap(); +} +#else static int __devinit fs_enet_probe(struct device *dev) { struct net_device *ndev; @@ -1279,6 +1502,7 @@ static void __exit fs_cleanup(void) driver_unregister(&fs_enet_scc_driver); cleanup_immap(); } +#endif #ifdef CONFIG_NET_POLL_CONTROLLER static void fs_enet_netpoll(struct net_device *dev) diff --git a/drivers/net/fs_enet/fs_enet.h b/drivers/net/fs_enet/fs_enet.h index 85571e49ec72..5a5c9d18df2e 100644 --- a/drivers/net/fs_enet/fs_enet.h +++ b/drivers/net/fs_enet/fs_enet.h @@ -24,19 +24,6 @@ struct fec_info { #include #endif -/* This is used to operate with pins. - Note that the actual port size may - be different; cpm(s) handle it OK */ -struct bb_info { - u8 mdio_dat_msk; - u8 mdio_dir_msk; - u8 *mdio_dir; - u8 *mdio_dat; - u8 mdc_msk; - u8 *mdc_dat; - int delay; -}; - /* hw driver ops */ struct fs_ops { int (*setup_data)(struct net_device *dev); @@ -85,48 +72,12 @@ struct phy_info { #define ENET_RX_ALIGN 16 #define ENET_RX_FRSIZE L1_CACHE_ALIGN(PKT_MAXBUF_SIZE + ENET_RX_ALIGN - 1) -struct fs_enet_mii_bus { - struct list_head list; - spinlock_t mii_lock; - const struct fs_mii_bus_info *bus_info; - int refs; - u32 usage_map; - - int (*mii_read)(struct fs_enet_mii_bus *bus, - int phy_id, int location); - - void (*mii_write)(struct fs_enet_mii_bus *bus, - int phy_id, int location, int value); - - union { - struct { - unsigned int mii_speed; - void *fecp; - } fec; - - struct { - /* note that the actual port size may */ - /* be different; cpm(s) handle it OK */ - u8 mdio_msk; - u8 *mdio_dir; - u8 *mdio_dat; - u8 mdc_msk; - u8 *mdc_dir; - u8 *mdc_dat; - } bitbang; - - struct { - u16 lpa; - } fixed; - }; -}; - struct fs_enet_private { struct napi_struct napi; struct device *dev; /* pointer back to the device (must be initialized first) */ spinlock_t lock; /* during all ops except TX pckt processing */ spinlock_t tx_lock; /* during fs_start_xmit and fs_tx */ - const struct fs_platform_info *fpi; + struct fs_platform_info *fpi; const struct fs_ops *ops; int rx_ring, tx_ring; dma_addr_t ring_mem_addr; @@ -145,7 +96,6 @@ struct fs_enet_private { u32 msg_enable; struct mii_if_info mii_if; unsigned int last_mii_status; - struct fs_enet_mii_bus *mii_bus; int interrupt; struct phy_device *phydev; @@ -187,9 +137,10 @@ struct fs_enet_private { }; /***************************************************************************/ +#ifndef CONFIG_PPC_CPM_NEW_BINDING int fs_enet_mdio_bb_init(void); -int fs_mii_fixed_init(struct fs_enet_mii_bus *bus); int fs_enet_mdio_fec_init(void); +#endif void fs_init_bds(struct net_device *dev); void fs_cleanup_bds(struct net_device *dev); diff --git a/drivers/net/fs_enet/mac-fcc.c b/drivers/net/fs_enet/mac-fcc.c index e990f728d51b..6094cbf542a2 100644 --- a/drivers/net/fs_enet/mac-fcc.c +++ b/drivers/net/fs_enet/mac-fcc.c @@ -42,6 +42,10 @@ #include #include +#ifdef CONFIG_PPC_CPM_NEW_BINDING +#include +#endif + #include "fs_enet.h" /*************************************************/ @@ -74,33 +78,64 @@ #define MAX_CR_CMD_LOOPS 10000 -static inline int fcc_cr_cmd(struct fs_enet_private *fep, u32 mcn, u32 op) +static inline int fcc_cr_cmd(struct fs_enet_private *fep, u32 op) { const struct fs_platform_info *fpi = fep->fpi; cpm2_map_t *immap = fs_enet_immap; cpm_cpm2_t *cpmp = &immap->im_cpm; - u32 v; int i; - /* Currently I don't know what feature call will look like. But - I guess there'd be something like do_cpm_cmd() which will require page & sblock */ - v = mk_cr_cmd(fpi->cp_page, fpi->cp_block, mcn, op); - W32(cpmp, cp_cpcr, v | CPM_CR_FLG); + W32(cpmp, cp_cpcr, fpi->cp_command | op | CPM_CR_FLG); for (i = 0; i < MAX_CR_CMD_LOOPS; i++) if ((R32(cpmp, cp_cpcr) & CPM_CR_FLG) == 0) - break; - - if (i >= MAX_CR_CMD_LOOPS) { - printk(KERN_ERR "%s(): Not able to issue CPM command\n", - __FUNCTION__); - return 1; - } + return 0; - return 0; + printk(KERN_ERR "%s(): Not able to issue CPM command\n", + __FUNCTION__); + return 1; } static int do_pd_setup(struct fs_enet_private *fep) { +#ifdef CONFIG_PPC_CPM_NEW_BINDING + struct of_device *ofdev = to_of_device(fep->dev); + struct fs_platform_info *fpi = fep->fpi; + int ret = -EINVAL; + + fep->interrupt = of_irq_to_resource(ofdev->node, 0, NULL); + if (fep->interrupt == NO_IRQ) + goto out; + + fep->fcc.fccp = of_iomap(ofdev->node, 0); + if (!fep->fcc.fccp) + goto out; + + fep->fcc.ep = of_iomap(ofdev->node, 1); + if (!fep->fcc.ep) + goto out_fccp; + + fep->fcc.fcccp = of_iomap(ofdev->node, 2); + if (!fep->fcc.fcccp) + goto out_ep; + + fep->fcc.mem = (void *)cpm_dpalloc(128, 8); + fpi->dpram_offset = (u32)cpm2_immr; + if (IS_ERR_VALUE(fpi->dpram_offset)) { + ret = fpi->dpram_offset; + goto out_fcccp; + } + + return 0; + +out_fcccp: + iounmap(fep->fcc.fcccp); +out_ep: + iounmap(fep->fcc.ep); +out_fccp: + iounmap(fep->fcc.fccp); +out: + return ret; +#else struct platform_device *pdev = to_platform_device(fep->dev); struct resource *r; @@ -138,6 +173,7 @@ static int do_pd_setup(struct fs_enet_private *fep) return -EINVAL; return 0; +#endif } #define FCC_NAPI_RX_EVENT_MSK (FCC_ENET_RXF | FCC_ENET_RXB) @@ -148,11 +184,17 @@ static int do_pd_setup(struct fs_enet_private *fep) static int setup_data(struct net_device *dev) { struct fs_enet_private *fep = netdev_priv(dev); - const struct fs_platform_info *fpi = fep->fpi; +#ifndef CONFIG_PPC_CPM_NEW_BINDING + struct fs_platform_info *fpi = fep->fpi; + + fpi->cp_command = (fpi->cp_page << 26) | + (fpi->cp_block << 21) | + (12 << 6); fep->fcc.idx = fs_get_fcc_index(fpi->fs_no); if ((unsigned int)fep->fcc.idx >= 3) /* max 3 FCCs */ return -EINVAL; +#endif if (do_pd_setup(fep) != 0) return -EINVAL; @@ -226,7 +268,7 @@ static void set_multicast_one(struct net_device *dev, const u8 *mac) W16(ep, fen_taddrh, taddrh); W16(ep, fen_taddrm, taddrm); W16(ep, fen_taddrl, taddrl); - fcc_cr_cmd(fep, 0x0C, CPM_CR_SET_GADDR); + fcc_cr_cmd(fep, CPM_CR_SET_GADDR); } static void set_multicast_finish(struct net_device *dev) @@ -281,7 +323,7 @@ static void restart(struct net_device *dev) /* clear everything (slow & steady does it) */ for (i = 0; i < sizeof(*ep); i++) - out_8((char *)ep + i, 0); + out_8((u8 __iomem *)ep + i, 0); /* get physical address */ rx_bd_base_phys = fep->ring_mem_addr; @@ -397,7 +439,7 @@ static void restart(struct net_device *dev) S8(fcccp, fcc_gfemr, 0x20); } - fcc_cr_cmd(fep, 0x0c, CPM_CR_INIT_TRX); + fcc_cr_cmd(fep, CPM_CR_INIT_TRX); /* clear events */ W16(fccp, fcc_fcce, 0xffff); @@ -515,23 +557,22 @@ int get_regs(struct net_device *dev, void *p, int *sizep) { struct fs_enet_private *fep = netdev_priv(dev); - if (*sizep < sizeof(fcc_t) + sizeof(fcc_c_t) + sizeof(fcc_enet_t)) + if (*sizep < sizeof(fcc_t) + sizeof(fcc_enet_t) + 1) return -EINVAL; memcpy_fromio(p, fep->fcc.fccp, sizeof(fcc_t)); p = (char *)p + sizeof(fcc_t); - memcpy_fromio(p, fep->fcc.fcccp, sizeof(fcc_c_t)); - p = (char *)p + sizeof(fcc_c_t); - memcpy_fromio(p, fep->fcc.ep, sizeof(fcc_enet_t)); + p = (char *)p + sizeof(fcc_enet_t); + memcpy_fromio(p, fep->fcc.fcccp, 1); return 0; } int get_regs_len(struct net_device *dev) { - return sizeof(fcc_t) + sizeof(fcc_c_t) + sizeof(fcc_enet_t); + return sizeof(fcc_t) + sizeof(fcc_enet_t) + 1; } /* Some transmit errors cause the transmitter to shut @@ -551,7 +592,7 @@ void tx_restart(struct net_device *dev) udelay(10); S32(fccp, fcc_gfmr, FCC_GFMR_ENT); - fcc_cr_cmd(fep, 0x0C, CPM_CR_RESTART_TX); + fcc_cr_cmd(fep, CPM_CR_RESTART_TX); } /*************************************************************************/ diff --git a/drivers/net/fs_enet/mac-fec.c b/drivers/net/fs_enet/mac-fec.c index cbdc17b743db..924d6617cd30 100644 --- a/drivers/net/fs_enet/mac-fec.c +++ b/drivers/net/fs_enet/mac-fec.c @@ -43,6 +43,10 @@ #include #endif +#ifdef CONFIG_PPC_CPM_NEW_BINDING +#include +#endif + #include "fs_enet.h" #include "fec.h" @@ -95,6 +99,19 @@ static int whack_reset(fec_t * fecp) static int do_pd_setup(struct fs_enet_private *fep) { +#ifdef CONFIG_PPC_CPM_NEW_BINDING + struct of_device *ofdev = to_of_device(fep->dev); + + fep->interrupt = of_irq_to_resource(ofdev->node, 0, NULL); + if (fep->interrupt == NO_IRQ) + return -EINVAL; + + fep->fec.fecp = of_iomap(ofdev->node, 0); + if (!fep->fcc.fccp) + return -EINVAL; + + return 0; +#else struct platform_device *pdev = to_platform_device(fep->dev); struct resource *r; @@ -110,7 +127,7 @@ static int do_pd_setup(struct fs_enet_private *fep) return -EINVAL; return 0; - +#endif } #define FEC_NAPI_RX_EVENT_MSK (FEC_ENET_RXF | FEC_ENET_RXB) diff --git a/drivers/net/fs_enet/mac-scc.c b/drivers/net/fs_enet/mac-scc.c index 6f32674a78e9..add9e32d4f47 100644 --- a/drivers/net/fs_enet/mac-scc.c +++ b/drivers/net/fs_enet/mac-scc.c @@ -43,6 +43,10 @@ #include #endif +#ifdef CONFIG_PPC_CPM_NEW_BINDING +#include +#endif + #include "fs_enet.h" /*************************************************/ @@ -89,27 +93,38 @@ static inline int scc_cr_cmd(struct fs_enet_private *fep, u32 op) { - cpm8xx_t *cpmp = &((immap_t *)fs_enet_immap)->im_cpm; - u32 v, ch; - int i = 0; + const struct fs_platform_info *fpi = fep->fpi; + int i; - ch = fep->scc.idx << 2; - v = mk_cr_cmd(ch, op); - W16(cpmp, cp_cpcr, v | CPM_CR_FLG); + W16(cpmp, cp_cpcr, fpi->cp_command | CPM_CR_FLG | (op << 8)); for (i = 0; i < MAX_CR_CMD_LOOPS; i++) if ((R16(cpmp, cp_cpcr) & CPM_CR_FLG) == 0) - break; + return 0; - if (i >= MAX_CR_CMD_LOOPS) { - printk(KERN_ERR "%s(): Not able to issue CPM command\n", - __FUNCTION__); - return 1; - } - return 0; + printk(KERN_ERR "%s(): Not able to issue CPM command\n", + __FUNCTION__); + return 1; } static int do_pd_setup(struct fs_enet_private *fep) { +#ifdef CONFIG_PPC_CPM_NEW_BINDING + struct of_device *ofdev = to_of_device(fep->dev); + + fep->interrupt = of_irq_to_resource(ofdev->node, 0, NULL); + if (fep->interrupt == NO_IRQ) + return -EINVAL; + + fep->scc.sccp = of_iomap(ofdev->node, 0); + if (!fep->scc.sccp) + return -EINVAL; + + fep->scc.ep = of_iomap(ofdev->node, 1); + if (!fep->scc.ep) { + iounmap(fep->scc.sccp); + return -EINVAL; + } +#else struct platform_device *pdev = to_platform_device(fep->dev); struct resource *r; @@ -129,6 +144,7 @@ static int do_pd_setup(struct fs_enet_private *fep) if (fep->scc.ep == NULL) return -EINVAL; +#endif return 0; } @@ -141,12 +157,17 @@ static int do_pd_setup(struct fs_enet_private *fep) static int setup_data(struct net_device *dev) { struct fs_enet_private *fep = netdev_priv(dev); - const struct fs_platform_info *fpi = fep->fpi; + +#ifdef CONFIG_PPC_CPM_NEW_BINDING + struct fs_platform_info *fpi = fep->fpi; fep->scc.idx = fs_get_scc_index(fpi->fs_no); - if ((unsigned int)fep->fcc.idx > 4) /* max 4 SCCs */ + if ((unsigned int)fep->fcc.idx >= 4) /* max 4 SCCs */ return -EINVAL; + fpi->cp_command = fep->fcc.idx << 6; +#endif + do_pd_setup(fep); fep->scc.hthi = 0; @@ -154,7 +175,7 @@ static int setup_data(struct net_device *dev) fep->ev_napi_rx = SCC_NAPI_RX_EVENT_MSK; fep->ev_rx = SCC_RX_EVENT; - fep->ev_tx = SCC_TX_EVENT; + fep->ev_tx = SCC_TX_EVENT | SCCE_ENET_TXE; fep->ev_err = SCC_ERR_EVENT_MSK; return 0; diff --git a/drivers/net/fs_enet/mii-bitbang.c b/drivers/net/fs_enet/mii-bitbang.c index 422f82877873..7cf132f0f952 100644 --- a/drivers/net/fs_enet/mii-bitbang.c +++ b/drivers/net/fs_enet/mii-bitbang.c @@ -13,11 +13,6 @@ */ #include -#include -#include -#include -#include -#include #include #include #include @@ -25,86 +20,77 @@ #include #include #include -#include -#include #include #include #include #include -#include -#include -#include +#ifdef CONFIG_PPC_CPM_NEW_BINDING +#include +#endif #include "fs_enet.h" -static int bitbang_prep_bit(u8 **datp, u8 *mskp, - struct fs_mii_bit *mii_bit) -{ - void *dat; - int adv; - u8 msk; - - dat = (void*) mii_bit->offset; - - adv = mii_bit->bit >> 3; - dat = (char *)dat + adv; - - msk = 1 << (7 - (mii_bit->bit & 7)); - - *datp = dat; - *mskp = msk; - - return 0; -} +struct bb_info { + __be32 __iomem *dir; + __be32 __iomem *dat; + u32 mdio_msk; + u32 mdc_msk; + int delay; +}; -static inline void bb_set(u8 *p, u8 m) +/* FIXME: If any other users of GPIO crop up, then these will have to + * have some sort of global synchronization to avoid races with other + * pins on the same port. The ideal solution would probably be to + * bind the ports to a GPIO driver, and have this be a client of it. + */ +static inline void bb_set(u32 __iomem *p, u32 m) { - out_8(p, in_8(p) | m); + out_be32(p, in_be32(p) | m); } -static inline void bb_clr(u8 *p, u8 m) +static inline void bb_clr(u32 __iomem *p, u32 m) { - out_8(p, in_8(p) & ~m); + out_be32(p, in_be32(p) & ~m); } -static inline int bb_read(u8 *p, u8 m) +static inline int bb_read(u32 __iomem *p, u32 m) { - return (in_8(p) & m) != 0; + return (in_be32(p) & m) != 0; } static inline void mdio_active(struct bb_info *bitbang) { - bb_set(bitbang->mdio_dir, bitbang->mdio_dir_msk); + bb_set(bitbang->dir, bitbang->mdio_msk); } -static inline void mdio_tristate(struct bb_info *bitbang ) +static inline void mdio_tristate(struct bb_info *bitbang) { - bb_clr(bitbang->mdio_dir, bitbang->mdio_dir_msk); + bb_clr(bitbang->dir, bitbang->mdio_msk); } -static inline int mdio_read(struct bb_info *bitbang ) +static inline int mdio_read(struct bb_info *bitbang) { - return bb_read(bitbang->mdio_dat, bitbang->mdio_dat_msk); + return bb_read(bitbang->dat, bitbang->mdio_msk); } -static inline void mdio(struct bb_info *bitbang , int what) +static inline void mdio(struct bb_info *bitbang, int what) { if (what) - bb_set(bitbang->mdio_dat, bitbang->mdio_dat_msk); + bb_set(bitbang->dat, bitbang->mdio_msk); else - bb_clr(bitbang->mdio_dat, bitbang->mdio_dat_msk); + bb_clr(bitbang->dat, bitbang->mdio_msk); } -static inline void mdc(struct bb_info *bitbang , int what) +static inline void mdc(struct bb_info *bitbang, int what) { if (what) - bb_set(bitbang->mdc_dat, bitbang->mdc_msk); + bb_set(bitbang->dat, bitbang->mdc_msk); else - bb_clr(bitbang->mdc_dat, bitbang->mdc_msk); + bb_clr(bitbang->dat, bitbang->mdc_msk); } -static inline void mii_delay(struct bb_info *bitbang ) +static inline void mii_delay(struct bb_info *bitbang) { udelay(bitbang->delay); } @@ -280,29 +266,178 @@ static int fs_enet_mii_bb_reset(struct mii_bus *bus) return 0; } -static int fs_mii_bitbang_init(struct bb_info *bitbang, struct fs_mii_bb_platform_info* fmpi) +#ifdef CONFIG_PPC_CPM_NEW_BINDING +static int __devinit fs_mii_bitbang_init(struct mii_bus *bus, + struct device_node *np) { - int r; + struct resource res; + const u32 *data; + int mdio_pin, mdc_pin, len; + struct bb_info *bitbang = bus->priv; - bitbang->delay = fmpi->delay; + int ret = of_address_to_resource(np, 0, &res); + if (ret) + return ret; + + if (res.end - res.start < 13) + return -ENODEV; + + /* This should really encode the pin number as well, but all + * we get is an int, and the odds of multiple bitbang mdio buses + * is low enough that it's not worth going too crazy. + */ + bus->id = res.start; + + data = of_get_property(np, "fsl,mdio-pin", &len); + if (!data || len != 4) + return -ENODEV; + mdio_pin = *data; + + data = of_get_property(np, "fsl,mdc-pin", &len); + if (!data || len != 4) + return -ENODEV; + mdc_pin = *data; + + bitbang->dir = ioremap(res.start, res.end - res.start + 1); + if (!bitbang->dir) + return -ENOMEM; + + bitbang->dat = bitbang->dir + 4; + bitbang->mdio_msk = 1 << (31 - mdio_pin); + bitbang->mdc_msk = 1 << (31 - mdc_pin); + bitbang->delay = 1; /* 1 us between operations */ - r = bitbang_prep_bit(&bitbang->mdio_dir, - &bitbang->mdio_dir_msk, - &fmpi->mdio_dir); - if (r != 0) - return r; - - r = bitbang_prep_bit(&bitbang->mdio_dat, - &bitbang->mdio_dat_msk, - &fmpi->mdio_dat); - if (r != 0) - return r; - - r = bitbang_prep_bit(&bitbang->mdc_dat, - &bitbang->mdc_msk, - &fmpi->mdc_dat); - if (r != 0) - return r; + return 0; +} + +static void __devinit add_phy(struct mii_bus *bus, struct device_node *np) +{ + const u32 *data; + int len, id, irq; + + data = of_get_property(np, "reg", &len); + if (!data || len != 4) + return; + + id = *data; + bus->phy_mask &= ~(1 << id); + + irq = of_irq_to_resource(np, 0, NULL); + if (irq != NO_IRQ) + bus->irq[id] = irq; +} + +static int __devinit fs_enet_mdio_probe(struct of_device *ofdev, + const struct of_device_id *match) +{ + struct device_node *np = NULL; + struct mii_bus *new_bus; + struct bb_info *bitbang; + int ret = -ENOMEM; + int i; + + new_bus = kzalloc(sizeof(struct mii_bus), GFP_KERNEL); + if (!new_bus) + goto out; + + bitbang = kzalloc(sizeof(struct bb_info), GFP_KERNEL); + if (!bitbang) + goto out_free_bus; + + new_bus->priv = bitbang; + new_bus->name = "CPM2 Bitbanged MII", + new_bus->read = &fs_enet_mii_bb_read, + new_bus->write = &fs_enet_mii_bb_write, + new_bus->reset = &fs_enet_mii_bb_reset, + + ret = fs_mii_bitbang_init(new_bus, ofdev->node); + if (ret) + goto out_free_bitbang; + + new_bus->phy_mask = ~0; + new_bus->irq = kmalloc(sizeof(int) * PHY_MAX_ADDR, GFP_KERNEL); + if (!new_bus->irq) + goto out_unmap_regs; + + for (i = 0; i < PHY_MAX_ADDR; i++) + new_bus->irq[i] = -1; + + while ((np = of_get_next_child(ofdev->node, np))) + if (!strcmp(np->type, "ethernet-phy")) + add_phy(new_bus, np); + + new_bus->dev = &ofdev->dev; + dev_set_drvdata(&ofdev->dev, new_bus); + + ret = mdiobus_register(new_bus); + if (ret) + goto out_free_irqs; + + return 0; + +out_free_irqs: + dev_set_drvdata(&ofdev->dev, NULL); + kfree(new_bus->irq); +out_unmap_regs: + iounmap(bitbang->dir); +out_free_bitbang: + kfree(bitbang); +out_free_bus: + kfree(new_bus); +out: + return ret; +} + +static int fs_enet_mdio_remove(struct of_device *ofdev) +{ + struct mii_bus *bus = dev_get_drvdata(&ofdev->dev); + struct bb_info *bitbang = bus->priv; + + mdiobus_unregister(bus); + dev_set_drvdata(&ofdev->dev, NULL); + kfree(bus->irq); + iounmap(bitbang->dir); + kfree(bitbang); + kfree(bus); + + return 0; +} + +static struct of_device_id fs_enet_mdio_bb_match[] = { + { + .compatible = "fsl,cpm2-mdio-bitbang", + }, + {}, +}; + +static struct of_platform_driver fs_enet_bb_mdio_driver = { + .name = "fsl-bb-mdio", + .match_table = fs_enet_mdio_bb_match, + .probe = fs_enet_mdio_probe, + .remove = fs_enet_mdio_remove, +}; + +int fs_enet_mdio_bb_init(void) +{ + return of_register_platform_driver(&fs_enet_bb_mdio_driver); +} + +void fs_enet_mdio_bb_exit(void) +{ + of_unregister_platform_driver(&fs_enet_bb_mdio_driver); +} + +module_init(fs_enet_mdio_bb_init); +module_exit(fs_enet_mdio_bb_exit); +#else +static int __devinit fs_mii_bitbang_init(struct bb_info *bitbang, + struct fs_mii_bb_platform_info *fmpi) +{ + bitbang->dir = (u32 __iomem *)fmpi->mdio_dir.offset; + bitbang->dat = (u32 __iomem *)fmpi->mdio_dat.offset; + bitbang->mdio_msk = 1U << (31 - fmpi->mdio_dat.bit); + bitbang->mdc_msk = 1U << (31 - fmpi->mdc_dat.bit); + bitbang->delay = fmpi->delay; return 0; } diff --git a/drivers/net/fs_enet/mii-fec.c b/drivers/net/fs_enet/mii-fec.c index 53db696b948f..f91c38d0b57b 100644 --- a/drivers/net/fs_enet/mii-fec.c +++ b/drivers/net/fs_enet/mii-fec.c @@ -36,6 +36,10 @@ #include #include +#ifdef CONFIG_PPC_CPM_NEW_BINDING +#include +#endif + #include "fs_enet.h" #include "fec.h" @@ -47,6 +51,7 @@ #define FEC_MII_LOOPS 10000 +#ifndef CONFIG_PPC_CPM_NEW_BINDING static int match_has_phy (struct device *dev, void* data) { struct platform_device* pdev = container_of(dev, struct platform_device, dev); @@ -90,6 +95,7 @@ static int fs_mii_fec_init(struct fec_info* fec, struct fs_mii_fec_platform_info return 0; } +#endif static int fs_enet_fec_mii_read(struct mii_bus *bus , int phy_id, int location) { @@ -145,6 +151,141 @@ static int fs_enet_fec_mii_reset(struct mii_bus *bus) return 0; } +#ifdef CONFIG_PPC_CPM_NEW_BINDING +static void __devinit add_phy(struct mii_bus *bus, struct device_node *np) +{ + const u32 *data; + int len, id, irq; + + data = of_get_property(np, "reg", &len); + if (!data || len != 4) + return; + + id = *data; + bus->phy_mask &= ~(1 << id); + + irq = of_irq_to_resource(np, 0, NULL); + if (irq != NO_IRQ) + bus->irq[id] = irq; +} + +static int __devinit fs_enet_mdio_probe(struct of_device *ofdev, + const struct of_device_id *match) +{ + struct device_node *np = NULL; + struct resource res; + struct mii_bus *new_bus; + struct fec_info *fec; + int ret = -ENOMEM, i; + + new_bus = kzalloc(sizeof(struct mii_bus), GFP_KERNEL); + if (!new_bus) + goto out; + + fec = kzalloc(sizeof(struct fec_info), GFP_KERNEL); + if (!fec) + goto out_mii; + + new_bus->priv = fec; + new_bus->name = "FEC MII Bus"; + new_bus->read = &fs_enet_fec_mii_read; + new_bus->write = &fs_enet_fec_mii_write; + new_bus->reset = &fs_enet_fec_mii_reset; + + ret = of_address_to_resource(ofdev->node, 0, &res); + if (ret) + return ret; + + new_bus->id = res.start; + + fec->fecp = ioremap(res.start, res.end - res.start + 1); + if (!fec->fecp) + goto out_fec; + + fec->mii_speed = ((ppc_proc_freq + 4999999) / 5000000) << 1; + + setbits32(&fec->fecp->fec_r_cntrl, FEC_RCNTRL_MII_MODE); + setbits32(&fec->fecp->fec_ecntrl, FEC_ECNTRL_PINMUX | + FEC_ECNTRL_ETHER_EN); + out_be32(&fec->fecp->fec_ievent, FEC_ENET_MII); + out_be32(&fec->fecp->fec_mii_speed, fec->mii_speed); + + new_bus->phy_mask = ~0; + new_bus->irq = kmalloc(sizeof(int) * PHY_MAX_ADDR, GFP_KERNEL); + if (!new_bus->irq) + goto out_unmap_regs; + + for (i = 0; i < PHY_MAX_ADDR; i++) + new_bus->irq[i] = -1; + + while ((np = of_get_next_child(ofdev->node, np))) + if (!strcmp(np->type, "ethernet-phy")) + add_phy(new_bus, np); + + new_bus->dev = &ofdev->dev; + dev_set_drvdata(&ofdev->dev, new_bus); + + ret = mdiobus_register(new_bus); + if (ret) + goto out_free_irqs; + + return 0; + +out_free_irqs: + dev_set_drvdata(&ofdev->dev, NULL); + kfree(new_bus->irq); +out_unmap_regs: + iounmap(fec->fecp); +out_fec: + kfree(fec); +out_mii: + kfree(new_bus); +out: + return ret; +} + +static int fs_enet_mdio_remove(struct of_device *ofdev) +{ + struct mii_bus *bus = dev_get_drvdata(&ofdev->dev); + struct fec_info *fec = bus->priv; + + mdiobus_unregister(bus); + dev_set_drvdata(&ofdev->dev, NULL); + kfree(bus->irq); + iounmap(fec->fecp); + kfree(fec); + kfree(bus); + + return 0; +} + +static struct of_device_id fs_enet_mdio_fec_match[] = { + { + .compatible = "fsl,pq1-fec-mdio", + }, + {}, +}; + +static struct of_platform_driver fs_enet_fec_mdio_driver = { + .name = "fsl-fec-mdio", + .match_table = fs_enet_mdio_fec_match, + .probe = fs_enet_mdio_probe, + .remove = fs_enet_mdio_remove, +}; + +static int fs_enet_mdio_fec_init(void) +{ + return of_register_platform_driver(&fs_enet_fec_mdio_driver); +} + +static void fs_enet_mdio_fec_exit(void) +{ + of_unregister_platform_driver(&fs_enet_fec_mdio_driver); +} + +module_init(fs_enet_mdio_fec_init); +module_exit(fs_enet_mdio_fec_exit); +#else static int __devinit fs_enet_fec_mdio_probe(struct device *dev) { struct platform_device *pdev = to_platform_device(dev); @@ -235,4 +376,4 @@ void fs_enet_mdio_fec_exit(void) { driver_unregister(&fs_enet_fec_mdio_driver); } - +#endif diff --git a/include/linux/fs_enet_pd.h b/include/linux/fs_enet_pd.h index 815c6f94378b..9bc045b8c478 100644 --- a/include/linux/fs_enet_pd.h +++ b/include/linux/fs_enet_pd.h @@ -120,6 +120,7 @@ struct fs_platform_info { u32 cp_page; /* CPM page */ u32 cp_block; /* CPM sblock */ + u32 cp_command; /* CPM page/sblock/mcn */ u32 clk_trx; /* some stuff for pins & mux configuration*/ u32 clk_rx; @@ -134,7 +135,11 @@ struct fs_platform_info { u32 device_flags; int phy_addr; /* the phy address (-1 no phy) */ +#ifdef CONFIG_PPC_CPM_NEW_BINDING + char bus_id[16]; +#else const char* bus_id; +#endif int phy_irq; /* the phy irq (if it exists) */ const struct fs_mii_bus_info *bus_info; -- cgit v1.2.3 From e2ec4581adf7e288c193e981c39ca01cdb20a272 Mon Sep 17 00:00:00 2001 From: Scott Wood Date: Mon, 1 Oct 2007 14:20:56 -0500 Subject: Generic bitbanged MDIO library Previously, bitbanged MDIO was only supported in individual hardware-specific drivers. This code factors out the higher level protocol implementation, reducing the hardware-specific portion to functions setting direction, data, and clock. Signed-off-by: Scott Wood Signed-off-by: Jeff Garzik --- drivers/net/phy/Kconfig | 9 ++ drivers/net/phy/Makefile | 1 + drivers/net/phy/mdio-bitbang.c | 187 +++++++++++++++++++++++++++++++++++++++++ include/linux/mdio-bitbang.h | 42 +++++++++ 4 files changed, 239 insertions(+) create mode 100644 drivers/net/phy/mdio-bitbang.c create mode 100644 include/linux/mdio-bitbang.h (limited to 'include/linux') diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig index 432c210513be..54b2ba996640 100644 --- a/drivers/net/phy/Kconfig +++ b/drivers/net/phy/Kconfig @@ -90,4 +90,13 @@ config FIXED_MII_AMNT This control will have specified number allocated for each fixed PHY type enabled. +config MDIO_BITBANG + tristate "Support for bitbanged MDIO buses" + help + This module implements the MDIO bus protocol in software, + for use by low level drivers that export the ability to + drive the relevant pins. + + If in doubt, say N. + endif # PHYLIB diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile index 8885650647ff..3d6cc7b67a80 100644 --- a/drivers/net/phy/Makefile +++ b/drivers/net/phy/Makefile @@ -13,3 +13,4 @@ obj-$(CONFIG_VITESSE_PHY) += vitesse.o obj-$(CONFIG_BROADCOM_PHY) += broadcom.o obj-$(CONFIG_ICPLUS_PHY) += icplus.o obj-$(CONFIG_FIXED_PHY) += fixed.o +obj-$(CONFIG_MDIO_BITBANG) += mdio-bitbang.o diff --git a/drivers/net/phy/mdio-bitbang.c b/drivers/net/phy/mdio-bitbang.c new file mode 100644 index 000000000000..8cd243d92af3 --- /dev/null +++ b/drivers/net/phy/mdio-bitbang.c @@ -0,0 +1,187 @@ +/* + * Bitbanged MDIO support. + * + * Author: Scott Wood + * Copyright (c) 2007 Freescale Semiconductor + * + * Based on CPM2 MDIO code which is: + * + * Copyright (c) 2003 Intracom S.A. + * by Pantelis Antoniou + * + * 2005 (c) MontaVista Software, Inc. + * Vitaly Bordug + * + * This file is licensed under the terms of the GNU General Public License + * version 2. This program is licensed "as is" without any warranty of any + * kind, whether express or implied. + */ + +#include +#include +#include +#include +#include + +#define MDIO_READ 1 +#define MDIO_WRITE 0 + +#define MDIO_SETUP_TIME 10 +#define MDIO_HOLD_TIME 10 + +/* Minimum MDC period is 400 ns, plus some margin for error. MDIO_DELAY + * is done twice per period. + */ +#define MDIO_DELAY 250 + +/* The PHY may take up to 300 ns to produce data, plus some margin + * for error. + */ +#define MDIO_READ_DELAY 350 + +/* MDIO must already be configured as output. */ +static void mdiobb_send_bit(struct mdiobb_ctrl *ctrl, int val) +{ + const struct mdiobb_ops *ops = ctrl->ops; + + ops->set_mdio_data(ctrl, val); + ndelay(MDIO_DELAY); + ops->set_mdc(ctrl, 1); + ndelay(MDIO_DELAY); + ops->set_mdc(ctrl, 0); +} + +/* MDIO must already be configured as input. */ +static int mdiobb_get_bit(struct mdiobb_ctrl *ctrl) +{ + const struct mdiobb_ops *ops = ctrl->ops; + + ndelay(MDIO_DELAY); + ops->set_mdc(ctrl, 1); + ndelay(MDIO_READ_DELAY); + ops->set_mdc(ctrl, 0); + + return ops->get_mdio_data(ctrl); +} + +/* MDIO must already be configured as output. */ +static void mdiobb_send_num(struct mdiobb_ctrl *ctrl, u16 val, int bits) +{ + int i; + + for (i = bits - 1; i >= 0; i--) + mdiobb_send_bit(ctrl, (val >> i) & 1); +} + +/* MDIO must already be configured as input. */ +static u16 mdiobb_get_num(struct mdiobb_ctrl *ctrl, int bits) +{ + int i; + u16 ret = 0; + + for (i = bits - 1; i >= 0; i--) { + ret <<= 1; + ret |= mdiobb_get_bit(ctrl); + } + + return ret; +} + +/* Utility to send the preamble, address, and + * register (common to read and write). + */ +static void mdiobb_cmd(struct mdiobb_ctrl *ctrl, int read, u8 phy, u8 reg) +{ + const struct mdiobb_ops *ops = ctrl->ops; + int i; + + ops->set_mdio_dir(ctrl, 1); + + /* + * Send a 32 bit preamble ('1's) with an extra '1' bit for good + * measure. The IEEE spec says this is a PHY optional + * requirement. The AMD 79C874 requires one after power up and + * one after a MII communications error. This means that we are + * doing more preambles than we need, but it is safer and will be + * much more robust. + */ + + for (i = 0; i < 32; i++) + mdiobb_send_bit(ctrl, 1); + + /* send the start bit (01) and the read opcode (10) or write (10) */ + mdiobb_send_bit(ctrl, 0); + mdiobb_send_bit(ctrl, 1); + mdiobb_send_bit(ctrl, read); + mdiobb_send_bit(ctrl, !read); + + mdiobb_send_num(ctrl, phy, 5); + mdiobb_send_num(ctrl, reg, 5); +} + + +static int mdiobb_read(struct mii_bus *bus, int phy, int reg) +{ + struct mdiobb_ctrl *ctrl = bus->priv; + int ret, i; + + mdiobb_cmd(ctrl, MDIO_READ, phy, reg); + ctrl->ops->set_mdio_dir(ctrl, 0); + + /* check the turnaround bit: the PHY should be driving it to zero */ + if (mdiobb_get_bit(ctrl) != 0) { + /* PHY didn't drive TA low -- flush any bits it + * may be trying to send. + */ + for (i = 0; i < 32; i++) + mdiobb_get_bit(ctrl); + + return 0xffff; + } + + ret = mdiobb_get_num(ctrl, 16); + mdiobb_get_bit(ctrl); + return ret; +} + +static int mdiobb_write(struct mii_bus *bus, int phy, int reg, u16 val) +{ + struct mdiobb_ctrl *ctrl = bus->priv; + + mdiobb_cmd(ctrl, MDIO_WRITE, phy, reg); + + /* send the turnaround (10) */ + mdiobb_send_bit(ctrl, 1); + mdiobb_send_bit(ctrl, 0); + + mdiobb_send_num(ctrl, val, 16); + + ctrl->ops->set_mdio_dir(ctrl, 0); + mdiobb_get_bit(ctrl); + return 0; +} + +struct mii_bus *alloc_mdio_bitbang(struct mdiobb_ctrl *ctrl) +{ + struct mii_bus *bus; + + bus = kzalloc(sizeof(struct mii_bus), GFP_KERNEL); + if (!bus) + return NULL; + + __module_get(ctrl->ops->owner); + + bus->read = mdiobb_read; + bus->write = mdiobb_write; + bus->priv = ctrl; + + return bus; +} + +void free_mdio_bitbang(struct mii_bus *bus) +{ + struct mdiobb_ctrl *ctrl = bus->priv; + + module_put(ctrl->ops->owner); + kfree(bus); +} diff --git a/include/linux/mdio-bitbang.h b/include/linux/mdio-bitbang.h new file mode 100644 index 000000000000..8ea9a42a4c02 --- /dev/null +++ b/include/linux/mdio-bitbang.h @@ -0,0 +1,42 @@ +#ifndef __LINUX_MDIO_BITBANG_H +#define __LINUX_MDIO_BITBANG_H + +#include +#include + +struct mdiobb_ctrl; + +struct mdiobb_ops { + struct module *owner; + + /* Set the Management Data Clock high if level is one, + * low if level is zero. + */ + void (*set_mdc)(struct mdiobb_ctrl *ctrl, int level); + + /* Configure the Management Data I/O pin as an input if + * "output" is zero, or an output if "output" is one. + */ + void (*set_mdio_dir)(struct mdiobb_ctrl *ctrl, int output); + + /* Set the Management Data I/O pin high if value is one, + * low if "value" is zero. This may only be called + * when the MDIO pin is configured as an output. + */ + void (*set_mdio_data)(struct mdiobb_ctrl *ctrl, int value); + + /* Retrieve the state Management Data I/O pin. */ + int (*get_mdio_data)(struct mdiobb_ctrl *ctrl); +}; + +struct mdiobb_ctrl { + const struct mdiobb_ops *ops; +}; + +/* The returned bus is not yet registered with the phy layer. */ +struct mii_bus *alloc_mdio_bitbang(struct mdiobb_ctrl *ctrl); + +/* The bus must already have been unregistered. */ +void free_mdio_bitbang(struct mii_bus *bus); + +#endif -- cgit v1.2.3 From 135900c182c321a4888ec496b014e6707272faca Mon Sep 17 00:00:00 2001 From: Michael Buesch Date: Thu, 27 Sep 2007 21:33:12 +0200 Subject: [RFKILL]: Add support for an rfkill LED. This adds a LED trigger. Signed-off-by: Michael Buesch Acked-by: Ivo van Doorn Signed-off-by: John W. Linville Signed-off-by: David S. Miller --- include/linux/rfkill.h | 21 +++++++++++++++++++++ net/rfkill/Kconfig | 7 +++++++ net/rfkill/rfkill.c | 42 +++++++++++++++++++++++++++++++++++++++++- 3 files changed, 69 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/rfkill.h b/include/linux/rfkill.h index d76397ca95ad..26fddea12c25 100644 --- a/include/linux/rfkill.h +++ b/include/linux/rfkill.h @@ -26,6 +26,7 @@ #include #include #include +#include /** * enum rfkill_type - type of rfkill switch. @@ -56,6 +57,7 @@ enum rfkill_state { * @data: Pointer to the RF button drivers private data which will be * passed along when toggling radio state. * @toggle_radio(): Mandatory handler to control state of the radio. + * @led_trigger: A LED trigger for this button's LED. * @dev: Device structure integrating the switch into device tree. * @node: Used to place switch into list of all switches known to the * the system. @@ -74,6 +76,10 @@ struct rfkill { void *data; int (*toggle_radio)(void *data, enum rfkill_state state); +#ifdef CONFIG_RFKILL_LEDS + struct led_trigger led_trigger; +#endif + struct device dev; struct list_head node; }; @@ -84,4 +90,19 @@ void rfkill_free(struct rfkill *rfkill); int rfkill_register(struct rfkill *rfkill); void rfkill_unregister(struct rfkill *rfkill); +/** + * rfkill_get_led_name - Get the LED trigger name for the button's LED. + * This function might return a NULL pointer if registering of the + * LED trigger failed. + * Use this as "default_trigger" for the LED. + */ +static inline char *rfkill_get_led_name(struct rfkill *rfkill) +{ +#ifdef CONFIG_RFKILL_LEDS + return (char *)(rfkill->led_trigger.name); +#else + return NULL; +#endif +} + #endif /* RFKILL_H */ diff --git a/net/rfkill/Kconfig b/net/rfkill/Kconfig index d28a6d9303e4..7f807b30cfbb 100644 --- a/net/rfkill/Kconfig +++ b/net/rfkill/Kconfig @@ -22,3 +22,10 @@ config RFKILL_INPUT To compile this driver as a module, choose M here: the module will be called rfkill-input. + +# LED trigger support +config RFKILL_LEDS + bool + depends on RFKILL && LEDS_TRIGGERS + default y + diff --git a/net/rfkill/rfkill.c b/net/rfkill/rfkill.c index 637a9f0c7655..a8c5e0b914e4 100644 --- a/net/rfkill/rfkill.c +++ b/net/rfkill/rfkill.c @@ -37,6 +37,22 @@ static DEFINE_MUTEX(rfkill_mutex); static enum rfkill_state rfkill_states[RFKILL_TYPE_MAX]; + +static void rfkill_led_trigger(struct rfkill *rfkill, + enum rfkill_state state) +{ +#ifdef CONFIG_RFKILL_LEDS + struct led_trigger *led = &rfkill->led_trigger; + + if (!led->name) + return; + if (state == RFKILL_STATE_OFF) + led_trigger_event(led, LED_OFF); + else + led_trigger_event(led, LED_FULL); +#endif /* CONFIG_RFKILL_LEDS */ +} + static int rfkill_toggle_radio(struct rfkill *rfkill, enum rfkill_state state) { @@ -48,8 +64,10 @@ static int rfkill_toggle_radio(struct rfkill *rfkill, if (state != rfkill->state) { retval = rfkill->toggle_radio(rfkill->data, state); - if (!retval) + if (!retval) { rfkill->state = state; + rfkill_led_trigger(rfkill, state); + } } mutex_unlock(&rfkill->mutex); @@ -328,6 +346,26 @@ void rfkill_free(struct rfkill *rfkill) } EXPORT_SYMBOL(rfkill_free); +static void rfkill_led_trigger_register(struct rfkill *rfkill) +{ +#ifdef CONFIG_RFKILL_LEDS + int error; + + rfkill->led_trigger.name = rfkill->dev.bus_id; + error = led_trigger_register(&rfkill->led_trigger); + if (error) + rfkill->led_trigger.name = NULL; +#endif /* CONFIG_RFKILL_LEDS */ +} + +static void rfkill_led_trigger_unregister(struct rfkill *rfkill) +{ +#ifdef CONFIG_RFKILL_LEDS + if (rfkill->led_trigger.name) + led_trigger_unregister(&rfkill->led_trigger); +#endif +} + /** * rfkill_register - Register a rfkill structure. * @rfkill: rfkill structure to be registered @@ -357,6 +395,7 @@ int rfkill_register(struct rfkill *rfkill) rfkill_remove_switch(rfkill); return error; } + rfkill_led_trigger_register(rfkill); return 0; } @@ -372,6 +411,7 @@ EXPORT_SYMBOL(rfkill_register); */ void rfkill_unregister(struct rfkill *rfkill) { + rfkill_led_trigger_unregister(rfkill); device_del(&rfkill->dev); rfkill_remove_switch(rfkill); put_device(&rfkill->dev); -- cgit v1.2.3 From 20405c08412a4d89357870d7220f9fb1c458b286 Mon Sep 17 00:00:00 2001 From: Michael Buesch Date: Thu, 27 Sep 2007 21:34:23 +0200 Subject: [RFKILL]: Add support for hardware-only rfkill buttons Buttons that work directly on hardware cannot support the "user_claim" functionality. Add a flag to signal this and return -EOPNOTSUPP in this case. b43 is such a device. Signed-off-by: Michael Buesch Acked-by: Ivo van Doorn Signed-off-by: John W. Linville Signed-off-by: David S. Miller --- include/linux/rfkill.h | 3 +++ net/rfkill/rfkill.c | 7 ++++++- 2 files changed, 9 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/rfkill.h b/include/linux/rfkill.h index 26fddea12c25..0ce5e0b52dbd 100644 --- a/include/linux/rfkill.h +++ b/include/linux/rfkill.h @@ -52,6 +52,8 @@ enum rfkill_state { * @type: Radio type which the button controls, the value stored * here should be a value from enum rfkill_type. * @state: State of the switch (on/off). + * @user_claim_unsupported: Whether the hardware supports exclusive + * RF-kill control by userspace. Set this before registering. * @user_claim: Set when the switch is controlled exlusively by userspace. * @mutex: Guards switch state transitions * @data: Pointer to the RF button drivers private data which will be @@ -69,6 +71,7 @@ struct rfkill { enum rfkill_type type; enum rfkill_state state; + bool user_claim_unsupported; bool user_claim; struct mutex mutex; diff --git a/net/rfkill/rfkill.c b/net/rfkill/rfkill.c index a8c5e0b914e4..51d151c0e962 100644 --- a/net/rfkill/rfkill.c +++ b/net/rfkill/rfkill.c @@ -190,6 +190,10 @@ static ssize_t rfkill_claim_store(struct device *dev, if (error) return error; + if (rfkill->user_claim_unsupported) { + error = -EOPNOTSUPP; + goto out_unlock; + } if (rfkill->user_claim != claim) { if (!claim) rfkill_toggle_radio(rfkill, @@ -197,9 +201,10 @@ static ssize_t rfkill_claim_store(struct device *dev, rfkill->user_claim = claim; } +out_unlock: mutex_unlock(&rfkill_mutex); - return count; + return error ? error : count; } static struct device_attribute rfkill_dev_attrs[] = { -- cgit v1.2.3 From 7c559a9e44ee61faf2f339604ce708decb345a93 Mon Sep 17 00:00:00 2001 From: Gerrit Renker Date: Thu, 4 Oct 2007 14:39:22 -0700 Subject: [DCCP]: Add socket option to query the current MPS This enables applications to query the current value of the Maximum Packet Size via a socket option, suggested as a SHOULD in (RFC 4340, p. 102). This socket option is useful to avoid the annoying bail-out via `-EMSGSIZE'. In particular, as fragmentation is not currently supported (and its use is partly discouraged in RFC 4340). With this option, it is possible to size buffers accordingly, e.g. int buflen = dccp_get_cur_mps(sockfd); /* or */ if (msgsize > dccp_get_cur_mps(sockfd)) die("message is too large for this path"); Signed-off-by: Gerrit Renker Signed-off-by: Ian McDonald Signed-off-by: Arnaldo Carvalho de Melo Signed-off-by: David S. Miller --- Documentation/networking/dccp.txt | 3 +++ include/linux/dccp.h | 1 + net/dccp/proto.c | 4 ++++ 3 files changed, 8 insertions(+) (limited to 'include/linux') diff --git a/Documentation/networking/dccp.txt b/Documentation/networking/dccp.txt index 477026ae0ffb..f9157180f7d8 100644 --- a/Documentation/networking/dccp.txt +++ b/Documentation/networking/dccp.txt @@ -41,6 +41,9 @@ the socket will fall back to 0 (which means that no meaningful service code is present). Connecting sockets set at most one service option; for listening sockets, multiple service codes can be specified. +DCCP_SOCKOPT_GET_CUR_MPS is read-only and retrieves the current maximum packet +size (application payload size) in bytes, see RFC 4340, section 14. + DCCP_SOCKOPT_SEND_CSCOV and DCCP_SOCKOPT_RECV_CSCOV are used for setting the partial checksum coverage (RFC 4340, sec. 9.2). The default is that checksums always cover the entire packet and that only fully covered application data is diff --git a/include/linux/dccp.h b/include/linux/dccp.h index 4ed82e2c9f65..0e44a3e5208d 100644 --- a/include/linux/dccp.h +++ b/include/linux/dccp.h @@ -202,6 +202,7 @@ struct dccp_so_feat { #define DCCP_SOCKOPT_SERVICE 2 #define DCCP_SOCKOPT_CHANGE_L 3 #define DCCP_SOCKOPT_CHANGE_R 4 +#define DCCP_SOCKOPT_GET_CUR_MPS 5 #define DCCP_SOCKOPT_SEND_CSCOV 10 #define DCCP_SOCKOPT_RECV_CSCOV 11 #define DCCP_SOCKOPT_CCID_RX_INFO 128 diff --git a/net/dccp/proto.c b/net/dccp/proto.c index 7e4f54a4ecaf..c0b685efe245 100644 --- a/net/dccp/proto.c +++ b/net/dccp/proto.c @@ -587,6 +587,10 @@ static int do_dccp_getsockopt(struct sock *sk, int level, int optname, case DCCP_SOCKOPT_SERVICE: return dccp_getsockopt_service(sk, len, (__be32 __user *)optval, optlen); + case DCCP_SOCKOPT_GET_CUR_MPS: + val = dp->dccps_mss_cache; + len = sizeof(val); + break; case DCCP_SOCKOPT_SEND_CSCOV: val = dp->dccps_pcslen; len = sizeof(val); -- cgit v1.2.3 From 451bc0473f010babeadd888ae8ec1015959fd1b2 Mon Sep 17 00:00:00 2001 From: Gerrit Renker Date: Thu, 4 Oct 2007 14:43:42 -0700 Subject: [DCCP]: Tidy-up -- minisock initialisation This * removes a declaration of a non-existent function __dccp_minisock_init; * shifts the initialisation function dccp_minisock_init() from options.c to minisocks.c, where it is more naturally expected to be. Signed-off-by: Gerrit Renker Signed-off-by: Ian McDonald Signed-off-by: Arnaldo Carvalho de Melo Signed-off-by: David S. Miller --- include/linux/dccp.h | 1 - net/dccp/minisocks.c | 10 ++++++++++ net/dccp/options.c | 10 ---------- 3 files changed, 10 insertions(+), 11 deletions(-) (limited to 'include/linux') diff --git a/include/linux/dccp.h b/include/linux/dccp.h index 0e44a3e5208d..f3fc4392e93d 100644 --- a/include/linux/dccp.h +++ b/include/linux/dccp.h @@ -391,7 +391,6 @@ struct dccp_opt_pend { struct dccp_opt_conf *dccpop_sc; }; -extern void __dccp_minisock_init(struct dccp_minisock *dmsk); extern void dccp_minisock_init(struct dccp_minisock *dmsk); extern int dccp_parse_options(struct sock *sk, struct sk_buff *skb); diff --git a/net/dccp/minisocks.c b/net/dccp/minisocks.c index 91685990d57e..831b76e08d02 100644 --- a/net/dccp/minisocks.c +++ b/net/dccp/minisocks.c @@ -42,6 +42,16 @@ struct inet_timewait_death_row dccp_death_row = { EXPORT_SYMBOL_GPL(dccp_death_row); +void dccp_minisock_init(struct dccp_minisock *dmsk) +{ + dmsk->dccpms_sequence_window = sysctl_dccp_feat_sequence_window; + dmsk->dccpms_rx_ccid = sysctl_dccp_feat_rx_ccid; + dmsk->dccpms_tx_ccid = sysctl_dccp_feat_tx_ccid; + dmsk->dccpms_ack_ratio = sysctl_dccp_feat_ack_ratio; + dmsk->dccpms_send_ack_vector = sysctl_dccp_feat_send_ack_vector; + dmsk->dccpms_send_ndp_count = sysctl_dccp_feat_send_ndp_count; +} + void dccp_time_wait(struct sock *sk, int state, int timeo) { struct inet_timewait_sock *tw = NULL; diff --git a/net/dccp/options.c b/net/dccp/options.c index a57fcbd7d03c..172eb6ba8702 100644 --- a/net/dccp/options.c +++ b/net/dccp/options.c @@ -29,16 +29,6 @@ int sysctl_dccp_feat_ack_ratio = DCCPF_INITIAL_ACK_RATIO; int sysctl_dccp_feat_send_ack_vector = DCCPF_INITIAL_SEND_ACK_VECTOR; int sysctl_dccp_feat_send_ndp_count = DCCPF_INITIAL_SEND_NDP_COUNT; -void dccp_minisock_init(struct dccp_minisock *dmsk) -{ - dmsk->dccpms_sequence_window = sysctl_dccp_feat_sequence_window; - dmsk->dccpms_rx_ccid = sysctl_dccp_feat_rx_ccid; - dmsk->dccpms_tx_ccid = sysctl_dccp_feat_tx_ccid; - dmsk->dccpms_ack_ratio = sysctl_dccp_feat_ack_ratio; - dmsk->dccpms_send_ack_vector = sysctl_dccp_feat_send_ack_vector; - dmsk->dccpms_send_ndp_count = sysctl_dccp_feat_send_ndp_count; -} - static u32 dccp_decode_value_var(const unsigned char *bf, const u8 len) { u32 value = 0; -- cgit v1.2.3 From 9974a356b204833b32173210ca25edfdc24dcdd5 Mon Sep 17 00:00:00 2001 From: Matt Carlson Date: Sun, 7 Oct 2007 23:27:28 -0700 Subject: [TG3]: Walk PCI capability lists. Newer tg3 devices shuffle around the registers in PCI configuration space. This patch changes the way the driver accesses the PCI capabilities registers. Hardcoded register locations are replaced with offsets from pci_find_capability() return values. Signed-off-by: Matt Carlson Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/tg3.c | 48 +++++++++++++++++++++++++++++++++++------------- drivers/net/tg3.h | 28 ++-------------------------- include/linux/pci_regs.h | 13 +++++++++++++ 3 files changed, 50 insertions(+), 39 deletions(-) (limited to 'include/linux') diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index d4ac6e9ef6db..4f9fbe268ec9 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -4865,9 +4865,15 @@ static void tg3_restore_pci_state(struct tg3 *tp) pci_write_config_dword(tp->pdev, TG3PCI_COMMAND, tp->pci_cmd); /* Make sure PCI-X relaxed ordering bit is clear. */ - pci_read_config_dword(tp->pdev, TG3PCI_X_CAPS, &val); - val &= ~PCIX_CAPS_RELAXED_ORDERING; - pci_write_config_dword(tp->pdev, TG3PCI_X_CAPS, val); + if (tp->pcix_cap) { + u16 pcix_cmd; + + pci_read_config_word(tp->pdev, tp->pcix_cap + PCI_X_CMD, + &pcix_cmd); + pcix_cmd &= ~PCI_X_CMD_ERO; + pci_write_config_word(tp->pdev, tp->pcix_cap + PCI_X_CMD, + pcix_cmd); + } if (tp->tg3_flags2 & TG3_FLG2_5780_CLASS) { @@ -6574,16 +6580,20 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy) tw32_f(WDMAC_MODE, val); udelay(40); - if ((tp->tg3_flags & TG3_FLAG_PCIX_MODE) != 0) { - val = tr32(TG3PCI_X_CAPS); + if (tp->tg3_flags & TG3_FLAG_PCIX_MODE) { + u16 pcix_cmd; + + pci_read_config_word(tp->pdev, tp->pcix_cap + PCI_X_CMD, + &pcix_cmd); if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5703) { - val &= ~PCIX_CAPS_BURST_MASK; - val |= (PCIX_CAPS_MAX_BURST_CPIOB << PCIX_CAPS_BURST_SHIFT); + pcix_cmd &= ~PCI_X_CMD_MAX_READ; + pcix_cmd |= PCI_X_CMD_READ_2K; } else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704) { - val &= ~(PCIX_CAPS_SPLIT_MASK | PCIX_CAPS_BURST_MASK); - val |= (PCIX_CAPS_MAX_BURST_CPIOB << PCIX_CAPS_BURST_SHIFT); + pcix_cmd &= ~(PCI_X_CMD_MAX_SPLIT | PCI_X_CMD_MAX_READ); + pcix_cmd |= PCI_X_CMD_READ_2K; } - tw32(TG3PCI_X_CAPS, val); + pci_write_config_word(tp->pdev, tp->pcix_cap + PCI_X_CMD, + pcix_cmd); } tw32_f(RDMAC_MODE, rdmac_mode); @@ -10712,10 +10722,20 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) cacheline_sz_reg); } + if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS) || + (tp->tg3_flags2 & TG3_FLG2_5780_CLASS)) { + tp->pcix_cap = pci_find_capability(tp->pdev, PCI_CAP_ID_PCIX); + if (!tp->pcix_cap) { + printk(KERN_ERR PFX "Cannot find PCI-X " + "capability, aborting.\n"); + return -EIO; + } + } + pci_read_config_dword(tp->pdev, TG3PCI_PCISTATE, &pci_state_reg); - if ((pci_state_reg & PCISTATE_CONV_PCI_MODE) == 0) { + if (tp->pcix_cap && (pci_state_reg & PCISTATE_CONV_PCI_MODE) == 0) { tp->tg3_flags |= TG3_FLAG_PCIX_MODE; /* If this is a 5700 BX chipset, and we are in PCI-X @@ -10733,11 +10753,13 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) * space registers clobbered due to this bug. * So explicitly force the chip into D0 here. */ - pci_read_config_dword(tp->pdev, TG3PCI_PM_CTRL_STAT, + pci_read_config_dword(tp->pdev, + tp->pm_cap + PCI_PM_CTRL, &pm_reg); pm_reg &= ~PCI_PM_CTRL_STATE_MASK; pm_reg |= PCI_PM_CTRL_PME_ENABLE | 0 /* D0 */; - pci_write_config_dword(tp->pdev, TG3PCI_PM_CTRL_STAT, + pci_write_config_dword(tp->pdev, + tp->pm_cap + PCI_PM_CTRL, pm_reg); /* Also, force SERR#/PERR# in PCI command. */ diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h index a6a23bbcdfee..c4f845dd1e8b 100644 --- a/drivers/net/tg3.h +++ b/drivers/net/tg3.h @@ -57,32 +57,7 @@ #define TG3PCI_IRQ_PIN 0x0000003d #define TG3PCI_MIN_GNT 0x0000003e #define TG3PCI_MAX_LAT 0x0000003f -#define TG3PCI_X_CAPS 0x00000040 -#define PCIX_CAPS_RELAXED_ORDERING 0x00020000 -#define PCIX_CAPS_SPLIT_MASK 0x00700000 -#define PCIX_CAPS_SPLIT_SHIFT 20 -#define PCIX_CAPS_BURST_MASK 0x000c0000 -#define PCIX_CAPS_BURST_SHIFT 18 -#define PCIX_CAPS_MAX_BURST_CPIOB 2 -#define TG3PCI_PM_CAP_PTR 0x00000041 -#define TG3PCI_X_COMMAND 0x00000042 -#define TG3PCI_X_STATUS 0x00000044 -#define TG3PCI_PM_CAP_ID 0x00000048 -#define TG3PCI_VPD_CAP_PTR 0x00000049 -#define TG3PCI_PM_CAPS 0x0000004a -#define TG3PCI_PM_CTRL_STAT 0x0000004c -#define TG3PCI_BR_SUPP_EXT 0x0000004e -#define TG3PCI_PM_DATA 0x0000004f -#define TG3PCI_VPD_CAP_ID 0x00000050 -#define TG3PCI_MSI_CAP_PTR 0x00000051 -#define TG3PCI_VPD_ADDR_FLAG 0x00000052 -#define VPD_ADDR_FLAG_WRITE 0x00008000 -#define TG3PCI_VPD_DATA 0x00000054 -#define TG3PCI_MSI_CAP_ID 0x00000058 -#define TG3PCI_NXT_CAP_PTR 0x00000059 -#define TG3PCI_MSI_CTRL 0x0000005a -#define TG3PCI_MSI_ADDR_LOW 0x0000005c -#define TG3PCI_MSI_ADDR_HIGH 0x00000060 +/* 0x40 --> 0x64 unused */ #define TG3PCI_MSI_DATA 0x00000064 /* 0x66 --> 0x68 unused */ #define TG3PCI_MISC_HOST_CTRL 0x00000068 @@ -2318,6 +2293,7 @@ struct tg3 { int pm_cap; int msi_cap; + int pcix_cap; /* PHY info */ u32 phy_id; diff --git a/include/linux/pci_regs.h b/include/linux/pci_regs.h index 495d368390e0..423d592c55d5 100644 --- a/include/linux/pci_regs.h +++ b/include/linux/pci_regs.h @@ -316,7 +316,20 @@ #define PCI_X_CMD 2 /* Modes & Features */ #define PCI_X_CMD_DPERR_E 0x0001 /* Data Parity Error Recovery Enable */ #define PCI_X_CMD_ERO 0x0002 /* Enable Relaxed Ordering */ +#define PCI_X_CMD_READ_512 0x0000 /* 512 byte maximum read byte count */ +#define PCI_X_CMD_READ_1K 0x0004 /* 1Kbyte maximum read byte count */ +#define PCI_X_CMD_READ_2K 0x0008 /* 2Kbyte maximum read byte count */ +#define PCI_X_CMD_READ_4K 0x000c /* 4Kbyte maximum read byte count */ #define PCI_X_CMD_MAX_READ 0x000c /* Max Memory Read Byte Count */ + /* Max # of outstanding split transactions */ +#define PCI_X_CMD_SPLIT_1 0x0000 /* Max 1 */ +#define PCI_X_CMD_SPLIT_2 0x0010 /* Max 2 */ +#define PCI_X_CMD_SPLIT_3 0x0020 /* Max 3 */ +#define PCI_X_CMD_SPLIT_4 0x0030 /* Max 4 */ +#define PCI_X_CMD_SPLIT_8 0x0040 /* Max 8 */ +#define PCI_X_CMD_SPLIT_12 0x0050 /* Max 12 */ +#define PCI_X_CMD_SPLIT_16 0x0060 /* Max 16 */ +#define PCI_X_CMD_SPLIT_32 0x0070 /* Max 32 */ #define PCI_X_CMD_MAX_SPLIT 0x0070 /* Max Outstanding Split Transactions */ #define PCI_X_CMD_VERSION(x) (((x) >> 12) & 3) /* Version */ #define PCI_X_STATUS 4 /* PCI-X capabilities */ -- cgit v1.2.3 From d30cdd28fba556143a4bb0d1a6097ebcc2891477 Mon Sep 17 00:00:00 2001 From: Matt Carlson Date: Sun, 7 Oct 2007 23:28:35 -0700 Subject: [TG3]: Add 5784 and 5764 support. This patch adds the support for 5784 and 5764 devices. Signed-off-by: Matt Carlson Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/tg3.c | 53 +++++++++++++++++++++++++++++++++++++++---------- drivers/net/tg3.h | 14 ++++++++++++- include/linux/pci_ids.h | 2 ++ 3 files changed, 57 insertions(+), 12 deletions(-) (limited to 'include/linux') diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 482b7df55247..2378ea3f357a 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -198,6 +198,8 @@ static struct pci_device_id tg3_pci_tbl[] = { {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5781)}, {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5906)}, {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5906M)}, + {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5784)}, + {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5764)}, {PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, PCI_DEVICE_ID_SYSKONNECT_9DXX)}, {PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, PCI_DEVICE_ID_SYSKONNECT_9MXX)}, {PCI_DEVICE(PCI_VENDOR_ID_ALTIMA, PCI_DEVICE_ID_ALTIMA_AC1000)}, @@ -4921,7 +4923,8 @@ static int tg3_chip_reset(struct tg3 *tp) if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5752 || GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755 || - GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787) + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787 || + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784) tw32(GRC_FASTBOOT_PC, 0); /* @@ -6146,6 +6149,12 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy) tg3_write_sig_legacy(tp, RESET_KIND_INIT); + if (tp->pci_chip_rev_id == CHIPREV_ID_5784_A0) { + val = tr32(TG3_CPMU_CTRL); + val &= ~(CPMU_CTRL_LINK_AWARE_MODE | CPMU_CTRL_LINK_IDLE_MODE); + tw32(TG3_CPMU_CTRL, val); + } + /* This works around an issue with Athlon chipsets on * B3 tigon3 silicon. This bit has no effect on any * other revision. But do not set this on PCI Express @@ -6180,10 +6189,12 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy) if (err) return err; - /* This value is determined during the probe time DMA - * engine test, tg3_test_dma. - */ - tw32(TG3PCI_DMA_RW_CTRL, tp->dma_rwctrl); + if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5784) { + /* This value is determined during the probe time DMA + * engine test, tg3_test_dma. + */ + tw32(TG3PCI_DMA_RW_CTRL, tp->dma_rwctrl); + } tp->grc_mode &= ~(GRC_MODE_HOST_SENDBDS | GRC_MODE_4X_NIC_SEND_RINGS | @@ -6417,6 +6428,11 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy) RDMAC_MODE_FIFOURUN_ENAB | RDMAC_MODE_FIFOOREAD_ENAB | RDMAC_MODE_LNGREAD_ENAB); + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784) + rdmac_mode |= RDMAC_MODE_BD_SBD_CRPT_ENAB | + RDMAC_MODE_MBUF_RBD_CRPT_ENAB | + RDMAC_MODE_MBUF_SBD_CRPT_ENAB; + /* If statement applies to 5705 and 5750 PCI devices only */ if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705 && tp->pci_chip_rev_id != CHIPREV_ID_5705_A0) || @@ -6578,7 +6594,8 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy) /* Enable host coalescing bug fix */ if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755) || - (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787)) + (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787) || + (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784)) val |= (1 << 29); tw32_f(WDMAC_MODE, val); @@ -8353,7 +8370,8 @@ static int tg3_set_tx_csum(struct net_device *dev, u32 data) } if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755 || - GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787) + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787 || + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784) ethtool_op_set_tx_ipv6_csum(dev, data); else ethtool_op_set_tx_csum(dev, data); @@ -8849,7 +8867,8 @@ static int tg3_test_memory(struct tg3 *tp) if (tp->tg3_flags2 & TG3_FLG2_5705_PLUS) { if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755 || - GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787) + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787 || + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784) mem_tbl = mem_tbl_5755; else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) mem_tbl = mem_tbl_5906; @@ -9600,7 +9619,8 @@ static void __devinit tg3_nvram_init(struct tg3 *tp) tg3_get_5752_nvram_info(tp); else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755) tg3_get_5755_nvram_info(tp); - else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787) + else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787 || + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784) tg3_get_5787_nvram_info(tp); else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) tg3_get_5906_nvram_info(tp); @@ -9913,6 +9933,7 @@ static int tg3_nvram_write_block_buffered(struct tg3 *tp, u32 offset, u32 len, if ((GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5752) && (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5755) && (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5787) && + (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5784) && (tp->nvram_jedecnum == JEDEC_ST) && (nvram_cmd & NVRAM_CMD_FIRST)) { @@ -10657,6 +10678,7 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5752 || GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755 || GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787 || + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784 || GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906 || (tp->tg3_flags2 & TG3_FLG2_5780_CLASS)) tp->tg3_flags2 |= TG3_FLG2_5750_PLUS; @@ -10676,6 +10698,7 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755 || GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787 || + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784 || GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) { tp->tg3_flags2 |= TG3_FLG2_HW_TSO_2; tp->tg3_flags2 |= TG3_FLG2_1SHOT_MSI; @@ -10693,6 +10716,7 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5752 && GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5755 && GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5787 && + GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5784 && GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5906) tp->tg3_flags2 |= TG3_FLG2_JUMBO_CAPABLE; @@ -10868,6 +10892,9 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) */ tg3_get_eeprom_hw_cfg(tp); + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784) + tp->tg3_flags |= TG3_FLAG_CPMU_PRESENT; + /* Set up tp->grc_local_ctrl before calling tg3_set_power_state(). * GPIO1 driven high will bring 5700's external PHY out of reset. * It is also used as eeprom write protect on LOMs. @@ -10934,7 +10961,8 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) if (tp->tg3_flags2 & TG3_FLG2_5705_PLUS) { if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755 || - GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787) { + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787 || + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784) { if (tp->pdev->device != PCI_DEVICE_ID_TIGON3_5756 && tp->pdev->device != PCI_DEVICE_ID_TIGON3_5722) tp->tg3_flags2 |= TG3_FLG2_PHY_JITTER_BUG; @@ -11077,6 +11105,7 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) */ if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755 || GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787 || + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784 || GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) tp->dev->hard_start_xmit = tg3_start_xmit; else @@ -11698,6 +11727,7 @@ static char * __devinit tg3_phy_string(struct tg3 *tp) case PHY_ID_BCM5780: return "5780"; case PHY_ID_BCM5755: return "5755"; case PHY_ID_BCM5787: return "5787"; + case PHY_ID_BCM5784: return "5784"; case PHY_ID_BCM5756: return "5722/5756"; case PHY_ID_BCM5906: return "5906"; case PHY_ID_BCM8002: return "8002/serdes"; @@ -12042,7 +12072,8 @@ static int __devinit tg3_init_one(struct pci_dev *pdev, if ((tp->tg3_flags & TG3_FLAG_BROKEN_CHECKSUMS) == 0) { dev->features |= NETIF_F_IP_CSUM | NETIF_F_SG; if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755 || - GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787) + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787 || + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784) dev->features |= NETIF_F_IPV6_CSUM; tp->tg3_flags |= TG3_FLAG_RX_CHECKSUMS; diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h index 79ce68cf836b..d8e829f6fcb2 100644 --- a/drivers/net/tg3.h +++ b/drivers/net/tg3.h @@ -108,6 +108,7 @@ #define CHIPREV_ID_5752_A1 0x6001 #define CHIPREV_ID_5714_A2 0x9002 #define CHIPREV_ID_5906_A1 0xc001 +#define CHIPREV_ID_5784_A0 0x5784000 #define GET_ASIC_REV(CHIP_REV_ID) ((CHIP_REV_ID) >> 12) #define ASIC_REV_5700 0x07 #define ASIC_REV_5701 0x00 @@ -122,6 +123,7 @@ #define ASIC_REV_5787 0x0b #define ASIC_REV_5906 0x0c #define ASIC_REV_USE_PROD_ID_REG 0x0f +#define ASIC_REV_5784 0x5784 #define GET_CHIP_REV(CHIP_REV_ID) ((CHIP_REV_ID) >> 8) #define CHIPREV_5700_AX 0x70 #define CHIPREV_5700_BX 0x71 @@ -843,7 +845,13 @@ #define RCVLSC_MODE_ATTN_ENABLE 0x00000004 #define RCVLSC_STATUS 0x00003404 #define RCVLSC_STATUS_ERROR_ATTN 0x00000004 -/* 0x3408 --> 0x3800 unused */ +/* 0x3408 --> 0x3600 unused */ + +/* CPMU registers */ +#define TG3_CPMU_CTRL 0x00003600 +#define CPMU_CTRL_LINK_IDLE_MODE 0x00000200 +#define CPMU_CTRL_LINK_AWARE_MODE 0x00000400 +/* 0x3604 --> 0x3800 unused */ /* Mbuf cluster free registers */ #define MBFREE_MODE 0x00003800 @@ -1023,7 +1031,10 @@ #define RDMAC_MODE_FIFOOREAD_ENAB 0x00000100 #define RDMAC_MODE_LNGREAD_ENAB 0x00000200 #define RDMAC_MODE_SPLIT_ENABLE 0x00000800 +#define RDMAC_MODE_BD_SBD_CRPT_ENAB 0x00000800 #define RDMAC_MODE_SPLIT_RESET 0x00001000 +#define RDMAC_MODE_MBUF_RBD_CRPT_ENAB 0x00001000 +#define RDMAC_MODE_MBUF_SBD_CRPT_ENAB 0x00002000 #define RDMAC_MODE_FIFO_SIZE_128 0x00020000 #define RDMAC_MODE_FIFO_LONG_BURST 0x00030000 #define RDMAC_STATUS 0x00004804 @@ -2315,6 +2326,7 @@ struct tg3 { #define PHY_ID_BCM5755 0xbc050cc0 #define PHY_ID_BCM5787 0xbc050ce0 #define PHY_ID_BCM5756 0xbc050ed0 +#define PHY_ID_BCM5784 0xbc050fa0 #define PHY_ID_BCM5906 0xdc00ac40 #define PHY_ID_BCM8002 0x60010140 #define PHY_ID_INVALID 0xffffffff diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index 9ebc2c70c5d4..6f5fa39c8290 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -1950,8 +1950,10 @@ #define PCI_DEVICE_ID_TIGON3_5751M 0x167d #define PCI_DEVICE_ID_TIGON3_5751F 0x167e #define PCI_DEVICE_ID_TIGON3_5787F 0x167f +#define PCI_DEVICE_ID_TIGON3_5764 0x1684 #define PCI_DEVICE_ID_TIGON3_5787M 0x1693 #define PCI_DEVICE_ID_TIGON3_5782 0x1696 +#define PCI_DEVICE_ID_TIGON3_5784 0x1698 #define PCI_DEVICE_ID_TIGON3_5786 0x169a #define PCI_DEVICE_ID_TIGON3_5787 0x169b #define PCI_DEVICE_ID_TIGON3_5788 0x169c -- cgit v1.2.3 From c79e3357166a2ca39fd7613b0eb7f493c1ac5e11 Mon Sep 17 00:00:00 2001 From: Ilpo Järvinen Date: Sun, 7 Oct 2007 23:37:25 -0700 Subject: [TCP]: Comment fastpath_cnt_hint off-by-one trap MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Ilpo Järvinen Signed-off-by: David S. Miller --- include/linux/tcp.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/tcp.h b/include/linux/tcp.h index f8cf090e8f49..9ff456e8d6c7 100644 --- a/include/linux/tcp.h +++ b/include/linux/tcp.h @@ -343,7 +343,8 @@ struct tcp_sock { struct sk_buff *forward_skb_hint; struct sk_buff *fastpath_skb_hint; - int fastpath_cnt_hint; + int fastpath_cnt_hint; /* Lags behind by current skb's pcount + * compared to respective fackets_out */ int lost_cnt_hint; int retransmit_cnt_hint; -- cgit v1.2.3 From d62a38d1ab350f787e4941e42a3d3e97971e38f5 Mon Sep 17 00:00:00 2001 From: Karsten Keil Date: Mon, 8 Oct 2007 20:37:11 -0700 Subject: [ISDN]: Change I4L to use alloc_netdev(). Signed-off-by: Karsten Keil Signed-off-by: David S. Miller --- drivers/isdn/i4l/isdn_net.c | 169 +++++++++++++++++++++++--------------------- drivers/isdn/i4l/isdn_ppp.c | 6 +- include/linux/isdn.h | 2 +- 3 files changed, 92 insertions(+), 85 deletions(-) (limited to 'include/linux') diff --git a/drivers/isdn/i4l/isdn_net.c b/drivers/isdn/i4l/isdn_net.c index 54546604656d..7c9cb7e19f2e 100644 --- a/drivers/isdn/i4l/isdn_net.c +++ b/drivers/isdn/i4l/isdn_net.c @@ -77,7 +77,7 @@ static __inline__ int isdn_net_device_started(isdn_net_dev *n) if (lp->master) dev = lp->master; else - dev = &n->dev; + dev = n->dev; return netif_running(dev); } @@ -90,7 +90,7 @@ static __inline__ void isdn_net_device_wake_queue(isdn_net_local *lp) if (lp->master) netif_wake_queue(lp->master); else - netif_wake_queue(&lp->netdev->dev); + netif_wake_queue(lp->netdev->dev); } /* @@ -102,7 +102,7 @@ static __inline__ void isdn_net_device_stop_queue(isdn_net_local *lp) if (lp->master) netif_stop_queue(lp->master); else - netif_stop_queue(&lp->netdev->dev); + netif_stop_queue(lp->netdev->dev); } /* @@ -287,7 +287,7 @@ isdn_net_unbind_channel(isdn_net_local * lp) BEWARE! This chunk of code cannot be called from hardware interrupt handler. I hope it is true. --ANK */ - qdisc_reset(lp->netdev->dev.qdisc); + qdisc_reset(lp->netdev->dev->qdisc); } lp->dialstate = 0; dev->rx_netdev[isdn_dc2minor(lp->isdn_device, lp->isdn_channel)] = NULL; @@ -345,27 +345,27 @@ isdn_net_autohup(void) l->chargetime += l->chargeint; if (time_after(jiffies, l->chargetime + l->chargeint - 2 * HZ)) if (l->outgoing || l->hupflags & ISDN_INHUP) - isdn_net_hangup(&p->dev); + isdn_net_hangup(p->dev); } else if (l->outgoing) { if (l->hupflags & ISDN_CHARGEHUP) { if (l->hupflags & ISDN_WAITCHARGE) { printk(KERN_DEBUG "isdn_net: Hupflags of %s are %X\n", l->name, l->hupflags); - isdn_net_hangup(&p->dev); + isdn_net_hangup(p->dev); } else if (time_after(jiffies, l->chargetime + l->chargeint)) { printk(KERN_DEBUG "isdn_net: %s: chtime = %lu, chint = %d\n", l->name, l->chargetime, l->chargeint); - isdn_net_hangup(&p->dev); + isdn_net_hangup(p->dev); } } else - isdn_net_hangup(&p->dev); + isdn_net_hangup(p->dev); } else if (l->hupflags & ISDN_INHUP) - isdn_net_hangup(&p->dev); + isdn_net_hangup(p->dev); } if(dev->global_flags & ISDN_GLOBAL_STOPPED || (ISDN_NET_DIALMODE(*l) == ISDN_NET_DM_OFF)) { - isdn_net_hangup(&p->dev); + isdn_net_hangup(p->dev); break; } } @@ -579,7 +579,7 @@ isdn_net_dial(void) if (!lp->dial) { printk(KERN_WARNING "%s: phone number deleted?\n", lp->name); - isdn_net_hangup(&p->dev); + isdn_net_hangup(p->dev); break; } anymore = 1; @@ -616,8 +616,8 @@ isdn_net_dial(void) s = "dial suppressed: isdn system stopped"; else s = "dial suppressed: dialmode `off'"; - isdn_net_unreachable(&p->dev, NULL, s); - isdn_net_hangup(&p->dev); + isdn_net_unreachable(p->dev, NULL, s); + isdn_net_hangup(p->dev); break; } cmd.driver = lp->isdn_device; @@ -633,7 +633,7 @@ isdn_net_dial(void) if (!lp->dial) { printk(KERN_WARNING "%s: phone number deleted?\n", lp->name); - isdn_net_hangup(&p->dev); + isdn_net_hangup(p->dev); break; } if (!strncmp(lp->dial->num, "LEASED", strlen("LEASED"))) { @@ -644,8 +644,8 @@ isdn_net_dial(void) if (time_after(jiffies, lp->dialstarted + lp->dialtimeout)) { lp->dialwait_timer = jiffies + lp->dialwait; lp->dialstarted = 0; - isdn_net_unreachable(&p->dev, NULL, "dial: timed out"); - isdn_net_hangup(&p->dev); + isdn_net_unreachable(p->dev, NULL, "dial: timed out"); + isdn_net_hangup(p->dev); break; } @@ -674,9 +674,9 @@ isdn_net_dial(void) if (lp->dialtimeout == 0) { lp->dialwait_timer = jiffies + lp->dialwait; lp->dialstarted = 0; - isdn_net_unreachable(&p->dev, NULL, "dial: tried all numbers dialmax times"); + isdn_net_unreachable(p->dev, NULL, "dial: tried all numbers dialmax times"); } - isdn_net_hangup(&p->dev); + isdn_net_hangup(p->dev); break; } } @@ -758,7 +758,7 @@ isdn_net_dial(void) cmd.arg = lp->isdn_channel + (lp->l3_proto << 8); isdn_command(&cmd); if (lp->dtimer++ > ISDN_TIMER_DTIMEOUT15) - isdn_net_hangup(&p->dev); + isdn_net_hangup(p->dev); else { anymore = 1; lp->dialstate++; @@ -781,7 +781,7 @@ isdn_net_dial(void) printk(KERN_DEBUG "dialtimer4: %d\n", lp->dtimer); #endif if (lp->dtimer++ > ISDN_TIMER_DTIMEOUT10) - isdn_net_hangup(&p->dev); + isdn_net_hangup(p->dev); else anymore = 1; break; @@ -1618,7 +1618,7 @@ isdn_net_ciscohdlck_slarp_send_reply(isdn_net_local *lp) __be32 addr = 0; /* local ipv4 address */ __be32 mask = 0; /* local netmask */ - if ((in_dev = lp->netdev->dev.ip_ptr) != NULL) { + if ((in_dev = lp->netdev->dev->ip_ptr) != NULL) { /* take primary(first) address of interface */ struct in_ifaddr *ifa = in_dev->ifa_list; if (ifa != NULL) { @@ -1866,7 +1866,7 @@ isdn_net_rcv_skb(int idx, struct sk_buff *skb) isdn_net_local *lp = p->local; if ((lp->flags & ISDN_NET_CONNECTED) && (!lp->dialstate)) { - isdn_net_receive(&p->dev, skb); + isdn_net_receive(p->dev, skb); return 1; } } @@ -2506,6 +2506,42 @@ isdn_net_force_dial(char *name) return (isdn_net_force_dial_lp(p->local)); } +/* + * Helper for alloc_netdev() + */ +static void _isdn_setup(struct net_device *dev) +{ + isdn_net_local *lp = dev->priv; + + dev->flags = IFF_NOARP | IFF_POINTOPOINT; + lp->p_encap = ISDN_NET_ENCAP_RAWIP; + lp->magic = ISDN_NET_MAGIC; + lp->last = lp; + lp->next = lp; + lp->isdn_device = -1; + lp->isdn_channel = -1; + lp->pre_device = -1; + lp->pre_channel = -1; + lp->exclusive = -1; + lp->ppp_slot = -1; + lp->pppbind = -1; + skb_queue_head_init(&lp->super_tx_queue); + lp->l2_proto = ISDN_PROTO_L2_X75I; + lp->l3_proto = ISDN_PROTO_L3_TRANS; + lp->triggercps = 6000; + lp->slavedelay = 10 * HZ; + lp->hupflags = ISDN_INHUP; /* Do hangup even on incoming calls */ + lp->onhtime = 10; /* Default hangup-time for saving costs */ + lp->dialmax = 1; + /* Hangup before Callback, manual dial */ + lp->flags = ISDN_NET_CBHUP | ISDN_NET_DM_MANUAL; + lp->cbdelay = 25; /* Wait 5 secs before Callback */ + lp->dialtimeout = -1; /* Infinite Dial-Timeout */ + lp->dialwait = 5 * HZ; /* Wait 5 sec. after failed dial */ + lp->dialstarted = 0; /* Jiffies of last dial-start */ + lp->dialwait_timer = 0; /* Jiffies of earliest next dial-start */ +} + /* * Allocate a new network-interface and initialize its data structures. */ @@ -2519,23 +2555,21 @@ isdn_net_new(char *name, struct net_device *master) printk(KERN_WARNING "isdn_net: interface %s already exists\n", name); return NULL; } + if (name == NULL) + name = " "; if (!(netdev = kzalloc(sizeof(isdn_net_dev), GFP_KERNEL))) { printk(KERN_WARNING "isdn_net: Could not allocate net-device\n"); return NULL; } - if (!(netdev->local = kzalloc(sizeof(isdn_net_local), GFP_KERNEL))) { - printk(KERN_WARNING "isdn_net: Could not allocate device locals\n"); + netdev->dev = alloc_netdev(sizeof(isdn_net_local), name, _isdn_setup); + if (!netdev->dev) { + printk(KERN_WARNING "isdn_net: Could not allocate network device\n"); kfree(netdev); return NULL; } - if (name == NULL) - strcpy(netdev->local->name, " "); - else - strcpy(netdev->local->name, name); - strcpy(netdev->dev.name, netdev->local->name); - netdev->dev.priv = netdev->local; - netdev->dev.init = isdn_net_init; - netdev->local->p_encap = ISDN_NET_ENCAP_RAWIP; + netdev->local = netdev->dev->priv; + strcpy(netdev->local->name, netdev->dev->name); + netdev->dev->init = isdn_net_init; if (master) { /* Device shall be a slave */ struct net_device *p = (((isdn_net_local *) master->priv)->slave); @@ -2547,60 +2581,33 @@ isdn_net_new(char *name, struct net_device *master) q = p; p = (((isdn_net_local *) p->priv)->slave); } - ((isdn_net_local *) q->priv)->slave = &(netdev->dev); + ((isdn_net_local *) q->priv)->slave = netdev->dev; } else { /* Device shall be a master */ /* * Watchdog timer (currently) for master only. */ - netdev->dev.tx_timeout = isdn_net_tx_timeout; - netdev->dev.watchdog_timeo = ISDN_NET_TX_TIMEOUT; - if (register_netdev(&netdev->dev) != 0) { + netdev->dev->tx_timeout = isdn_net_tx_timeout; + netdev->dev->watchdog_timeo = ISDN_NET_TX_TIMEOUT; + if (register_netdev(netdev->dev) != 0) { printk(KERN_WARNING "isdn_net: Could not register net-device\n"); - kfree(netdev->local); + free_netdev(netdev->dev); kfree(netdev); return NULL; } } - netdev->local->magic = ISDN_NET_MAGIC; - netdev->queue = netdev->local; spin_lock_init(&netdev->queue_lock); - netdev->local->last = netdev->local; netdev->local->netdev = netdev; - netdev->local->next = netdev->local; INIT_WORK(&netdev->local->tqueue, isdn_net_softint); spin_lock_init(&netdev->local->xmit_lock); - netdev->local->isdn_device = -1; - netdev->local->isdn_channel = -1; - netdev->local->pre_device = -1; - netdev->local->pre_channel = -1; - netdev->local->exclusive = -1; - netdev->local->ppp_slot = -1; - netdev->local->pppbind = -1; - skb_queue_head_init(&netdev->local->super_tx_queue); - netdev->local->l2_proto = ISDN_PROTO_L2_X75I; - netdev->local->l3_proto = ISDN_PROTO_L3_TRANS; - netdev->local->triggercps = 6000; - netdev->local->slavedelay = 10 * HZ; - netdev->local->hupflags = ISDN_INHUP; /* Do hangup even on incoming calls */ - netdev->local->onhtime = 10; /* Default hangup-time for saving costs - of those who forget configuring this */ - netdev->local->dialmax = 1; - netdev->local->flags = ISDN_NET_CBHUP | ISDN_NET_DM_MANUAL; /* Hangup before Callback, manual dial */ - netdev->local->cbdelay = 25; /* Wait 5 secs before Callback */ - netdev->local->dialtimeout = -1; /* Infinite Dial-Timeout */ - netdev->local->dialwait = 5 * HZ; /* Wait 5 sec. after failed dial */ - netdev->local->dialstarted = 0; /* Jiffies of last dial-start */ - netdev->local->dialwait_timer = 0; /* Jiffies of earliest next dial-start */ - /* Put into to netdev-chain */ netdev->next = (void *) dev->netdev; dev->netdev = netdev; - return netdev->dev.name; + return netdev->dev->name; } char * @@ -2625,7 +2632,7 @@ isdn_net_newslave(char *parm) /* Master must not be started yet */ if (isdn_net_device_started(n)) return NULL; - return (isdn_net_new(newname, &(n->dev))); + return (isdn_net_new(newname, n->dev)); } return NULL; } @@ -2694,9 +2701,9 @@ isdn_net_setcfg(isdn_net_ioctl_cfg * cfg) lp->name); return -EINVAL; #else - p->dev.type = ARPHRD_PPP; /* change ARP type */ - p->dev.addr_len = 0; - p->dev.do_ioctl = isdn_ppp_dev_ioctl; + p->dev->type = ARPHRD_PPP; /* change ARP type */ + p->dev->addr_len = 0; + p->dev->do_ioctl = isdn_ppp_dev_ioctl; #endif break; case ISDN_NET_ENCAP_X25IFACE: @@ -2705,12 +2712,12 @@ isdn_net_setcfg(isdn_net_ioctl_cfg * cfg) p->local->name); return -EINVAL; #else - p->dev.type = ARPHRD_X25; /* change ARP type */ - p->dev.addr_len = 0; + p->dev->type = ARPHRD_X25; /* change ARP type */ + p->dev->addr_len = 0; #endif break; case ISDN_NET_ENCAP_CISCOHDLCK: - p->dev.do_ioctl = isdn_ciscohdlck_dev_ioctl; + p->dev->do_ioctl = isdn_ciscohdlck_dev_ioctl; break; default: if( cfg->p_encap >= 0 && @@ -2837,14 +2844,14 @@ isdn_net_setcfg(isdn_net_ioctl_cfg * cfg) } if (cfg->p_encap != lp->p_encap) { if (cfg->p_encap == ISDN_NET_ENCAP_RAWIP) { - p->dev.header_ops = NULL; - p->dev.flags = IFF_NOARP|IFF_POINTOPOINT; + p->dev->header_ops = NULL; + p->dev->flags = IFF_NOARP|IFF_POINTOPOINT; } else { - p->dev.header_ops = &isdn_header_ops; + p->dev->header_ops = &isdn_header_ops; if (cfg->p_encap == ISDN_NET_ENCAP_ETHER) - p->dev.flags = IFF_BROADCAST | IFF_MULTICAST; + p->dev->flags = IFF_BROADCAST | IFF_MULTICAST; else - p->dev.flags = IFF_NOARP|IFF_POINTOPOINT; + p->dev->flags = IFF_NOARP|IFF_POINTOPOINT; } } lp->p_encap = cfg->p_encap; @@ -3064,7 +3071,7 @@ isdn_net_force_hangup(char *name) isdn_net_hangup(q); q = (((isdn_net_local *) q->priv)->slave); } - isdn_net_hangup(&p->dev); + isdn_net_hangup(p->dev); return 0; } return -ENODEV; @@ -3092,11 +3099,11 @@ isdn_net_realrm(isdn_net_dev * p, isdn_net_dev * q) isdn_unexclusive_channel(p->local->pre_device, p->local->pre_channel); if (p->local->master) { /* It's a slave-device, so update master's slave-pointer if necessary */ - if (((isdn_net_local *) (p->local->master->priv))->slave == &p->dev) + if (((isdn_net_local *) (p->local->master->priv))->slave == p->dev) ((isdn_net_local *) (p->local->master->priv))->slave = p->local->slave; } else { /* Unregister only if it's a master-device */ - unregister_netdev(&p->dev); + unregister_netdev(p->dev); } /* Unlink device from chain */ spin_lock_irqsave(&dev->lock, flags); @@ -3124,7 +3131,7 @@ isdn_net_realrm(isdn_net_dev * p, isdn_net_dev * q) /* If no more net-devices remain, disable auto-hangup timer */ if (dev->netdev == NULL) isdn_timer_ctrl(ISDN_TIMER_NETHANGUP, 0); - kfree(p->local); + free_netdev(p->dev); kfree(p); return 0; diff --git a/drivers/isdn/i4l/isdn_ppp.c b/drivers/isdn/i4l/isdn_ppp.c index 387392cb3d68..0e5e59f84344 100644 --- a/drivers/isdn/i4l/isdn_ppp.c +++ b/drivers/isdn/i4l/isdn_ppp.c @@ -360,7 +360,7 @@ isdn_ppp_release(int min, struct file *file) * isdn_ppp_free() sets is->lp to NULL and lp->ppp_slot to -1 * removing the IPPP_CONNECT flag omits calling of isdn_ppp_wakeup_daemon() */ - isdn_net_hangup(&p->dev); + isdn_net_hangup(p->dev); } for (i = 0; i < NUM_RCV_BUFFS; i++) { kfree(is->rq[i].buf); @@ -531,7 +531,7 @@ isdn_ppp_ioctl(int min, struct file *file, unsigned int cmd, unsigned long arg) if (lp) { /* OK .. we are ready to send buffers */ is->pppcfg = val; /* isdn_ppp_xmit test for SC_ENABLE_IP !!! */ - netif_wake_queue(&lp->netdev->dev); + netif_wake_queue(lp->netdev->dev); break; } } @@ -1023,7 +1023,7 @@ void isdn_ppp_receive(isdn_net_dev * net_dev, isdn_net_local * lp, struct sk_buf static void isdn_ppp_push_higher(isdn_net_dev * net_dev, isdn_net_local * lp, struct sk_buff *skb, int proto) { - struct net_device *dev = &net_dev->dev; + struct net_device *dev = net_dev->dev; struct ippp_struct *is, *mis; isdn_net_local *mlp = NULL; int slot; diff --git a/include/linux/isdn.h b/include/linux/isdn.h index a6fb366748bb..ad09506554a3 100644 --- a/include/linux/isdn.h +++ b/include/linux/isdn.h @@ -382,7 +382,7 @@ typedef struct isdn_net_dev_s { online */ spinlock_t queue_lock; /* lock to protect queue */ void *next; /* Pointer to next isdn-interface */ - struct net_device dev; /* interface to upper levels */ + struct net_device *dev; /* interface to upper levels */ #ifdef CONFIG_ISDN_PPP ippp_bundle * pb; /* pointer to the common bundle structure * with the per-bundle data */ -- cgit v1.2.3 From 4665079cbb2a3e17de82f2ab2940b9f97f37d65e Mon Sep 17 00:00:00 2001 From: Pavel Emelyanov Date: Mon, 8 Oct 2007 20:38:39 -0700 Subject: [NETNS]: Move some code into __init section when CONFIG_NET_NS=n With the net namespaces many code leaved the __init section, thus making the kernel occupy more memory than it did before. Since we have a config option that prohibits the namespace creation, the functions that initialize/finalize some netns stuff are simply not needed and can be freed after the boot. Currently, this is almost not noticeable, since few calls are no longer in __init, but when the namespaces will be merged it will be possible to free more code. I propose to use the __net_init, __net_exit and __net_initdata "attributes" for functions/variables that are not used if the CONFIG_NET_NS is not set to save more space in memory. The exiting functions cannot just reside in the __exit section, as noticed by David, since the init section will have references on it and the compilation will fail due to modpost checks. These references can exist, since the init namespace never dies and the exit callbacks are never called. So I introduce the __exit_refok attribute just like it is already done with the __init_refok. Signed-off-by: Pavel Emelyanov Signed-off-by: David S. Miller --- drivers/net/loopback.c | 6 +++--- fs/proc/proc_net.c | 8 ++++---- include/linux/init.h | 1 + include/net/net_namespace.h | 9 +++++++++ net/core/dev.c | 16 ++++++++-------- net/core/dev_mcast.c | 6 +++--- net/netlink/af_netlink.c | 6 +++--- scripts/mod/modpost.c | 1 + 8 files changed, 32 insertions(+), 21 deletions(-) (limited to 'include/linux') diff --git a/drivers/net/loopback.c b/drivers/net/loopback.c index d6997aec45dd..be25aa33971c 100644 --- a/drivers/net/loopback.c +++ b/drivers/net/loopback.c @@ -250,7 +250,7 @@ static void loopback_setup(struct net_device *dev) } /* Setup and register the loopback device. */ -static int loopback_net_init(struct net *net) +static __net_init int loopback_net_init(struct net *net) { struct net_device *dev; int err; @@ -278,14 +278,14 @@ out_free_netdev: goto out; } -static void loopback_net_exit(struct net *net) +static __net_exit void loopback_net_exit(struct net *net) { struct net_device *dev = net->loopback_dev; unregister_netdev(dev); } -static struct pernet_operations loopback_net_ops = { +static struct pernet_operations __net_initdata loopback_net_ops = { .init = loopback_net_init, .exit = loopback_net_exit, }; diff --git a/fs/proc/proc_net.c b/fs/proc/proc_net.c index 85cc8e8bb862..2e91fb756e9a 100644 --- a/fs/proc/proc_net.c +++ b/fs/proc/proc_net.c @@ -140,7 +140,7 @@ static struct inode_operations proc_net_dir_inode_operations = { .setattr = proc_net_setattr, }; -static int proc_net_ns_init(struct net *net) +static __net_init int proc_net_ns_init(struct net *net) { struct proc_dir_entry *root, *netd, *net_statd; int err; @@ -178,19 +178,19 @@ free_root: goto out; } -static void proc_net_ns_exit(struct net *net) +static __net_exit void proc_net_ns_exit(struct net *net) { remove_proc_entry("stat", net->proc_net); remove_proc_entry("net", net->proc_net_root); kfree(net->proc_net_root); } -struct pernet_operations proc_net_ns_ops = { +struct pernet_operations __net_initdata proc_net_ns_ops = { .init = proc_net_ns_init, .exit = proc_net_ns_exit, }; -int proc_net_init(void) +int __init proc_net_init(void) { proc_net_shadow = proc_mkdir("net", NULL); proc_net_shadow->proc_iops = &proc_net_dir_inode_operations; diff --git a/include/linux/init.h b/include/linux/init.h index 74b1f43bf982..f8d9d0b5cffc 100644 --- a/include/linux/init.h +++ b/include/linux/init.h @@ -57,6 +57,7 @@ * The markers follow same syntax rules as __init / __initdata. */ #define __init_refok noinline __attribute__ ((__section__ (".text.init.refok"))) #define __initdata_refok __attribute__ ((__section__ (".data.init.refok"))) +#define __exit_refok noinline __attribute__ ((__section__ (".exit.text.refok"))) #ifdef MODULE #define __exit __attribute__ ((__section__(".exit.text"))) __cold diff --git a/include/net/net_namespace.h b/include/net/net_namespace.h index 934c840b5941..93aa87d32804 100644 --- a/include/net/net_namespace.h +++ b/include/net/net_namespace.h @@ -99,6 +99,15 @@ static inline void release_net(struct net *net) #define for_each_net(VAR) \ list_for_each_entry(VAR, &net_namespace_list, list) +#ifdef CONFIG_NET_NS +#define __net_init +#define __net_exit +#define __net_initdata +#else +#define __net_init __init +#define __net_exit __exit_refok +#define __net_initdata __initdata +#endif struct pernet_operations { struct list_head list; diff --git a/net/core/dev.c b/net/core/dev.c index 1aa07047826e..e7e728aea9f3 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -2611,7 +2611,7 @@ static const struct file_operations ptype_seq_fops = { }; -static int dev_proc_net_init(struct net *net) +static int __net_init dev_proc_net_init(struct net *net) { int rc = -ENOMEM; @@ -2636,7 +2636,7 @@ out_dev: goto out; } -static void dev_proc_net_exit(struct net *net) +static void __net_exit dev_proc_net_exit(struct net *net) { wext_proc_exit(net); @@ -2645,7 +2645,7 @@ static void dev_proc_net_exit(struct net *net) proc_net_remove(net, "dev"); } -static struct pernet_operations dev_proc_ops = { +static struct pernet_operations __net_initdata dev_proc_ops = { .init = dev_proc_net_init, .exit = dev_proc_net_exit, }; @@ -4278,7 +4278,7 @@ static struct hlist_head *netdev_create_hash(void) } /* Initialize per network namespace state */ -static int netdev_init(struct net *net) +static int __net_init netdev_init(struct net *net) { INIT_LIST_HEAD(&net->dev_base_head); rwlock_init(&dev_base_lock); @@ -4299,18 +4299,18 @@ err_name: return -ENOMEM; } -static void netdev_exit(struct net *net) +static void __net_exit netdev_exit(struct net *net) { kfree(net->dev_name_head); kfree(net->dev_index_head); } -static struct pernet_operations netdev_net_ops = { +static struct pernet_operations __net_initdata netdev_net_ops = { .init = netdev_init, .exit = netdev_exit, }; -static void default_device_exit(struct net *net) +static void __net_exit default_device_exit(struct net *net) { struct net_device *dev, *next; /* @@ -4336,7 +4336,7 @@ static void default_device_exit(struct net *net) rtnl_unlock(); } -static struct pernet_operations default_device_ops = { +static struct pernet_operations __net_initdata default_device_ops = { .exit = default_device_exit, }; diff --git a/net/core/dev_mcast.c b/net/core/dev_mcast.c index 896b0ca5aed7..15241cf48af8 100644 --- a/net/core/dev_mcast.c +++ b/net/core/dev_mcast.c @@ -273,19 +273,19 @@ static const struct file_operations dev_mc_seq_fops = { #endif -static int dev_mc_net_init(struct net *net) +static int __net_init dev_mc_net_init(struct net *net) { if (!proc_net_fops_create(net, "dev_mcast", 0, &dev_mc_seq_fops)) return -ENOMEM; return 0; } -static void dev_mc_net_exit(struct net *net) +static void __net_exit dev_mc_net_exit(struct net *net) { proc_net_remove(net, "dev_mcast"); } -static struct pernet_operations dev_mc_net_ops = { +static struct pernet_operations __net_initdata dev_mc_net_ops = { .init = dev_mc_net_init, .exit = dev_mc_net_exit, }; diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c index 46eb5ea1fbd7..3ef32825da71 100644 --- a/net/netlink/af_netlink.c +++ b/net/netlink/af_netlink.c @@ -1924,7 +1924,7 @@ static struct net_proto_family netlink_family_ops = { .owner = THIS_MODULE, /* for consistency 8) */ }; -static int netlink_net_init(struct net *net) +static int __net_init netlink_net_init(struct net *net) { #ifdef CONFIG_PROC_FS if (!proc_net_fops_create(net, "netlink", 0, &netlink_seq_fops)) @@ -1933,14 +1933,14 @@ static int netlink_net_init(struct net *net) return 0; } -static void netlink_net_exit(struct net *net) +static void __net_exit netlink_net_exit(struct net *net) { #ifdef CONFIG_PROC_FS proc_net_remove(net, "netlink"); #endif } -static struct pernet_operations netlink_net_ops = { +static struct pernet_operations __net_initdata netlink_net_ops = { .init = netlink_net_init, .exit = netlink_net_exit, }; diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 6c145d6e89de..0a4051fbd34e 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -709,6 +709,7 @@ static int secref_whitelist(const char *modname, const char *tosec, /* Check for pattern 0 */ if ((strncmp(fromsec, ".text.init.refok", strlen(".text.init.refok")) == 0) || + (strncmp(fromsec, ".exit.text.refok", strlen(".exit.text.refok")) == 0) || (strncmp(fromsec, ".data.init.refok", strlen(".data.init.refok")) == 0)) return 1; -- cgit v1.2.3 From bfe13f54f5028cff034e3b6247e9f433908f4f4f Mon Sep 17 00:00:00 2001 From: Roland Dreier Date: Tue, 9 Oct 2007 15:47:37 -0700 Subject: ibm_emac: Convert to use napi_struct independent of struct net_device Commit da3dedd9 ("[NET]: Make NAPI polling independent of struct net_device objects.") changed the interface to NAPI polling. Fix up the ibm_emac driver so that it works with this new interface. This is actually a nice cleanup because ibm_emac is one of the drivers that wants to have multiple NAPI structures for a single net_device. Tested with the internal MAC of a PowerPC 440SPe SoC with an AMCC 'Yucca' evaluation board. Signed-off-by: Roland Dreier Signed-off-by: Jeff Garzik --- drivers/net/ibm_emac/ibm_emac_mal.c | 48 +++++++++++++------------------------ drivers/net/ibm_emac/ibm_emac_mal.h | 2 +- include/linux/netdevice.h | 10 ++++++++ 3 files changed, 28 insertions(+), 32 deletions(-) (limited to 'include/linux') diff --git a/drivers/net/ibm_emac/ibm_emac_mal.c b/drivers/net/ibm_emac/ibm_emac_mal.c index cabd9846a5ee..4e49e8c4f871 100644 --- a/drivers/net/ibm_emac/ibm_emac_mal.c +++ b/drivers/net/ibm_emac/ibm_emac_mal.c @@ -207,10 +207,10 @@ static irqreturn_t mal_serr(int irq, void *dev_instance) static inline void mal_schedule_poll(struct ibm_ocp_mal *mal) { - if (likely(netif_rx_schedule_prep(&mal->poll_dev))) { + if (likely(napi_schedule_prep(&mal->napi))) { MAL_DBG2("%d: schedule_poll" NL, mal->def->index); mal_disable_eob_irq(mal); - __netif_rx_schedule(&mal->poll_dev); + __napi_schedule(&mal->napi); } else MAL_DBG2("%d: already in poll" NL, mal->def->index); } @@ -273,11 +273,11 @@ static irqreturn_t mal_rxde(int irq, void *dev_instance) return IRQ_HANDLED; } -static int mal_poll(struct net_device *ndev, int *budget) +static int mal_poll(struct napi_struct *napi, int budget) { - struct ibm_ocp_mal *mal = ndev->priv; + struct ibm_ocp_mal *mal = container_of(napi, struct ibm_ocp_mal, napi); struct list_head *l; - int rx_work_limit = min(ndev->quota, *budget), received = 0, done; + int received = 0; MAL_DBG2("%d: poll(%d) %d ->" NL, mal->def->index, *budget, rx_work_limit); @@ -295,38 +295,34 @@ static int mal_poll(struct net_device *ndev, int *budget) list_for_each(l, &mal->poll_list) { struct mal_commac *mc = list_entry(l, struct mal_commac, poll_list); - int n = mc->ops->poll_rx(mc->dev, rx_work_limit); + int n = mc->ops->poll_rx(mc->dev, budget); if (n) { received += n; - rx_work_limit -= n; - if (rx_work_limit <= 0) { - done = 0; + budget -= n; + if (budget <= 0) goto more_work; // XXX What if this is the last one ? - } } } /* We need to disable IRQs to protect from RXDE IRQ here */ local_irq_disable(); - __netif_rx_complete(ndev); + __napi_complete(napi); mal_enable_eob_irq(mal); local_irq_enable(); - done = 1; - /* Check for "rotting" packet(s) */ list_for_each(l, &mal->poll_list) { struct mal_commac *mc = list_entry(l, struct mal_commac, poll_list); if (unlikely(mc->ops->peek_rx(mc->dev) || mc->rx_stopped)) { MAL_DBG2("%d: rotting packet" NL, mal->def->index); - if (netif_rx_reschedule(ndev, received)) + if (napi_reschedule(napi)) mal_disable_eob_irq(mal); else MAL_DBG2("%d: already in poll list" NL, mal->def->index); - if (rx_work_limit > 0) + if (budget > 0) goto again; else goto more_work; @@ -335,12 +331,8 @@ static int mal_poll(struct net_device *ndev, int *budget) } more_work: - ndev->quota -= received; - *budget -= received; - - MAL_DBG2("%d: poll() %d <- %d" NL, mal->def->index, *budget, - done ? 0 : 1); - return done ? 0 : 1; + MAL_DBG2("%d: poll() %d <- %d" NL, mal->def->index, budget, received); + return received; } static void mal_reset(struct ibm_ocp_mal *mal) @@ -425,11 +417,8 @@ static int __init mal_probe(struct ocp_device *ocpdev) mal->def = ocpdev->def; INIT_LIST_HEAD(&mal->poll_list); - set_bit(__LINK_STATE_START, &mal->poll_dev.state); - mal->poll_dev.weight = CONFIG_IBM_EMAC_POLL_WEIGHT; - mal->poll_dev.poll = mal_poll; - mal->poll_dev.priv = mal; - atomic_set(&mal->poll_dev.refcnt, 1); + mal->napi.weight = CONFIG_IBM_EMAC_POLL_WEIGHT; + mal->napi.poll = mal_poll; INIT_LIST_HEAD(&mal->list); @@ -520,11 +509,8 @@ static void __exit mal_remove(struct ocp_device *ocpdev) MAL_DBG("%d: remove" NL, mal->def->index); - /* Syncronize with scheduled polling, - stolen from net/core/dev.c:dev_close() - */ - clear_bit(__LINK_STATE_START, &mal->poll_dev.state); - netif_poll_disable(&mal->poll_dev); + /* Synchronize with scheduled polling */ + napi_disable(&mal->napi); if (!list_empty(&mal->list)) { /* This is *very* bad */ diff --git a/drivers/net/ibm_emac/ibm_emac_mal.h b/drivers/net/ibm_emac/ibm_emac_mal.h index 64bc338acc6c..8f54d621994d 100644 --- a/drivers/net/ibm_emac/ibm_emac_mal.h +++ b/drivers/net/ibm_emac/ibm_emac_mal.h @@ -195,7 +195,7 @@ struct ibm_ocp_mal { dcr_host_t dcrhost; struct list_head poll_list; - struct net_device poll_dev; + struct napi_struct napi; struct list_head list; u32 tx_chan_mask; diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 91cd3f3db507..4848c7afa4e7 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -349,6 +349,16 @@ static inline void napi_schedule(struct napi_struct *n) __napi_schedule(n); } +/* Try to reschedule poll. Called by dev->poll() after napi_complete(). */ +static inline int napi_reschedule(struct napi_struct *napi) +{ + if (napi_schedule_prep(napi)) { + __napi_schedule(napi); + return 1; + } + return 0; +} + /** * napi_complete - NAPI processing complete * @n: napi context -- cgit v1.2.3 From 39699037a5c94d7cd1363dfe48a50c78c643fd9a Mon Sep 17 00:00:00 2001 From: Pavel Emelyanov Date: Wed, 10 Oct 2007 02:28:42 -0700 Subject: [FS] seq_file: Introduce the seq_open_private() This function allocates the zeroed chunk of memory and call seq_open(). The __seq_open_private() helper returns the allocated memory to make it possible for the caller to initialize it. Signed-off-by: Pavel Emelyanov Signed-off-by: David S. Miller --- fs/seq_file.c | 33 +++++++++++++++++++++++++++++++++ include/linux/seq_file.h | 2 ++ 2 files changed, 35 insertions(+) (limited to 'include/linux') diff --git a/fs/seq_file.c b/fs/seq_file.c index bbb19be260ce..ca71c115bdaa 100644 --- a/fs/seq_file.c +++ b/fs/seq_file.c @@ -429,6 +429,39 @@ int seq_release_private(struct inode *inode, struct file *file) } EXPORT_SYMBOL(seq_release_private); +void *__seq_open_private(struct file *f, const struct seq_operations *ops, + int psize) +{ + int rc; + void *private; + struct seq_file *seq; + + private = kzalloc(psize, GFP_KERNEL); + if (private == NULL) + goto out; + + rc = seq_open(f, ops); + if (rc < 0) + goto out_free; + + seq = f->private_data; + seq->private = private; + return private; + +out_free: + kfree(private); +out: + return NULL; +} +EXPORT_SYMBOL(__seq_open_private); + +int seq_open_private(struct file *filp, const struct seq_operations *ops, + int psize) +{ + return __seq_open_private(filp, ops, psize) ? 0 : -ENOMEM; +} +EXPORT_SYMBOL(seq_open_private); + int seq_putc(struct seq_file *m, char c) { if (m->count < m->size) { diff --git a/include/linux/seq_file.h b/include/linux/seq_file.h index 83783ab0f552..8bf1e05115b4 100644 --- a/include/linux/seq_file.h +++ b/include/linux/seq_file.h @@ -46,6 +46,8 @@ int seq_path(struct seq_file *, struct vfsmount *, struct dentry *, char *); int single_open(struct file *, int (*)(struct seq_file *, void *), void *); int single_release(struct inode *, struct file *); +void *__seq_open_private(struct file *, const struct seq_operations *, int); +int seq_open_private(struct file *, const struct seq_operations *, int); int seq_release_private(struct inode *, struct file *); #define SEQ_START_TOKEN ((void *)1) -- cgit v1.2.3 From 1ae978208e2ee9ba1b01d309164bc5e590cd242d Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Thu, 30 Aug 2007 15:36:14 +0800 Subject: [CRYPTO] api: Add aead crypto type This patch adds crypto_aead which is the interface for AEAD (Authenticated Encryption with Associated Data) algorithms. AEAD algorithms perform authentication and encryption in one step. Traditionally users (such as IPsec) would use two different crypto algorithms to perform these. With AEAD this comes down to one algorithm and one operation. Of course if traditional algorithms were used we'd still be doing two operations underneath. However, real AEAD algorithms may allow the underlying operations to be optimised as well. Signed-off-by: Herbert Xu --- crypto/Kconfig | 4 + crypto/Makefile | 1 + crypto/aead.c | 101 ++++++++++++++++++++++++ include/crypto/algapi.h | 6 ++ include/linux/crypto.h | 200 ++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 312 insertions(+) create mode 100644 crypto/aead.c (limited to 'include/linux') diff --git a/crypto/Kconfig b/crypto/Kconfig index 981497c89752..f42bc7715f48 100644 --- a/crypto/Kconfig +++ b/crypto/Kconfig @@ -28,6 +28,10 @@ config CRYPTO_ABLKCIPHER tristate select CRYPTO_BLKCIPHER +config CRYPTO_AEAD + tristate + select CRYPTO_ALGAPI + config CRYPTO_BLKCIPHER tristate select CRYPTO_ALGAPI diff --git a/crypto/Makefile b/crypto/Makefile index a070dcc074ff..9821c5ba054e 100644 --- a/crypto/Makefile +++ b/crypto/Makefile @@ -9,6 +9,7 @@ crypto_algapi-objs := algapi.o $(crypto_algapi-y) obj-$(CONFIG_CRYPTO_ALGAPI) += crypto_algapi.o obj-$(CONFIG_CRYPTO_ABLKCIPHER) += ablkcipher.o +obj-$(CONFIG_CRYPTO_AEAD) += aead.o obj-$(CONFIG_CRYPTO_BLKCIPHER) += blkcipher.o crypto_hash-objs := hash.o diff --git a/crypto/aead.c b/crypto/aead.c new file mode 100644 index 000000000000..84a3501fb478 --- /dev/null +++ b/crypto/aead.c @@ -0,0 +1,101 @@ +/* + * AEAD: Authenticated Encryption with Associated Data + * + * This file provides API support for AEAD algorithms. + * + * Copyright (c) 2007 Herbert Xu + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + */ + +#include +#include +#include +#include +#include +#include +#include + +static int setkey_unaligned(struct crypto_aead *tfm, const u8 *key, + unsigned int keylen) +{ + struct aead_alg *aead = crypto_aead_alg(tfm); + unsigned long alignmask = crypto_aead_alignmask(tfm); + int ret; + u8 *buffer, *alignbuffer; + unsigned long absize; + + absize = keylen + alignmask; + buffer = kmalloc(absize, GFP_ATOMIC); + if (!buffer) + return -ENOMEM; + + alignbuffer = (u8 *)ALIGN((unsigned long)buffer, alignmask + 1); + memcpy(alignbuffer, key, keylen); + ret = aead->setkey(tfm, alignbuffer, keylen); + memset(alignbuffer, 0, keylen); + kfree(buffer); + return ret; +} + +static int setkey(struct crypto_aead *tfm, const u8 *key, unsigned int keylen) +{ + struct aead_alg *aead = crypto_aead_alg(tfm); + unsigned long alignmask = crypto_aead_alignmask(tfm); + + if ((unsigned long)key & alignmask) + return setkey_unaligned(tfm, key, keylen); + + return aead->setkey(tfm, key, keylen); +} + +static unsigned int crypto_aead_ctxsize(struct crypto_alg *alg, u32 type, + u32 mask) +{ + return alg->cra_ctxsize; +} + +static int crypto_init_aead_ops(struct crypto_tfm *tfm, u32 type, u32 mask) +{ + struct aead_alg *alg = &tfm->__crt_alg->cra_aead; + struct aead_tfm *crt = &tfm->crt_aead; + + if (max(alg->authsize, alg->ivsize) > PAGE_SIZE / 8) + return -EINVAL; + + crt->setkey = setkey; + crt->encrypt = alg->encrypt; + crt->decrypt = alg->decrypt; + crt->ivsize = alg->ivsize; + crt->authsize = alg->authsize; + + return 0; +} + +static void crypto_aead_show(struct seq_file *m, struct crypto_alg *alg) + __attribute__ ((unused)); +static void crypto_aead_show(struct seq_file *m, struct crypto_alg *alg) +{ + struct aead_alg *aead = &alg->cra_aead; + + seq_printf(m, "type : aead\n"); + seq_printf(m, "blocksize : %u\n", alg->cra_blocksize); + seq_printf(m, "ivsize : %u\n", aead->ivsize); + seq_printf(m, "authsize : %u\n", aead->authsize); +} + +const struct crypto_type crypto_aead_type = { + .ctxsize = crypto_aead_ctxsize, + .init = crypto_init_aead_ops, +#ifdef CONFIG_PROC_FS + .show = crypto_aead_show, +#endif +}; +EXPORT_SYMBOL_GPL(crypto_aead_type); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Authenticated Encryption with Associated Data (AEAD)"); diff --git a/include/crypto/algapi.h b/include/crypto/algapi.h index 8081294e4328..290bce0c5bd5 100644 --- a/include/crypto/algapi.h +++ b/include/crypto/algapi.h @@ -94,6 +94,7 @@ struct blkcipher_walk { }; extern const struct crypto_type crypto_ablkcipher_type; +extern const struct crypto_type crypto_aead_type; extern const struct crypto_type crypto_blkcipher_type; extern const struct crypto_type crypto_hash_type; @@ -165,6 +166,11 @@ static inline void *crypto_ablkcipher_ctx_aligned(struct crypto_ablkcipher *tfm) return crypto_tfm_ctx_aligned(&tfm->base); } +static inline struct aead_alg *crypto_aead_alg(struct crypto_aead *tfm) +{ + return &crypto_aead_tfm(tfm)->__crt_alg->cra_aead; +} + static inline struct crypto_blkcipher *crypto_spawn_blkcipher( struct crypto_spawn *spawn) { diff --git a/include/linux/crypto.h b/include/linux/crypto.h index 357e8cfedc37..1072f9abaef6 100644 --- a/include/linux/crypto.h +++ b/include/linux/crypto.h @@ -34,6 +34,7 @@ #define CRYPTO_ALG_TYPE_HASH 0x00000003 #define CRYPTO_ALG_TYPE_BLKCIPHER 0x00000004 #define CRYPTO_ALG_TYPE_COMPRESS 0x00000005 +#define CRYPTO_ALG_TYPE_AEAD 0x00000006 #define CRYPTO_ALG_TYPE_HASH_MASK 0x0000000e @@ -91,6 +92,7 @@ struct scatterlist; struct crypto_ablkcipher; struct crypto_async_request; +struct crypto_aead; struct crypto_blkcipher; struct crypto_hash; struct crypto_queue; @@ -121,6 +123,32 @@ struct ablkcipher_request { void *__ctx[] CRYPTO_MINALIGN_ATTR; }; +/** + * struct aead_request - AEAD request + * @base: Common attributes for async crypto requests + * @assoclen: Length in bytes of associated data for authentication + * @cryptlen: Length of data to be encrypted or decrypted + * @iv: Initialisation vector + * @assoc: Associated data + * @src: Source data + * @dst: Destination data + * @__ctx: Start of private context data + */ +struct aead_request { + struct crypto_async_request base; + + unsigned int assoclen; + unsigned int cryptlen; + + u8 *iv; + + struct scatterlist *assoc; + struct scatterlist *src; + struct scatterlist *dst; + + void *__ctx[] CRYPTO_MINALIGN_ATTR; +}; + struct blkcipher_desc { struct crypto_blkcipher *tfm; void *info; @@ -157,6 +185,16 @@ struct ablkcipher_alg { unsigned int ivsize; }; +struct aead_alg { + int (*setkey)(struct crypto_aead *tfm, const u8 *key, + unsigned int keylen); + int (*encrypt)(struct aead_request *req); + int (*decrypt)(struct aead_request *req); + + unsigned int ivsize; + unsigned int authsize; +}; + struct blkcipher_alg { int (*setkey)(struct crypto_tfm *tfm, const u8 *key, unsigned int keylen); @@ -212,6 +250,7 @@ struct compress_alg { }; #define cra_ablkcipher cra_u.ablkcipher +#define cra_aead cra_u.aead #define cra_blkcipher cra_u.blkcipher #define cra_cipher cra_u.cipher #define cra_digest cra_u.digest @@ -237,6 +276,7 @@ struct crypto_alg { union { struct ablkcipher_alg ablkcipher; + struct aead_alg aead; struct blkcipher_alg blkcipher; struct cipher_alg cipher; struct digest_alg digest; @@ -284,6 +324,16 @@ struct ablkcipher_tfm { unsigned int reqsize; }; +struct aead_tfm { + int (*setkey)(struct crypto_aead *tfm, const u8 *key, + unsigned int keylen); + int (*encrypt)(struct aead_request *req); + int (*decrypt)(struct aead_request *req); + unsigned int ivsize; + unsigned int authsize; + unsigned int reqsize; +}; + struct blkcipher_tfm { void *iv; int (*setkey)(struct crypto_tfm *tfm, const u8 *key, @@ -323,6 +373,7 @@ struct compress_tfm { }; #define crt_ablkcipher crt_u.ablkcipher +#define crt_aead crt_u.aead #define crt_blkcipher crt_u.blkcipher #define crt_cipher crt_u.cipher #define crt_hash crt_u.hash @@ -334,6 +385,7 @@ struct crypto_tfm { union { struct ablkcipher_tfm ablkcipher; + struct aead_tfm aead; struct blkcipher_tfm blkcipher; struct cipher_tfm cipher; struct hash_tfm hash; @@ -349,6 +401,10 @@ struct crypto_ablkcipher { struct crypto_tfm base; }; +struct crypto_aead { + struct crypto_tfm base; +}; + struct crypto_blkcipher { struct crypto_tfm base; }; @@ -619,6 +675,150 @@ static inline void ablkcipher_request_set_crypt( req->info = iv; } +static inline struct crypto_aead *__crypto_aead_cast(struct crypto_tfm *tfm) +{ + return (struct crypto_aead *)tfm; +} + +static inline struct crypto_aead *crypto_alloc_aead(const char *alg_name, + u32 type, u32 mask) +{ + type &= ~CRYPTO_ALG_TYPE_MASK; + type |= CRYPTO_ALG_TYPE_AEAD; + mask |= CRYPTO_ALG_TYPE_MASK; + + return __crypto_aead_cast(crypto_alloc_base(alg_name, type, mask)); +} + +static inline struct crypto_tfm *crypto_aead_tfm(struct crypto_aead *tfm) +{ + return &tfm->base; +} + +static inline void crypto_free_aead(struct crypto_aead *tfm) +{ + crypto_free_tfm(crypto_aead_tfm(tfm)); +} + +static inline struct aead_tfm *crypto_aead_crt(struct crypto_aead *tfm) +{ + return &crypto_aead_tfm(tfm)->crt_aead; +} + +static inline unsigned int crypto_aead_ivsize(struct crypto_aead *tfm) +{ + return crypto_aead_crt(tfm)->ivsize; +} + +static inline unsigned int crypto_aead_authsize(struct crypto_aead *tfm) +{ + return crypto_aead_crt(tfm)->authsize; +} + +static inline unsigned int crypto_aead_blocksize(struct crypto_aead *tfm) +{ + return crypto_tfm_alg_blocksize(crypto_aead_tfm(tfm)); +} + +static inline unsigned int crypto_aead_alignmask(struct crypto_aead *tfm) +{ + return crypto_tfm_alg_alignmask(crypto_aead_tfm(tfm)); +} + +static inline u32 crypto_aead_get_flags(struct crypto_aead *tfm) +{ + return crypto_tfm_get_flags(crypto_aead_tfm(tfm)); +} + +static inline void crypto_aead_set_flags(struct crypto_aead *tfm, u32 flags) +{ + crypto_tfm_set_flags(crypto_aead_tfm(tfm), flags); +} + +static inline void crypto_aead_clear_flags(struct crypto_aead *tfm, u32 flags) +{ + crypto_tfm_clear_flags(crypto_aead_tfm(tfm), flags); +} + +static inline int crypto_aead_setkey(struct crypto_aead *tfm, const u8 *key, + unsigned int keylen) +{ + return crypto_aead_crt(tfm)->setkey(tfm, key, keylen); +} + +static inline struct crypto_aead *crypto_aead_reqtfm(struct aead_request *req) +{ + return __crypto_aead_cast(req->base.tfm); +} + +static inline int crypto_aead_encrypt(struct aead_request *req) +{ + return crypto_aead_crt(crypto_aead_reqtfm(req))->encrypt(req); +} + +static inline int crypto_aead_decrypt(struct aead_request *req) +{ + return crypto_aead_crt(crypto_aead_reqtfm(req))->decrypt(req); +} + +static inline int crypto_aead_reqsize(struct crypto_aead *tfm) +{ + return crypto_aead_crt(tfm)->reqsize; +} + +static inline void aead_request_set_tfm(struct aead_request *req, + struct crypto_aead *tfm) +{ + req->base.tfm = crypto_aead_tfm(tfm); +} + +static inline struct aead_request *aead_request_alloc(struct crypto_aead *tfm, + gfp_t gfp) +{ + struct aead_request *req; + + req = kmalloc(sizeof(*req) + crypto_aead_reqsize(tfm), gfp); + + if (likely(req)) + aead_request_set_tfm(req, tfm); + + return req; +} + +static inline void aead_request_free(struct aead_request *req) +{ + kfree(req); +} + +static inline void aead_request_set_callback(struct aead_request *req, + u32 flags, + crypto_completion_t complete, + void *data) +{ + req->base.complete = complete; + req->base.data = data; + req->base.flags = flags; +} + +static inline void aead_request_set_crypt(struct aead_request *req, + struct scatterlist *src, + struct scatterlist *dst, + unsigned int cryptlen, u8 *iv) +{ + req->src = src; + req->dst = dst; + req->cryptlen = cryptlen; + req->iv = iv; +} + +static inline void aead_request_set_assoc(struct aead_request *req, + struct scatterlist *assoc, + unsigned int assoclen) +{ + req->assoc = assoc; + req->assoclen = assoclen; +} + static inline struct crypto_blkcipher *__crypto_blkcipher_cast( struct crypto_tfm *tfm) { -- cgit v1.2.3 From 39e1ee011f42dbbcb0210c73ea728ae54cf63b06 Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Wed, 29 Aug 2007 19:27:26 +0800 Subject: [CRYPTO] api: Add support for multiple template parameters This patch adds support for having multiple parameters to a template, separated by a comma. It also adds support for integer parameters in addition to the current algorithm parameter type. This will be used by the authenc template which will have four parameters: the authentication algorithm, the encryption algorithm, the authentication size and the encryption key length. Signed-off-by: Herbert Xu --- crypto/algapi.c | 8 +++-- crypto/cryptomgr.c | 95 +++++++++++++++++++++++++++++++++++++------------- include/linux/crypto.h | 8 +++++ 3 files changed, 84 insertions(+), 27 deletions(-) (limited to 'include/linux') diff --git a/crypto/algapi.c b/crypto/algapi.c index 38aa9e994703..d9559609b525 100644 --- a/crypto/algapi.c +++ b/crypto/algapi.c @@ -439,13 +439,15 @@ EXPORT_SYMBOL_GPL(crypto_unregister_notifier); struct crypto_attr_type *crypto_get_attr_type(struct rtattr **tb) { - struct rtattr *rta = tb[CRYPTOA_TYPE - 1]; + struct rtattr *rta = tb[0]; struct crypto_attr_type *algt; if (!rta) return ERR_PTR(-ENOENT); if (RTA_PAYLOAD(rta) < sizeof(*algt)) return ERR_PTR(-EINVAL); + if (rta->rta_type != CRYPTOA_TYPE) + return ERR_PTR(-EINVAL); algt = RTA_DATA(rta); @@ -470,13 +472,15 @@ EXPORT_SYMBOL_GPL(crypto_check_attr_type); struct crypto_alg *crypto_get_attr_alg(struct rtattr **tb, u32 type, u32 mask) { - struct rtattr *rta = tb[CRYPTOA_ALG - 1]; + struct rtattr *rta = tb[1]; struct crypto_attr_alg *alga; if (!rta) return ERR_PTR(-ENOENT); if (RTA_PAYLOAD(rta) < sizeof(*alga)) return ERR_PTR(-EINVAL); + if (rta->rta_type != CRYPTOA_ALG) + return ERR_PTR(-EINVAL); alga = RTA_DATA(rta); alga->name[CRYPTO_MAX_ALG_NAME - 1] = 0; diff --git a/crypto/cryptomgr.c b/crypto/cryptomgr.c index e5fb7cca5107..c83884fec5f9 100644 --- a/crypto/cryptomgr.c +++ b/crypto/cryptomgr.c @@ -24,22 +24,26 @@ #include "internal.h" struct cryptomgr_param { - struct rtattr *tb[CRYPTOA_MAX]; + struct rtattr *tb[CRYPTO_MAX_ATTRS + 2]; struct { struct rtattr attr; struct crypto_attr_type data; } type; - struct { + union { struct rtattr attr; - struct crypto_attr_alg data; - } alg; - - struct { - char name[CRYPTO_MAX_ALG_NAME]; - } larval; - + struct { + struct rtattr attr; + struct crypto_attr_alg data; + } alg; + struct { + struct rtattr attr; + struct crypto_attr_u32 data; + } nu32; + } attrs[CRYPTO_MAX_ATTRS]; + + char larval[CRYPTO_MAX_ALG_NAME]; char template[CRYPTO_MAX_ALG_NAME]; }; @@ -72,7 +76,7 @@ out: module_put_and_exit(0); err: - crypto_larval_error(param->larval.name, param->type.data.type, + crypto_larval_error(param->larval, param->type.data.type, param->type.data.mask); goto out; } @@ -84,6 +88,7 @@ static int cryptomgr_schedule_probe(struct crypto_larval *larval) const char *name = larval->alg.cra_name; const char *p; unsigned int len; + int i; if (!try_module_get(THIS_MODULE)) goto err; @@ -101,33 +106,73 @@ static int cryptomgr_schedule_probe(struct crypto_larval *larval) memcpy(param->template, name, len); - name = p + 1; - len = 0; - for (p = name; *p; p++) { - for (; isalnum(*p) || *p == '-' || *p == '_' || *p == '('; p++) - ; + i = 0; + for (;;) { + int notnum = 0; - if (*p != ')') - goto err_free_param; + name = ++p; + len = 0; + + for (; isalnum(*p) || *p == '-' || *p == '_'; p++) + notnum |= !isdigit(*p); + + if (*p == '(') { + int recursion = 0; + + for (;;) { + if (!*++p) + goto err_free_param; + if (*p == '(') + recursion++; + else if (*p == ')' && !recursion--) + break; + } + + notnum = 1; + } len = p - name; + if (!len) + goto err_free_param; + + if (notnum) { + param->attrs[i].alg.attr.rta_len = + sizeof(param->attrs[i].alg); + param->attrs[i].alg.attr.rta_type = CRYPTOA_ALG; + memcpy(param->attrs[i].alg.data.name, name, len); + } else { + param->attrs[i].nu32.attr.rta_len = + sizeof(param->attrs[i].nu32); + param->attrs[i].nu32.attr.rta_type = CRYPTOA_U32; + param->attrs[i].nu32.data.num = + simple_strtol(name, NULL, 0); + } + + param->tb[i + 1] = ¶m->attrs[i].attr; + i++; + + if (WARN_ON(i >= CRYPTO_MAX_ATTRS)) + goto err_free_param; + + if (*p == ')') + break; + + if (*p != ',') + goto err_free_param; } - if (!len || name[len + 1]) + if (!i) goto err_free_param; + param->tb[i + 1] = NULL; + param->type.attr.rta_len = sizeof(param->type); param->type.attr.rta_type = CRYPTOA_TYPE; param->type.data.type = larval->alg.cra_flags; param->type.data.mask = larval->mask; - param->tb[CRYPTOA_TYPE - 1] = ¶m->type.attr; - - param->alg.attr.rta_len = sizeof(param->alg); - param->alg.attr.rta_type = CRYPTOA_ALG; - memcpy(param->alg.data.name, name, len); - param->tb[CRYPTOA_ALG - 1] = ¶m->alg.attr; + param->tb[0] = ¶m->type.attr; - memcpy(param->larval.name, larval->alg.cra_name, CRYPTO_MAX_ALG_NAME); + memcpy(param->larval, larval->alg.cra_name, CRYPTO_MAX_ALG_NAME); thread = kthread_run(cryptomgr_probe, param, "cryptomgr"); if (IS_ERR(thread)) diff --git a/include/linux/crypto.h b/include/linux/crypto.h index 1072f9abaef6..da09b4ac3ae9 100644 --- a/include/linux/crypto.h +++ b/include/linux/crypto.h @@ -425,11 +425,15 @@ enum { CRYPTOA_UNSPEC, CRYPTOA_ALG, CRYPTOA_TYPE, + CRYPTOA_U32, __CRYPTOA_MAX, }; #define CRYPTOA_MAX (__CRYPTOA_MAX - 1) +/* Maximum number of (rtattr) parameters for each template. */ +#define CRYPTO_MAX_ATTRS 32 + struct crypto_attr_alg { char name[CRYPTO_MAX_ALG_NAME]; }; @@ -439,6 +443,10 @@ struct crypto_attr_type { u32 mask; }; +struct crypto_attr_u32 { + u32 num; +}; + /* * Transform user interface. */ -- cgit v1.2.3 From 2de98e75449fc1c43d2fbb857668ae62d4f5eece Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Sun, 26 Aug 2007 19:12:47 +0800 Subject: [CRYPTO] ablkcipher: Remove queue pointer from common alg object Since not everyone needs a queue pointer and those who need it can always get it from the context anyway the queue pointer in the common alg object is redundant. Signed-off-by: Herbert Xu --- crypto/ablkcipher.c | 4 ---- crypto/cryptd.c | 7 +++---- include/crypto/algapi.h | 14 +++++++------- include/linux/crypto.h | 3 --- 4 files changed, 10 insertions(+), 18 deletions(-) (limited to 'include/linux') diff --git a/crypto/ablkcipher.c b/crypto/ablkcipher.c index 47438b650c92..2731acb86e7d 100644 --- a/crypto/ablkcipher.c +++ b/crypto/ablkcipher.c @@ -94,10 +94,6 @@ static void crypto_ablkcipher_show(struct seq_file *m, struct crypto_alg *alg) seq_printf(m, "min keysize : %u\n", ablkcipher->min_keysize); seq_printf(m, "max keysize : %u\n", ablkcipher->max_keysize); seq_printf(m, "ivsize : %u\n", ablkcipher->ivsize); - if (ablkcipher->queue) { - seq_printf(m, "qlen : %u\n", ablkcipher->queue->qlen); - seq_printf(m, "max qlen : %u\n", ablkcipher->queue->max_qlen); - } } const struct crypto_type crypto_ablkcipher_type = { diff --git a/crypto/cryptd.c b/crypto/cryptd.c index ac6dce2e7596..8bf2da835f7b 100644 --- a/crypto/cryptd.c +++ b/crypto/cryptd.c @@ -131,7 +131,7 @@ static int cryptd_blkcipher_enqueue(struct ablkcipher_request *req, req->base.complete = complete; spin_lock_bh(&state->lock); - err = ablkcipher_enqueue_request(crypto_ablkcipher_alg(tfm), req); + err = ablkcipher_enqueue_request(&state->queue, req); spin_unlock_bh(&state->lock); wake_up_process(state->task); @@ -173,7 +173,8 @@ static void cryptd_blkcipher_exit_tfm(struct crypto_tfm *tfm) int active; mutex_lock(&state->mutex); - active = ablkcipher_tfm_in_queue(__crypto_ablkcipher_cast(tfm)); + active = ablkcipher_tfm_in_queue(&state->queue, + __crypto_ablkcipher_cast(tfm)); mutex_unlock(&state->mutex); BUG_ON(active); @@ -251,8 +252,6 @@ static struct crypto_instance *cryptd_alloc_blkcipher( inst->alg.cra_ablkcipher.encrypt = cryptd_blkcipher_encrypt_enqueue; inst->alg.cra_ablkcipher.decrypt = cryptd_blkcipher_decrypt_enqueue; - inst->alg.cra_ablkcipher.queue = &state->queue; - out_put_alg: crypto_mod_put(alg); return inst; diff --git a/include/crypto/algapi.h b/include/crypto/algapi.h index 290bce0c5bd5..cd721a7ce78f 100644 --- a/include/crypto/algapi.h +++ b/include/crypto/algapi.h @@ -234,16 +234,16 @@ static inline struct crypto_async_request *crypto_get_backlog( container_of(queue->backlog, struct crypto_async_request, list); } -static inline int ablkcipher_enqueue_request(struct ablkcipher_alg *alg, +static inline int ablkcipher_enqueue_request(struct crypto_queue *queue, struct ablkcipher_request *request) { - return crypto_enqueue_request(alg->queue, &request->base); + return crypto_enqueue_request(queue, &request->base); } static inline struct ablkcipher_request *ablkcipher_dequeue_request( - struct ablkcipher_alg *alg) + struct crypto_queue *queue) { - return ablkcipher_request_cast(crypto_dequeue_request(alg->queue)); + return ablkcipher_request_cast(crypto_dequeue_request(queue)); } static inline void *ablkcipher_request_ctx(struct ablkcipher_request *req) @@ -251,10 +251,10 @@ static inline void *ablkcipher_request_ctx(struct ablkcipher_request *req) return req->__ctx; } -static inline int ablkcipher_tfm_in_queue(struct crypto_ablkcipher *tfm) +static inline int ablkcipher_tfm_in_queue(struct crypto_queue *queue, + struct crypto_ablkcipher *tfm) { - return crypto_tfm_in_queue(crypto_ablkcipher_alg(tfm)->queue, - crypto_ablkcipher_tfm(tfm)); + return crypto_tfm_in_queue(queue, crypto_ablkcipher_tfm(tfm)); } #endif /* _CRYPTO_ALGAPI_H */ diff --git a/include/linux/crypto.h b/include/linux/crypto.h index da09b4ac3ae9..b1c7f4187c5b 100644 --- a/include/linux/crypto.h +++ b/include/linux/crypto.h @@ -95,7 +95,6 @@ struct crypto_async_request; struct crypto_aead; struct crypto_blkcipher; struct crypto_hash; -struct crypto_queue; struct crypto_tfm; struct crypto_type; @@ -178,8 +177,6 @@ struct ablkcipher_alg { int (*encrypt)(struct ablkcipher_request *req); int (*decrypt)(struct ablkcipher_request *req); - struct crypto_queue *queue; - unsigned int min_keysize; unsigned int max_keysize; unsigned int ivsize; -- cgit v1.2.3 From b16c3a2e2c0307f5370b2b5e18bcbe1437b5f3d8 Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Wed, 29 Aug 2007 19:02:04 +0800 Subject: [CRYPTO] api: Fixed crypto_*_reqsize return type This patch changes the return type of crypto_*_reqsize from int to unsigned int which matches what the underlying type is (and should be). Signed-off-by: Herbert Xu --- include/linux/crypto.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/crypto.h b/include/linux/crypto.h index b1c7f4187c5b..fc32694287e2 100644 --- a/include/linux/crypto.h +++ b/include/linux/crypto.h @@ -624,7 +624,8 @@ static inline int crypto_ablkcipher_decrypt(struct ablkcipher_request *req) return crt->decrypt(req); } -static inline int crypto_ablkcipher_reqsize(struct crypto_ablkcipher *tfm) +static inline unsigned int crypto_ablkcipher_reqsize( + struct crypto_ablkcipher *tfm) { return crypto_ablkcipher_crt(tfm)->reqsize; } @@ -766,7 +767,7 @@ static inline int crypto_aead_decrypt(struct aead_request *req) return crypto_aead_crt(crypto_aead_reqtfm(req))->decrypt(req); } -static inline int crypto_aead_reqsize(struct crypto_aead *tfm) +static inline unsigned int crypto_aead_reqsize(struct crypto_aead *tfm) { return crypto_aead_crt(tfm)->reqsize; } -- cgit v1.2.3 From 87bdc48d304191313203df9b98d783e1ab5a55ab Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Wed, 10 Oct 2007 15:45:25 -0700 Subject: [IPSEC]: Get rid of ipv6_{auth,esp,comp}_hdr This patch removes the duplicate ipv6_{auth,esp,comp}_hdr structures since they're identical to the IPv4 versions. Duplicating them would only create problems for ourselves later when we need to add things like extended sequence numbers. I've also added transport header type conversion headers for these types which are now used by the transforms. Signed-off-by: Herbert Xu Signed-off-by: David S. Miller --- include/linux/ipv6.h | 21 --------------------- include/net/ah.h | 7 +++++++ include/net/esp.h | 7 +++++++ include/net/ipcomp.h | 11 ++++++++++- net/ipv4/ah4.c | 18 +++++++++--------- net/ipv4/esp4.c | 10 +++++----- net/ipv4/ipcomp.c | 2 +- net/ipv6/ah6.c | 16 ++++++++-------- net/ipv6/esp6.c | 18 +++++++++--------- net/ipv6/ipcomp6.c | 17 ++++++++--------- 10 files changed, 64 insertions(+), 63 deletions(-) (limited to 'include/linux') diff --git a/include/linux/ipv6.h b/include/linux/ipv6.h index 4ca60c3320fb..5d35a4cc3bff 100644 --- a/include/linux/ipv6.h +++ b/include/linux/ipv6.h @@ -96,27 +96,6 @@ struct ipv6_destopt_hao { struct in6_addr addr; } __attribute__ ((__packed__)); -struct ipv6_auth_hdr { - __u8 nexthdr; - __u8 hdrlen; /* This one is measured in 32 bit units! */ - __be16 reserved; - __be32 spi; - __be32 seq_no; /* Sequence number */ - __u8 auth_data[0]; /* Length variable but >=4. Mind the 64 bit alignment! */ -}; - -struct ipv6_esp_hdr { - __be32 spi; - __be32 seq_no; /* Sequence number */ - __u8 enc_data[0]; /* Length variable but >=8. Mind the 64 bit alignment! */ -}; - -struct ipv6_comp_hdr { - __u8 nexthdr; - __u8 flags; - __be16 cpi; -}; - /* * IPv6 fixed header * diff --git a/include/net/ah.h b/include/net/ah.h index 5e758c2b5dd5..ae1c322f4242 100644 --- a/include/net/ah.h +++ b/include/net/ah.h @@ -38,4 +38,11 @@ out: return err; } +struct ip_auth_hdr; + +static inline struct ip_auth_hdr *ip_auth_hdr(const struct sk_buff *skb) +{ + return (struct ip_auth_hdr *)skb_transport_header(skb); +} + #endif diff --git a/include/net/esp.h b/include/net/esp.h index e793d769430e..c1bc529809da 100644 --- a/include/net/esp.h +++ b/include/net/esp.h @@ -53,4 +53,11 @@ static inline int esp_mac_digest(struct esp_data *esp, struct sk_buff *skb, return crypto_hash_final(&desc, esp->auth.work_icv); } +struct ip_esp_hdr; + +static inline struct ip_esp_hdr *ip_esp_hdr(const struct sk_buff *skb) +{ + return (struct ip_esp_hdr *)skb_transport_header(skb); +} + #endif diff --git a/include/net/ipcomp.h b/include/net/ipcomp.h index 87c1af3e5e82..330b74e813a9 100644 --- a/include/net/ipcomp.h +++ b/include/net/ipcomp.h @@ -1,14 +1,23 @@ #ifndef _NET_IPCOMP_H #define _NET_IPCOMP_H -#include #include #define IPCOMP_SCRATCH_SIZE 65400 +struct crypto_comp; + struct ipcomp_data { u16 threshold; struct crypto_comp **tfms; }; +struct ip_comp_hdr; +struct sk_buff; + +static inline struct ip_comp_hdr *ip_comp_hdr(const struct sk_buff *skb) +{ + return (struct ip_comp_hdr *)skb_transport_header(skb); +} + #endif diff --git a/net/ipv4/ah4.c b/net/ipv4/ah4.c index e4f7aa39978d..d69706405d58 100644 --- a/net/ipv4/ah4.c +++ b/net/ipv4/ah4.c @@ -82,7 +82,7 @@ static int ah_output(struct xfrm_state *x, struct sk_buff *skb) goto error; } - ah = (struct ip_auth_hdr *)skb_transport_header(skb); + ah = ip_auth_hdr(skb); ah->nexthdr = *skb_mac_header(skb); *skb_mac_header(skb) = IPPROTO_AH; @@ -93,8 +93,7 @@ static int ah_output(struct xfrm_state *x, struct sk_buff *skb) top_iph->check = 0; ahp = x->data; - ah->hdrlen = (XFRM_ALIGN8(sizeof(struct ip_auth_hdr) + - ahp->icv_trunc_len) >> 2) - 2; + ah->hdrlen = (XFRM_ALIGN8(sizeof(*ah) + ahp->icv_trunc_len) >> 2) - 2; ah->reserved = 0; ah->spi = x->id.spi; @@ -134,15 +133,15 @@ static int ah_input(struct xfrm_state *x, struct sk_buff *skb) struct ah_data *ahp; char work_buf[60]; - if (!pskb_may_pull(skb, sizeof(struct ip_auth_hdr))) + if (!pskb_may_pull(skb, sizeof(*ah))) goto out; - ah = (struct ip_auth_hdr*)skb->data; + ah = (struct ip_auth_hdr *)skb->data; ahp = x->data; ah_hlen = (ah->hdrlen + 2) << 2; - if (ah_hlen != XFRM_ALIGN8(sizeof(struct ip_auth_hdr) + ahp->icv_full_len) && - ah_hlen != XFRM_ALIGN8(sizeof(struct ip_auth_hdr) + ahp->icv_trunc_len)) + if (ah_hlen != XFRM_ALIGN8(sizeof(*ah) + ahp->icv_full_len) && + ah_hlen != XFRM_ALIGN8(sizeof(*ah) + ahp->icv_trunc_len)) goto out; if (!pskb_may_pull(skb, ah_hlen)) @@ -156,7 +155,7 @@ static int ah_input(struct xfrm_state *x, struct sk_buff *skb) skb->ip_summed = CHECKSUM_NONE; - ah = (struct ip_auth_hdr*)skb->data; + ah = (struct ip_auth_hdr *)skb->data; iph = ip_hdr(skb); ihl = skb->data - skb_network_header(skb); @@ -266,7 +265,8 @@ static int ah_init_state(struct xfrm_state *x) if (!ahp->work_icv) goto error; - x->props.header_len = XFRM_ALIGN8(sizeof(struct ip_auth_hdr) + ahp->icv_trunc_len); + x->props.header_len = XFRM_ALIGN8(sizeof(struct ip_auth_hdr) + + ahp->icv_trunc_len); if (x->props.mode == XFRM_MODE_TUNNEL) x->props.header_len += sizeof(struct iphdr); x->data = ahp; diff --git a/net/ipv4/esp4.c b/net/ipv4/esp4.c index 93153d105619..66eb4968b910 100644 --- a/net/ipv4/esp4.c +++ b/net/ipv4/esp4.c @@ -60,7 +60,7 @@ static int esp_output(struct xfrm_state *x, struct sk_buff *skb) skb_push(skb, -skb_network_offset(skb)); top_iph = ip_hdr(skb); - esph = (struct ip_esp_hdr *)skb_transport_header(skb); + esph = ip_esp_hdr(skb); top_iph->tot_len = htons(skb->len + alen); *(skb_tail_pointer(trailer) - 1) = *skb_mac_header(skb); *skb_mac_header(skb) = IPPROTO_ESP; @@ -157,7 +157,7 @@ static int esp_input(struct xfrm_state *x, struct sk_buff *skb) struct sk_buff *trailer; int blksize = ALIGN(crypto_blkcipher_blocksize(tfm), 4); int alen = esp->auth.icv_trunc_len; - int elen = skb->len - sizeof(struct ip_esp_hdr) - esp->conf.ivlen - alen; + int elen = skb->len - sizeof(*esph) - esp->conf.ivlen - alen; int nfrags; int ihl; u8 nexthdr[2]; @@ -165,7 +165,7 @@ static int esp_input(struct xfrm_state *x, struct sk_buff *skb) int padlen; int err; - if (!pskb_may_pull(skb, sizeof(struct ip_esp_hdr))) + if (!pskb_may_pull(skb, sizeof(*esph))) goto out; if (elen <= 0 || (elen & (blksize-1))) @@ -193,7 +193,7 @@ static int esp_input(struct xfrm_state *x, struct sk_buff *skb) skb->ip_summed = CHECKSUM_NONE; - esph = (struct ip_esp_hdr*)skb->data; + esph = (struct ip_esp_hdr *)skb->data; /* Get ivec. This can be wrong, check against another impls. */ if (esp->conf.ivlen) @@ -206,7 +206,7 @@ static int esp_input(struct xfrm_state *x, struct sk_buff *skb) if (!sg) goto out; } - skb_to_sgvec(skb, sg, sizeof(struct ip_esp_hdr) + esp->conf.ivlen, elen); + skb_to_sgvec(skb, sg, sizeof(*esph) + esp->conf.ivlen, elen); err = crypto_blkcipher_decrypt(&desc, sg, sg, elen); if (unlikely(sg != &esp->sgbuf[0])) kfree(sg); diff --git a/net/ipv4/ipcomp.c b/net/ipv4/ipcomp.c index bf74f64fe5fb..78d6ddb02d1d 100644 --- a/net/ipv4/ipcomp.c +++ b/net/ipv4/ipcomp.c @@ -154,7 +154,7 @@ static int ipcomp_output(struct xfrm_state *x, struct sk_buff *skb) /* Install ipcomp header, convert into ipcomp datagram. */ iph->tot_len = htons(skb->len); - ipch = (struct ip_comp_hdr *)skb_transport_header(skb); + ipch = ip_comp_hdr(skb); ipch->nexthdr = *skb_mac_header(skb); ipch->flags = 0; ipch->cpi = htons((u16 )ntohl(x->id.spi)); diff --git a/net/ipv6/ah6.c b/net/ipv6/ah6.c index ac6bae17a13b..f9f689162692 100644 --- a/net/ipv6/ah6.c +++ b/net/ipv6/ah6.c @@ -270,7 +270,7 @@ static int ah6_output(struct xfrm_state *x, struct sk_buff *skb) goto error_free_iph; } - ah = (struct ip_auth_hdr *)skb_transport_header(skb); + ah = ip_auth_hdr(skb); ah->nexthdr = nexthdr; top_iph->priority = 0; @@ -280,8 +280,7 @@ static int ah6_output(struct xfrm_state *x, struct sk_buff *skb) top_iph->hop_limit = 0; ahp = x->data; - ah->hdrlen = (XFRM_ALIGN8(sizeof(struct ipv6_auth_hdr) + - ahp->icv_trunc_len) >> 2) - 2; + ah->hdrlen = (XFRM_ALIGN8(sizeof(*ah) + ahp->icv_trunc_len) >> 2) - 2; ah->reserved = 0; ah->spi = x->id.spi; @@ -327,7 +326,7 @@ static int ah6_input(struct xfrm_state *x, struct sk_buff *skb) * There is offset of AH before IPv6 header after the process. */ - struct ipv6_auth_hdr *ah; + struct ip_auth_hdr *ah; struct ipv6hdr *ip6h; struct ah_data *ahp; unsigned char *tmp_hdr = NULL; @@ -346,13 +345,13 @@ static int ah6_input(struct xfrm_state *x, struct sk_buff *skb) goto out; hdr_len = skb->data - skb_network_header(skb); - ah = (struct ipv6_auth_hdr*)skb->data; + ah = (struct ip_auth_hdr *)skb->data; ahp = x->data; nexthdr = ah->nexthdr; ah_hlen = (ah->hdrlen + 2) << 2; - if (ah_hlen != XFRM_ALIGN8(sizeof(struct ipv6_auth_hdr) + ahp->icv_full_len) && - ah_hlen != XFRM_ALIGN8(sizeof(struct ipv6_auth_hdr) + ahp->icv_trunc_len)) + if (ah_hlen != XFRM_ALIGN8(sizeof(*ah) + ahp->icv_full_len) && + ah_hlen != XFRM_ALIGN8(sizeof(*ah) + ahp->icv_trunc_len)) goto out; if (!pskb_may_pull(skb, ah_hlen)) @@ -474,7 +473,8 @@ static int ah6_init_state(struct xfrm_state *x) if (!ahp->work_icv) goto error; - x->props.header_len = XFRM_ALIGN8(sizeof(struct ipv6_auth_hdr) + ahp->icv_trunc_len); + x->props.header_len = XFRM_ALIGN8(sizeof(struct ip_auth_hdr) + + ahp->icv_trunc_len); if (x->props.mode == XFRM_MODE_TUNNEL) x->props.header_len += sizeof(struct ipv6hdr); x->data = ahp; diff --git a/net/ipv6/esp6.c b/net/ipv6/esp6.c index 21c93f026dbc..a64295d164ea 100644 --- a/net/ipv6/esp6.c +++ b/net/ipv6/esp6.c @@ -44,7 +44,7 @@ static int esp6_output(struct xfrm_state *x, struct sk_buff *skb) { int err; struct ipv6hdr *top_iph; - struct ipv6_esp_hdr *esph; + struct ip_esp_hdr *esph; struct crypto_blkcipher *tfm; struct blkcipher_desc desc; struct sk_buff *trailer; @@ -86,7 +86,7 @@ static int esp6_output(struct xfrm_state *x, struct sk_buff *skb) skb_push(skb, -skb_network_offset(skb)); top_iph = ipv6_hdr(skb); - esph = (struct ipv6_esp_hdr *)skb_transport_header(skb); + esph = ip_esp_hdr(skb); top_iph->payload_len = htons(skb->len + alen - sizeof(*top_iph)); *(skb_tail_pointer(trailer) - 1) = *skb_mac_header(skb); *skb_mac_header(skb) = IPPROTO_ESP; @@ -142,19 +142,19 @@ error: static int esp6_input(struct xfrm_state *x, struct sk_buff *skb) { struct ipv6hdr *iph; - struct ipv6_esp_hdr *esph; + struct ip_esp_hdr *esph; struct esp_data *esp = x->data; struct crypto_blkcipher *tfm = esp->conf.tfm; struct blkcipher_desc desc = { .tfm = tfm }; struct sk_buff *trailer; int blksize = ALIGN(crypto_blkcipher_blocksize(tfm), 4); int alen = esp->auth.icv_trunc_len; - int elen = skb->len - sizeof(struct ipv6_esp_hdr) - esp->conf.ivlen - alen; + int elen = skb->len - sizeof(*esph) - esp->conf.ivlen - alen; int hdr_len = skb_network_header_len(skb); int nfrags; int ret = 0; - if (!pskb_may_pull(skb, sizeof(struct ipv6_esp_hdr))) { + if (!pskb_may_pull(skb, sizeof(*esph))) { ret = -EINVAL; goto out; } @@ -189,7 +189,7 @@ static int esp6_input(struct xfrm_state *x, struct sk_buff *skb) skb->ip_summed = CHECKSUM_NONE; - esph = (struct ipv6_esp_hdr*)skb->data; + esph = (struct ip_esp_hdr *)skb->data; iph = ipv6_hdr(skb); /* Get ivec. This can be wrong, check against another impls. */ @@ -208,7 +208,7 @@ static int esp6_input(struct xfrm_state *x, struct sk_buff *skb) goto out; } } - skb_to_sgvec(skb, sg, sizeof(struct ipv6_esp_hdr) + esp->conf.ivlen, elen); + skb_to_sgvec(skb, sg, sizeof(*esph) + esp->conf.ivlen, elen); ret = crypto_blkcipher_decrypt(&desc, sg, sg, elen); if (unlikely(sg != &esp->sgbuf[0])) kfree(sg); @@ -260,7 +260,7 @@ static void esp6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, int type, int code, int offset, __be32 info) { struct ipv6hdr *iph = (struct ipv6hdr*)skb->data; - struct ipv6_esp_hdr *esph = (struct ipv6_esp_hdr*)(skb->data+offset); + struct ip_esp_hdr *esph = (struct ip_esp_hdr *)(skb->data + offset); struct xfrm_state *x; if (type != ICMPV6_DEST_UNREACH && @@ -356,7 +356,7 @@ static int esp6_init_state(struct xfrm_state *x) if (crypto_blkcipher_setkey(tfm, x->ealg->alg_key, (x->ealg->alg_key_len + 7) / 8)) goto error; - x->props.header_len = sizeof(struct ipv6_esp_hdr) + esp->conf.ivlen; + x->props.header_len = sizeof(struct ip_esp_hdr) + esp->conf.ivlen; if (x->props.mode == XFRM_MODE_TUNNEL) x->props.header_len += sizeof(struct ipv6hdr); x->data = esp; diff --git a/net/ipv6/ipcomp6.c b/net/ipv6/ipcomp6.c index 87e6407ebf97..8f3f32faaf4c 100644 --- a/net/ipv6/ipcomp6.c +++ b/net/ipv6/ipcomp6.c @@ -65,7 +65,7 @@ static LIST_HEAD(ipcomp6_tfms_list); static int ipcomp6_input(struct xfrm_state *x, struct sk_buff *skb) { int err = -ENOMEM; - struct ipv6_comp_hdr *ipch; + struct ip_comp_hdr *ipch; int plen, dlen; struct ipcomp_data *ipcd = x->data; u8 *start, *scratch; @@ -92,12 +92,10 @@ static int ipcomp6_input(struct xfrm_state *x, struct sk_buff *skb) tfm = *per_cpu_ptr(ipcd->tfms, cpu); err = crypto_comp_decompress(tfm, start, plen, scratch, &dlen); - if (err) { - err = -EINVAL; + if (err) goto out_put_cpu; - } - if (dlen < (plen + sizeof(struct ipv6_comp_hdr))) { + if (dlen < (plen + sizeof(*ipch))) { err = -EINVAL; goto out_put_cpu; } @@ -122,7 +120,7 @@ static int ipcomp6_output(struct xfrm_state *x, struct sk_buff *skb) { int err; struct ipv6hdr *top_iph; - struct ipv6_comp_hdr *ipch; + struct ip_comp_hdr *ipch; struct ipcomp_data *ipcd = x->data; int plen, dlen; u8 *start, *scratch; @@ -151,7 +149,7 @@ static int ipcomp6_output(struct xfrm_state *x, struct sk_buff *skb) tfm = *per_cpu_ptr(ipcd->tfms, cpu); err = crypto_comp_compress(tfm, start, plen, scratch, &dlen); - if (err || (dlen + sizeof(struct ipv6_comp_hdr)) >= plen) { + if (err || (dlen + sizeof(*ipch)) >= plen) { put_cpu(); goto out_ok; } @@ -164,7 +162,7 @@ static int ipcomp6_output(struct xfrm_state *x, struct sk_buff *skb) top_iph->payload_len = htons(skb->len - sizeof(struct ipv6hdr)); - ipch = (struct ipv6_comp_hdr *)start; + ipch = ip_comp_hdr(skb); ipch->nexthdr = *skb_mac_header(skb); ipch->flags = 0; ipch->cpi = htons((u16 )ntohl(x->id.spi)); @@ -179,7 +177,8 @@ static void ipcomp6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, { __be32 spi; struct ipv6hdr *iph = (struct ipv6hdr*)skb->data; - struct ipv6_comp_hdr *ipcomph = (struct ipv6_comp_hdr*)(skb->data+offset); + struct ip_comp_hdr *ipcomph = + (struct ip_comp_hdr *)(skb->data + offset); struct xfrm_state *x; if (type != ICMPV6_DEST_UNREACH && type != ICMPV6_PKT_TOOBIG) -- cgit v1.2.3 From 9936bcf68a7e4d33f080bba9ee03d156c75c91ee Mon Sep 17 00:00:00 2001 From: Matt Carlson Date: Wed, 10 Oct 2007 18:03:07 -0700 Subject: [TG3]: Add 5761 support This patch adds rest of the miscellaneous code required to support the 5761. Signed-off-by: Matt Carlson Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/tg3.c | 86 +++++++++++++++++++++++++++++++++++++++++-------- drivers/net/tg3.h | 14 ++++++-- include/linux/pci_ids.h | 2 ++ 3 files changed, 87 insertions(+), 15 deletions(-) (limited to 'include/linux') diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 5b6c1b286e92..65aeca8e5147 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -200,6 +200,8 @@ static struct pci_device_id tg3_pci_tbl[] = { {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5906M)}, {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5784)}, {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5764)}, + {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5761)}, + {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5761E)}, {PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, PCI_DEVICE_ID_SYSKONNECT_9DXX)}, {PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, PCI_DEVICE_ID_SYSKONNECT_9MXX)}, {PCI_DEVICE(PCI_VENDOR_ID_ALTIMA, PCI_DEVICE_ID_ALTIMA_AC1000)}, @@ -5087,7 +5089,8 @@ static int tg3_chip_reset(struct tg3 *tp) if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5752 || GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755 || GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787 || - GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784) + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784 || + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761) tw32(GRC_FASTBOOT_PC, 0); /* @@ -6363,7 +6366,8 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy) if (err) return err; - if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5784) { + if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5784 && + GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5761) { /* This value is determined during the probe time DMA * engine test, tg3_test_dma. */ @@ -6769,7 +6773,8 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy) /* Enable host coalescing bug fix */ if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755) || (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787) || - (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784)) + (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784) || + (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761)) val |= (1 << 29); tw32_f(WDMAC_MODE, val); @@ -6797,7 +6802,13 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy) tw32(RCVDCC_MODE, RCVDCC_MODE_ENABLE | RCVDCC_MODE_ATTN_ENABLE); if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS)) tw32(MBFREE_MODE, MBFREE_MODE_ENABLE); - tw32(SNDDATAC_MODE, SNDDATAC_MODE_ENABLE); + + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761) + tw32(SNDDATAC_MODE, + SNDDATAC_MODE_ENABLE | SNDDATAC_MODE_CDELAY); + else + tw32(SNDDATAC_MODE, SNDDATAC_MODE_ENABLE); + tw32(SNDBDC_MODE, SNDBDC_MODE_ENABLE | SNDBDC_MODE_ATTN_ENABLE); tw32(RCVBDI_MODE, RCVBDI_MODE_ENABLE | RCVBDI_MODE_RCB_ATTN_ENAB); tw32(RCVDBDI_MODE, RCVDBDI_MODE_ENABLE | RCVDBDI_MODE_INV_RING_SZ); @@ -6824,7 +6835,8 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy) udelay(100); tp->rx_mode = RX_MODE_ENABLE; - if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755) + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755 || + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761) tp->rx_mode |= RX_MODE_IPV6_CSUM_ENABLE; tw32_f(MAC_RX_MODE, tp->rx_mode); @@ -8368,10 +8380,12 @@ static int tg3_set_tso(struct net_device *dev, u32 value) } if ((tp->tg3_flags2 & TG3_FLG2_HW_TSO_2) && (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5906)) { - if (value) + if (value) { dev->features |= NETIF_F_TSO6; - else - dev->features &= ~NETIF_F_TSO6; + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761) + dev->features |= NETIF_F_TSO_ECN; + } else + dev->features &= ~(NETIF_F_TSO6 | NETIF_F_TSO_ECN); } return ethtool_op_set_tso(dev, value); } @@ -8550,7 +8564,8 @@ static int tg3_set_tx_csum(struct net_device *dev, u32 data) if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755 || GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787 || - GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784) + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784 || + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761) ethtool_op_set_tx_ipv6_csum(dev, data); else ethtool_op_set_tx_csum(dev, data); @@ -9047,7 +9062,8 @@ static int tg3_test_memory(struct tg3 *tp) if (tp->tg3_flags2 & TG3_FLG2_5705_PLUS) { if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755 || GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787 || - GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784) + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784 || + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761) mem_tbl = mem_tbl_5755; else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) mem_tbl = mem_tbl_5906; @@ -9244,6 +9260,7 @@ out: static int tg3_test_loopback(struct tg3 *tp) { int err = 0; + u32 cpmuctrl = 0; if (!netif_running(tp->dev)) return TG3_LOOPBACK_FAILED; @@ -9252,8 +9269,40 @@ static int tg3_test_loopback(struct tg3 *tp) if (err) return TG3_LOOPBACK_FAILED; + if (tp->tg3_flags & TG3_FLAG_CPMU_PRESENT) { + int i; + u32 status; + + tw32(TG3_CPMU_MUTEX_REQ, CPMU_MUTEX_REQ_DRIVER); + + /* Wait for up to 40 microseconds to acquire lock. */ + for (i = 0; i < 4; i++) { + status = tr32(TG3_CPMU_MUTEX_GNT); + if (status == CPMU_MUTEX_GNT_DRIVER) + break; + udelay(10); + } + + if (status != CPMU_MUTEX_GNT_DRIVER) + return TG3_LOOPBACK_FAILED; + + cpmuctrl = tr32(TG3_CPMU_CTRL); + + /* Turn off power management based on link speed. */ + tw32(TG3_CPMU_CTRL, + cpmuctrl & ~CPMU_CTRL_LINK_SPEED_MODE); + } + if (tg3_run_loopback(tp, TG3_MAC_LOOPBACK)) err |= TG3_MAC_LOOPBACK_FAILED; + + if (tp->tg3_flags & TG3_FLAG_CPMU_PRESENT) { + tw32(TG3_CPMU_CTRL, cpmuctrl); + + /* Release the mutex */ + tw32(TG3_CPMU_MUTEX_GNT, CPMU_MUTEX_GNT_DRIVER); + } + if (!(tp->tg3_flags2 & TG3_FLG2_PHY_SERDES)) { if (tg3_run_loopback(tp, TG3_PHY_LOOPBACK)) err |= TG3_PHY_LOOPBACK_FAILED; @@ -10192,6 +10241,7 @@ static int tg3_nvram_write_block_buffered(struct tg3 *tp, u32 offset, u32 len, (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5755) && (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5787) && (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5784) && + (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5761) && (tp->nvram_jedecnum == JEDEC_ST) && (nvram_cmd & NVRAM_CMD_FIRST)) { @@ -10941,6 +10991,7 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755 || GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787 || GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784 || + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761 || GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906 || (tp->tg3_flags2 & TG3_FLG2_5780_CLASS)) tp->tg3_flags2 |= TG3_FLG2_5750_PLUS; @@ -10961,6 +11012,7 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755 || GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787 || GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784 || + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761 || GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) { tp->tg3_flags2 |= TG3_FLG2_HW_TSO_2; tp->tg3_flags2 |= TG3_FLG2_1SHOT_MSI; @@ -10979,6 +11031,7 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5755 && GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5787 && GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5784 && + GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5761 && GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5906) tp->tg3_flags2 |= TG3_FLG2_JUMBO_CAPABLE; @@ -11164,7 +11217,8 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) pci_state_reg); } - if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784) + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784 || + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761) tp->tg3_flags |= TG3_FLAG_CPMU_PRESENT; /* Set up tp->grc_local_ctrl before calling tg3_set_power_state(). @@ -11234,7 +11288,8 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) if (tp->tg3_flags2 & TG3_FLG2_5705_PLUS) { if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755 || GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787 || - GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784) { + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784 || + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761) { if (tp->pdev->device != PCI_DEVICE_ID_TIGON3_5756 && tp->pdev->device != PCI_DEVICE_ID_TIGON3_5722) tp->tg3_flags2 |= TG3_FLG2_PHY_JITTER_BUG; @@ -11378,6 +11433,7 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755 || GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787 || GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784 || + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761 || GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) tp->dev->hard_start_xmit = tg3_start_xmit; else @@ -12002,6 +12058,7 @@ static char * __devinit tg3_phy_string(struct tg3 *tp) case PHY_ID_BCM5784: return "5784"; case PHY_ID_BCM5756: return "5722/5756"; case PHY_ID_BCM5906: return "5906"; + case PHY_ID_BCM5761: return "5761"; case PHY_ID_BCM8002: return "8002/serdes"; case 0: return "serdes"; default: return "unknown"; @@ -12304,6 +12361,8 @@ static int __devinit tg3_init_one(struct pci_dev *pdev, if ((tp->tg3_flags2 & TG3_FLG2_HW_TSO_2) && (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5906)) dev->features |= NETIF_F_TSO6; + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761) + dev->features |= NETIF_F_TSO_ECN; } @@ -12345,7 +12404,8 @@ static int __devinit tg3_init_one(struct pci_dev *pdev, dev->features |= NETIF_F_IP_CSUM | NETIF_F_SG; if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755 || GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787 || - GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784) + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784 || + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761) dev->features |= NETIF_F_IPV6_CSUM; tp->tg3_flags |= TG3_FLAG_RX_CHECKSUMS; diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h index 632c2f084c52..d1f5fa394ea7 100644 --- a/drivers/net/tg3.h +++ b/drivers/net/tg3.h @@ -666,6 +666,7 @@ #define SNDDATAC_MODE 0x00001000 #define SNDDATAC_MODE_RESET 0x00000001 #define SNDDATAC_MODE_ENABLE 0x00000002 +#define SNDDATAC_MODE_CDELAY 0x00000010 /* 0x1004 --> 0x1400 unused */ /* Send BD ring selector */ @@ -854,7 +855,14 @@ #define TG3_CPMU_CTRL 0x00003600 #define CPMU_CTRL_LINK_IDLE_MODE 0x00000200 #define CPMU_CTRL_LINK_AWARE_MODE 0x00000400 -/* 0x3604 --> 0x3800 unused */ +#define CPMU_CTRL_LINK_SPEED_MODE 0x00004000 +/* 0x3604 --> 0x365c unused */ + +#define TG3_CPMU_MUTEX_REQ 0x0000365c +#define CPMU_MUTEX_REQ_DRIVER 0x00001000 +#define TG3_CPMU_MUTEX_GNT 0x00003660 +#define CPMU_MUTEX_GNT_DRIVER 0x00001000 +/* 0x3664 --> 0x3800 unused */ /* Mbuf cluster free registers */ #define MBFREE_MODE 0x00003800 @@ -2394,6 +2402,7 @@ struct tg3 { #define PHY_ID_BCM5787 0xbc050ce0 #define PHY_ID_BCM5756 0xbc050ed0 #define PHY_ID_BCM5784 0xbc050fa0 +#define PHY_ID_BCM5761 0xbc050fd0 #define PHY_ID_BCM5906 0xdc00ac40 #define PHY_ID_BCM8002 0x60010140 #define PHY_ID_INVALID 0xffffffff @@ -2423,7 +2432,8 @@ struct tg3 { (X) == PHY_ID_BCM5752 || (X) == PHY_ID_BCM5714 || \ (X) == PHY_ID_BCM5780 || (X) == PHY_ID_BCM5787 || \ (X) == PHY_ID_BCM5755 || (X) == PHY_ID_BCM5756 || \ - (X) == PHY_ID_BCM5906 || (X) == PHY_ID_BCM8002) + (X) == PHY_ID_BCM5906 || (X) == PHY_ID_BCM5761 || \ + (X) == PHY_ID_BCM8002) struct tg3_hw_stats *hw_stats; dma_addr_t stats_mapping; diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index 6f5fa39c8290..27363bf29791 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -1950,6 +1950,8 @@ #define PCI_DEVICE_ID_TIGON3_5751M 0x167d #define PCI_DEVICE_ID_TIGON3_5751F 0x167e #define PCI_DEVICE_ID_TIGON3_5787F 0x167f +#define PCI_DEVICE_ID_TIGON3_5761E 0x1680 +#define PCI_DEVICE_ID_TIGON3_5761 0x1681 #define PCI_DEVICE_ID_TIGON3_5764 0x1684 #define PCI_DEVICE_ID_TIGON3_5787M 0x1693 #define PCI_DEVICE_ID_TIGON3_5782 0x1696 -- cgit v1.2.3 From 7ee015e0fa3c856416e9477aac4b850ec6f09017 Mon Sep 17 00:00:00 2001 From: "Denis V. Lunev" Date: Wed, 10 Oct 2007 21:14:03 -0700 Subject: [NET]: cleanup 3rd argument in netlink_sendskb netlink_sendskb does not use third argument. Clean it and save a couple of bytes. Signed-off-by: Denis V. Lunev Acked-by: Alexey Kuznetsov Signed-off-by: David S. Miller --- include/linux/netlink.h | 2 +- ipc/mqueue.c | 5 ++--- net/netlink/af_netlink.c | 4 ++-- 3 files changed, 5 insertions(+), 6 deletions(-) (limited to 'include/linux') diff --git a/include/linux/netlink.h b/include/linux/netlink.h index e638256ce472..7b552b6c2c19 100644 --- a/include/linux/netlink.h +++ b/include/linux/netlink.h @@ -194,7 +194,7 @@ struct sock *netlink_getsockbyfilp(struct file *filp); int netlink_attachskb(struct sock *sk, struct sk_buff *skb, int nonblock, long timeo, struct sock *ssk); void netlink_detachskb(struct sock *sk, struct sk_buff *skb); -int netlink_sendskb(struct sock *sk, struct sk_buff *skb, int protocol); +int netlink_sendskb(struct sock *sk, struct sk_buff *skb); /* * skb should fit one page. This choice is good for headerless malloc. diff --git a/ipc/mqueue.c b/ipc/mqueue.c index 145d5a0d299f..24df3347ad4b 100644 --- a/ipc/mqueue.c +++ b/ipc/mqueue.c @@ -521,8 +521,7 @@ static void __do_notify(struct mqueue_inode_info *info) break; case SIGEV_THREAD: set_cookie(info->notify_cookie, NOTIFY_WOKENUP); - netlink_sendskb(info->notify_sock, - info->notify_cookie, 0); + netlink_sendskb(info->notify_sock, info->notify_cookie); break; } /* after notification unregisters process */ @@ -568,7 +567,7 @@ static void remove_notification(struct mqueue_inode_info *info) if (info->notify_owner != NULL && info->notify.sigev_notify == SIGEV_THREAD) { set_cookie(info->notify_cookie, NOTIFY_REMOVED); - netlink_sendskb(info->notify_sock, info->notify_cookie, 0); + netlink_sendskb(info->notify_sock, info->notify_cookie); } put_pid(info->notify_owner); info->notify_owner = NULL; diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c index f934f54fbfd5..a5bd63ca86bc 100644 --- a/net/netlink/af_netlink.c +++ b/net/netlink/af_netlink.c @@ -791,7 +791,7 @@ int netlink_attachskb(struct sock *sk, struct sk_buff *skb, int nonblock, return 0; } -int netlink_sendskb(struct sock *sk, struct sk_buff *skb, int protocol) +int netlink_sendskb(struct sock *sk, struct sk_buff *skb) { int len = skb->len; @@ -853,7 +853,7 @@ retry: if (err) return err; - return netlink_sendskb(sk, skb, ssk->sk_protocol); + return netlink_sendskb(sk, skb); } int netlink_has_listeners(struct sock *sk, unsigned int group) -- cgit v1.2.3 From cd40b7d3983c708aabe3d3008ec64ffce56d33b0 Mon Sep 17 00:00:00 2001 From: "Denis V. Lunev" Date: Wed, 10 Oct 2007 21:15:29 -0700 Subject: [NET]: make netlink user -> kernel interface synchronious This patch make processing netlink user -> kernel messages synchronious. This change was inspired by the talk with Alexey Kuznetsov about current netlink messages processing. He says that he was badly wrong when introduced asynchronious user -> kernel communication. The call netlink_unicast is the only path to send message to the kernel netlink socket. But, unfortunately, it is also used to send data to the user. Before this change the user message has been attached to the socket queue and sk->sk_data_ready was called. The process has been blocked until all pending messages were processed. The bad thing is that this processing may occur in the arbitrary process context. This patch changes nlk->data_ready callback to get 1 skb and force packet processing right in the netlink_unicast. Kernel -> user path in netlink_unicast remains untouched. EINTR processing for in netlink_run_queue was changed. It forces rtnl_lock drop, but the process remains in the cycle until the message will be fully processed. So, there is no need to use this kludges now. Signed-off-by: Denis V. Lunev Acked-by: Alexey Kuznetsov Signed-off-by: David S. Miller --- drivers/connector/connector.c | 14 +--- drivers/scsi/scsi_netlink.c | 25 +----- drivers/scsi/scsi_transport_iscsi.c | 82 +++++++++---------- fs/ecryptfs/netlink.c | 14 +--- include/linux/connector.h | 2 +- include/linux/netlink.h | 2 +- include/net/netlink.h | 6 +- kernel/audit.c | 12 +-- net/core/rtnetlink.c | 12 +-- net/decnet/netfilter/dn_rtmsg.c | 14 +--- net/ipv4/fib_frontend.c | 9 ++- net/ipv4/inet_diag.c | 12 +-- net/ipv4/netfilter/ip_queue.c | 17 +--- net/ipv6/netfilter/ip6_queue.c | 19 ++--- net/netfilter/nfnetlink.c | 12 +-- net/netlink/af_netlink.c | 152 +++++++++++------------------------- net/netlink/genetlink.c | 12 +-- net/xfrm/xfrm_user.c | 13 +-- 18 files changed, 130 insertions(+), 299 deletions(-) (limited to 'include/linux') diff --git a/drivers/connector/connector.c b/drivers/connector/connector.c index 569070997cc1..0e328d387af4 100644 --- a/drivers/connector/connector.c +++ b/drivers/connector/connector.c @@ -234,18 +234,6 @@ out: kfree_skb(__skb); } -/* - * Netlink socket input callback - dequeues the skbs and calls the - * main netlink receiving function. - */ -static void cn_input(struct sock *sk, int len) -{ - struct sk_buff *skb; - - while ((skb = skb_dequeue(&sk->sk_receive_queue)) != NULL) - cn_rx_skb(skb); -} - /* * Notification routing. * @@ -442,7 +430,7 @@ static int __devinit cn_init(void) struct cn_dev *dev = &cdev; int err; - dev->input = cn_input; + dev->input = cn_rx_skb; dev->id.idx = cn_idx; dev->id.val = cn_val; diff --git a/drivers/scsi/scsi_netlink.c b/drivers/scsi/scsi_netlink.c index 163acf6ad2d3..40579edca101 100644 --- a/drivers/scsi/scsi_netlink.c +++ b/drivers/scsi/scsi_netlink.c @@ -64,7 +64,7 @@ scsi_nl_rcv_msg(struct sk_buff *skb) if (nlh->nlmsg_type != SCSI_TRANSPORT_MSG) { err = -EBADMSG; - goto next_msg; + return; } hdr = NLMSG_DATA(nlh); @@ -98,27 +98,6 @@ next_msg: } -/** - * scsi_nl_rcv_msg - - * Receive handler for a socket. Extracts a received message buffer from - * the socket, and starts message processing. - * - * @sk: socket - * @len: unused - * - **/ -static void -scsi_nl_rcv(struct sock *sk, int len) -{ - struct sk_buff *skb; - - while ((skb = skb_dequeue(&sk->sk_receive_queue))) { - scsi_nl_rcv_msg(skb); - kfree_skb(skb); - } -} - - /** * scsi_nl_rcv_event - * Event handler for a netlink socket. @@ -168,7 +147,7 @@ scsi_netlink_init(void) } scsi_nl_sock = netlink_kernel_create(&init_net, NETLINK_SCSITRANSPORT, - SCSI_NL_GRP_CNT, scsi_nl_rcv, NULL, + SCSI_NL_GRP_CNT, scsi_nl_rcv_msg, NULL, THIS_MODULE); if (!scsi_nl_sock) { printk(KERN_ERR "%s: register of recieve handler failed\n", diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c index 4916f01230dc..5428d15f23c6 100644 --- a/drivers/scsi/scsi_transport_iscsi.c +++ b/drivers/scsi/scsi_transport_iscsi.c @@ -1097,61 +1097,49 @@ iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) } /* - * Get message from skb (based on rtnetlink_rcv_skb). Each message is - * processed by iscsi_if_recv_msg. Malformed skbs with wrong lengths or - * invalid creds are discarded silently. + * Get message from skb. Each message is processed by iscsi_if_recv_msg. + * Malformed skbs with wrong lengths or invalid creds are not processed. */ static void -iscsi_if_rx(struct sock *sk, int len) +iscsi_if_rx(struct sk_buff *skb) { - struct sk_buff *skb; - mutex_lock(&rx_queue_mutex); - while ((skb = skb_dequeue(&sk->sk_receive_queue)) != NULL) { - if (NETLINK_CREDS(skb)->uid) { - skb_pull(skb, skb->len); - goto free_skb; + while (skb->len >= NLMSG_SPACE(0)) { + int err; + uint32_t rlen; + struct nlmsghdr *nlh; + struct iscsi_uevent *ev; + + nlh = nlmsg_hdr(skb); + if (nlh->nlmsg_len < sizeof(*nlh) || + skb->len < nlh->nlmsg_len) { + break; } - while (skb->len >= NLMSG_SPACE(0)) { - int err; - uint32_t rlen; - struct nlmsghdr *nlh; - struct iscsi_uevent *ev; + ev = NLMSG_DATA(nlh); + rlen = NLMSG_ALIGN(nlh->nlmsg_len); + if (rlen > skb->len) + rlen = skb->len; - nlh = nlmsg_hdr(skb); - if (nlh->nlmsg_len < sizeof(*nlh) || - skb->len < nlh->nlmsg_len) { - break; - } - - ev = NLMSG_DATA(nlh); - rlen = NLMSG_ALIGN(nlh->nlmsg_len); - if (rlen > skb->len) - rlen = skb->len; - - err = iscsi_if_recv_msg(skb, nlh); - if (err) { - ev->type = ISCSI_KEVENT_IF_ERROR; - ev->iferror = err; - } - do { - /* - * special case for GET_STATS: - * on success - sending reply and stats from - * inside of if_recv_msg(), - * on error - fall through. - */ - if (ev->type == ISCSI_UEVENT_GET_STATS && !err) - break; - err = iscsi_if_send_reply( - NETLINK_CREDS(skb)->pid, nlh->nlmsg_seq, - nlh->nlmsg_type, 0, 0, ev, sizeof(*ev)); - } while (err < 0 && err != -ECONNREFUSED); - skb_pull(skb, rlen); + err = iscsi_if_recv_msg(skb, nlh); + if (err) { + ev->type = ISCSI_KEVENT_IF_ERROR; + ev->iferror = err; } -free_skb: - kfree_skb(skb); + do { + /* + * special case for GET_STATS: + * on success - sending reply and stats from + * inside of if_recv_msg(), + * on error - fall through. + */ + if (ev->type == ISCSI_UEVENT_GET_STATS && !err) + break; + err = iscsi_if_send_reply( + NETLINK_CREDS(skb)->pid, nlh->nlmsg_seq, + nlh->nlmsg_type, 0, 0, ev, sizeof(*ev)); + } while (err < 0 && err != -ECONNREFUSED); + skb_pull(skb, rlen); } mutex_unlock(&rx_queue_mutex); } diff --git a/fs/ecryptfs/netlink.c b/fs/ecryptfs/netlink.c index 056519cd92bc..9aa345121e09 100644 --- a/fs/ecryptfs/netlink.c +++ b/fs/ecryptfs/netlink.c @@ -165,22 +165,10 @@ static int ecryptfs_process_nl_quit(struct sk_buff *skb) * it to its desired netlink context element and wake up the process * that is waiting for a response. */ -static void ecryptfs_receive_nl_message(struct sock *sk, int len) +static void ecryptfs_receive_nl_message(struct sk_buff *skb) { - struct sk_buff *skb; struct nlmsghdr *nlh; - int rc = 0; /* skb_recv_datagram requires this */ -receive: - skb = skb_recv_datagram(sk, 0, 0, &rc); - if (rc == -EINTR) - goto receive; - else if (rc < 0) { - ecryptfs_printk(KERN_ERR, "Error occurred while " - "receiving eCryptfs netlink message; " - "rc = [%d]\n", rc); - return; - } nlh = nlmsg_hdr(skb); if (!NLMSG_OK(nlh, skb->len)) { ecryptfs_printk(KERN_ERR, "Received corrupt netlink " diff --git a/include/linux/connector.h b/include/linux/connector.h index 10eb56b2940a..b62f823e90cf 100644 --- a/include/linux/connector.h +++ b/include/linux/connector.h @@ -153,7 +153,7 @@ struct cn_dev { u32 seq, groups; struct sock *nls; - void (*input) (struct sock * sk, int len); + void (*input) (struct sk_buff *skb); struct cn_queue_dev *cbdev; }; diff --git a/include/linux/netlink.h b/include/linux/netlink.h index 7b552b6c2c19..7c1f3b1d2ee5 100644 --- a/include/linux/netlink.h +++ b/include/linux/netlink.h @@ -175,7 +175,7 @@ struct netlink_skb_parms extern struct sock *netlink_kernel_create(struct net *net, int unit,unsigned int groups, - void (*input)(struct sock *sk, int len), + void (*input)(struct sk_buff *skb), struct mutex *cb_mutex, struct module *module); extern int netlink_change_ngroups(struct sock *sk, unsigned int groups); diff --git a/include/net/netlink.h b/include/net/netlink.h index 1afd3e837d23..9298218c07f9 100644 --- a/include/net/netlink.h +++ b/include/net/netlink.h @@ -220,9 +220,9 @@ struct nl_info { u32 pid; }; -extern unsigned int netlink_run_queue(struct sock *sk, unsigned int qlen, - int (*cb)(struct sk_buff *, - struct nlmsghdr *)); +extern int netlink_rcv_skb(struct sk_buff *skb, + int (*cb)(struct sk_buff *, + struct nlmsghdr *)); extern int nlmsg_notify(struct sock *sk, struct sk_buff *skb, u32 pid, unsigned int group, int report, gfp_t flags); diff --git a/kernel/audit.c b/kernel/audit.c index f3c390f6c0b4..2924251a6547 100644 --- a/kernel/audit.c +++ b/kernel/audit.c @@ -847,18 +847,10 @@ static void audit_receive_skb(struct sk_buff *skb) } /* Receive messages from netlink socket. */ -static void audit_receive(struct sock *sk, int length) +static void audit_receive(struct sk_buff *skb) { - struct sk_buff *skb; - unsigned int qlen; - mutex_lock(&audit_cmd_mutex); - - for (qlen = skb_queue_len(&sk->sk_receive_queue); qlen; qlen--) { - skb = skb_dequeue(&sk->sk_receive_queue); - audit_receive_skb(skb); - kfree_skb(skb); - } + audit_receive_skb(skb); mutex_unlock(&audit_cmd_mutex); } diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index 471d2d9f8eae..1072d16696c3 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c @@ -1312,15 +1312,11 @@ static int rtnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) return doit(skb, nlh, (void *)&rta_buf[0]); } -static void rtnetlink_rcv(struct sock *sk, int len) +static void rtnetlink_rcv(struct sk_buff *skb) { - unsigned int qlen = 0; - - do { - rtnl_lock(); - qlen = netlink_run_queue(sk, qlen, &rtnetlink_rcv_msg); - rtnl_unlock(); - } while (qlen); + rtnl_lock(); + netlink_rcv_skb(skb, &rtnetlink_rcv_msg); + rtnl_unlock(); } static int rtnetlink_event(struct notifier_block *this, unsigned long event, void *ptr) diff --git a/net/decnet/netfilter/dn_rtmsg.c b/net/decnet/netfilter/dn_rtmsg.c index ebb38feb4df3..f7fba7721e63 100644 --- a/net/decnet/netfilter/dn_rtmsg.c +++ b/net/decnet/netfilter/dn_rtmsg.c @@ -115,17 +115,6 @@ static inline void dnrmg_receive_user_skb(struct sk_buff *skb) RCV_SKB_FAIL(-EINVAL); } -static void dnrmg_receive_user_sk(struct sock *sk, int len) -{ - struct sk_buff *skb; - unsigned int qlen = skb_queue_len(&sk->sk_receive_queue); - - for (; qlen && (skb = skb_dequeue(&sk->sk_receive_queue)); qlen--) { - dnrmg_receive_user_skb(skb); - kfree_skb(skb); - } -} - static struct nf_hook_ops dnrmg_ops = { .hook = dnrmg_hook, .pf = PF_DECnet, @@ -139,7 +128,8 @@ static int __init dn_rtmsg_init(void) dnrmg = netlink_kernel_create(&init_net, NETLINK_DNRTMSG, DNRNG_NLGRP_MAX, - dnrmg_receive_user_sk, NULL, THIS_MODULE); + dnrmg_receive_user_skb, + NULL, THIS_MODULE); if (dnrmg == NULL) { printk(KERN_ERR "dn_rtmsg: Cannot create netlink socket"); return -ENOMEM; diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c index f823ca34cb12..a5cba2349605 100644 --- a/net/ipv4/fib_frontend.c +++ b/net/ipv4/fib_frontend.c @@ -62,6 +62,9 @@ static struct hlist_head fib_table_hash[FIB_TABLE_HASHSZ]; #define FIB_TABLE_HASHSZ 256 static struct hlist_head fib_table_hash[FIB_TABLE_HASHSZ]; +static struct sock *fibnl = NULL; + + struct fib_table *fib_new_table(u32 id) { struct fib_table *tb; @@ -811,13 +814,13 @@ static void nl_fib_input(struct sock *sk, int len) pid = NETLINK_CB(skb).pid; /* pid of sending process */ NETLINK_CB(skb).pid = 0; /* from kernel */ NETLINK_CB(skb).dst_group = 0; /* unicast */ - netlink_unicast(sk, skb, pid, MSG_DONTWAIT); + netlink_unicast(fibnl, skb, pid, MSG_DONTWAIT); } static void nl_fib_lookup_init(void) { - netlink_kernel_create(&init_net, NETLINK_FIB_LOOKUP, 0, nl_fib_input, - NULL, THIS_MODULE); + fibnl = netlink_kernel_create(&init_net, NETLINK_FIB_LOOKUP, 0, + nl_fib_input, NULL, THIS_MODULE); } static void fib_disable_ip(struct net_device *dev, int force) diff --git a/net/ipv4/inet_diag.c b/net/ipv4/inet_diag.c index b04a6ee5a9a1..7eb83ebed2ec 100644 --- a/net/ipv4/inet_diag.c +++ b/net/ipv4/inet_diag.c @@ -839,15 +839,11 @@ static int inet_diag_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) static DEFINE_MUTEX(inet_diag_mutex); -static void inet_diag_rcv(struct sock *sk, int len) +static void inet_diag_rcv(struct sk_buff *skb) { - unsigned int qlen = 0; - - do { - mutex_lock(&inet_diag_mutex); - qlen = netlink_run_queue(sk, qlen, &inet_diag_rcv_msg); - mutex_unlock(&inet_diag_mutex); - } while (qlen); + mutex_lock(&inet_diag_mutex); + netlink_rcv_skb(skb, &inet_diag_rcv_msg); + mutex_unlock(&inet_diag_mutex); } static DEFINE_SPINLOCK(inet_diag_register_lock); diff --git a/net/ipv4/netfilter/ip_queue.c b/net/ipv4/netfilter/ip_queue.c index aaa3f5c56761..23cbfc7c80fd 100644 --- a/net/ipv4/netfilter/ip_queue.c +++ b/net/ipv4/netfilter/ip_queue.c @@ -475,7 +475,7 @@ ipq_dev_drop(int ifindex) #define RCV_SKB_FAIL(err) do { netlink_ack(skb, nlh, (err)); return; } while (0) static inline void -ipq_rcv_skb(struct sk_buff *skb) +__ipq_rcv_skb(struct sk_buff *skb) { int status, type, pid, flags, nlmsglen, skblen; struct nlmsghdr *nlh; @@ -533,19 +533,10 @@ ipq_rcv_skb(struct sk_buff *skb) } static void -ipq_rcv_sk(struct sock *sk, int len) +ipq_rcv_skb(struct sk_buff *skb) { - struct sk_buff *skb; - unsigned int qlen; - mutex_lock(&ipqnl_mutex); - - for (qlen = skb_queue_len(&sk->sk_receive_queue); qlen; qlen--) { - skb = skb_dequeue(&sk->sk_receive_queue); - ipq_rcv_skb(skb); - kfree_skb(skb); - } - + __ipq_rcv_skb(skb); mutex_unlock(&ipqnl_mutex); } @@ -670,7 +661,7 @@ static int __init ip_queue_init(void) netlink_register_notifier(&ipq_nl_notifier); ipqnl = netlink_kernel_create(&init_net, NETLINK_FIREWALL, 0, - ipq_rcv_sk, NULL, THIS_MODULE); + ipq_rcv_skb, NULL, THIS_MODULE); if (ipqnl == NULL) { printk(KERN_ERR "ip_queue: failed to create netlink socket\n"); goto cleanup_netlink_notifier; diff --git a/net/ipv6/netfilter/ip6_queue.c b/net/ipv6/netfilter/ip6_queue.c index c75f467a8f51..0473145ac534 100644 --- a/net/ipv6/netfilter/ip6_queue.c +++ b/net/ipv6/netfilter/ip6_queue.c @@ -464,7 +464,7 @@ ipq_dev_drop(int ifindex) #define RCV_SKB_FAIL(err) do { netlink_ack(skb, nlh, (err)); return; } while (0) static inline void -ipq_rcv_skb(struct sk_buff *skb) +__ipq_rcv_skb(struct sk_buff *skb) { int status, type, pid, flags, nlmsglen, skblen; struct nlmsghdr *nlh; @@ -522,19 +522,10 @@ ipq_rcv_skb(struct sk_buff *skb) } static void -ipq_rcv_sk(struct sock *sk, int len) +ipq_rcv_skb(struct sk_buff *skb) { - struct sk_buff *skb; - unsigned int qlen; - mutex_lock(&ipqnl_mutex); - - for (qlen = skb_queue_len(&sk->sk_receive_queue); qlen; qlen--) { - skb = skb_dequeue(&sk->sk_receive_queue); - ipq_rcv_skb(skb); - kfree_skb(skb); - } - + __ipq_rcv_skb(skb); mutex_unlock(&ipqnl_mutex); } @@ -658,8 +649,8 @@ static int __init ip6_queue_init(void) struct proc_dir_entry *proc; netlink_register_notifier(&ipq_nl_notifier); - ipqnl = netlink_kernel_create(&init_net, NETLINK_IP6_FW, 0, ipq_rcv_sk, - NULL, THIS_MODULE); + ipqnl = netlink_kernel_create(&init_net, NETLINK_IP6_FW, 0, + ipq_rcv_skb, NULL, THIS_MODULE); if (ipqnl == NULL) { printk(KERN_ERR "ip6_queue: failed to create netlink socket\n"); goto cleanup_netlink_notifier; diff --git a/net/netfilter/nfnetlink.c b/net/netfilter/nfnetlink.c index 99775af19ff4..2128542995f7 100644 --- a/net/netfilter/nfnetlink.c +++ b/net/netfilter/nfnetlink.c @@ -169,15 +169,11 @@ static int nfnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) } } -static void nfnetlink_rcv(struct sock *sk, int len) +static void nfnetlink_rcv(struct sk_buff *skb) { - unsigned int qlen = 0; - - do { - nfnl_lock(); - qlen = netlink_run_queue(sk, qlen, nfnetlink_rcv_msg); - nfnl_unlock(); - } while (qlen); + nfnl_lock(); + netlink_rcv_skb(skb, &nfnetlink_rcv_msg); + nfnl_unlock(); } static void __exit nfnetlink_exit(void) diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c index 4ce7dcbcb6ef..c776bcd9f825 100644 --- a/net/netlink/af_netlink.c +++ b/net/netlink/af_netlink.c @@ -80,7 +80,7 @@ struct netlink_sock { struct netlink_callback *cb; struct mutex *cb_mutex; struct mutex cb_def_mutex; - void (*data_ready)(struct sock *sk, int bytes); + void (*netlink_rcv)(struct sk_buff *skb); struct module *module; }; @@ -127,7 +127,6 @@ static DECLARE_WAIT_QUEUE_HEAD(nl_table_wait); static int netlink_dump(struct sock *sk); static void netlink_destroy_callback(struct netlink_callback *cb); -static void netlink_queue_skip(struct nlmsghdr *nlh, struct sk_buff *skb); static DEFINE_RWLOCK(nl_table_lock); static atomic_t nl_table_users = ATOMIC_INIT(0); @@ -709,21 +708,17 @@ static void netlink_overrun(struct sock *sk) static struct sock *netlink_getsockbypid(struct sock *ssk, u32 pid) { - int protocol = ssk->sk_protocol; - struct net *net; struct sock *sock; struct netlink_sock *nlk; - net = ssk->sk_net; - sock = netlink_lookup(net, protocol, pid); + sock = netlink_lookup(ssk->sk_net, ssk->sk_protocol, pid); if (!sock) return ERR_PTR(-ECONNREFUSED); /* Don't bother queuing skb if kernel socket has no input function */ nlk = nlk_sk(sock); - if ((netlink_is_kernel(sock) && !nlk->data_ready) || - (sock->sk_state == NETLINK_CONNECTED && - nlk->dst_pid != nlk_sk(ssk)->pid)) { + if (sock->sk_state == NETLINK_CONNECTED && + nlk->dst_pid != nlk_sk(ssk)->pid) { sock_put(sock); return ERR_PTR(-ECONNREFUSED); } @@ -837,7 +832,34 @@ static inline struct sk_buff *netlink_trim(struct sk_buff *skb, return skb; } -int netlink_unicast(struct sock *ssk, struct sk_buff *skb, u32 pid, int nonblock) +static inline void netlink_rcv_wake(struct sock *sk) +{ + struct netlink_sock *nlk = nlk_sk(sk); + + if (skb_queue_empty(&sk->sk_receive_queue)) + clear_bit(0, &nlk->state); + if (!test_bit(0, &nlk->state)) + wake_up_interruptible(&nlk->wait); +} + +static inline int netlink_unicast_kernel(struct sock *sk, struct sk_buff *skb) +{ + int ret; + struct netlink_sock *nlk = nlk_sk(sk); + + ret = -ECONNREFUSED; + if (nlk->netlink_rcv != NULL) { + ret = skb->len; + skb_set_owner_r(skb, sk); + nlk->netlink_rcv(skb); + } + kfree_skb(skb); + sock_put(sk); + return ret; +} + +int netlink_unicast(struct sock *ssk, struct sk_buff *skb, + u32 pid, int nonblock) { struct sock *sk; int err; @@ -852,6 +874,9 @@ retry: kfree_skb(skb); return PTR_ERR(sk); } + if (netlink_is_kernel(sk)) + return netlink_unicast_kernel(sk, skb); + err = netlink_attachskb(sk, skb, nonblock, timeo, ssk); if (err == 1) goto retry; @@ -1151,16 +1176,6 @@ static void netlink_cmsg_recv_pktinfo(struct msghdr *msg, struct sk_buff *skb) put_cmsg(msg, SOL_NETLINK, NETLINK_PKTINFO, sizeof(info), &info); } -static inline void netlink_rcv_wake(struct sock *sk) -{ - struct netlink_sock *nlk = nlk_sk(sk); - - if (skb_queue_empty(&sk->sk_receive_queue)) - clear_bit(0, &nlk->state); - if (!test_bit(0, &nlk->state)) - wake_up_interruptible(&nlk->wait); -} - static int netlink_sendmsg(struct kiocb *kiocb, struct socket *sock, struct msghdr *msg, size_t len) { @@ -1308,11 +1323,7 @@ out: static void netlink_data_ready(struct sock *sk, int len) { - struct netlink_sock *nlk = nlk_sk(sk); - - if (nlk->data_ready) - nlk->data_ready(sk, len); - netlink_rcv_wake(sk); + BUG(); } /* @@ -1323,7 +1334,7 @@ static void netlink_data_ready(struct sock *sk, int len) struct sock * netlink_kernel_create(struct net *net, int unit, unsigned int groups, - void (*input)(struct sock *sk, int len), + void (*input)(struct sk_buff *skb), struct mutex *cb_mutex, struct module *module) { struct socket *sock; @@ -1352,7 +1363,7 @@ netlink_kernel_create(struct net *net, int unit, unsigned int groups, sk = sock->sk; sk->sk_data_ready = netlink_data_ready; if (input) - nlk_sk(sk)->data_ready = input; + nlk_sk(sk)->netlink_rcv = input; if (netlink_insert(sk, net, 0)) goto out_sock_release; @@ -1552,12 +1563,7 @@ int netlink_dump_start(struct sock *ssk, struct sk_buff *skb, netlink_dump(sk); sock_put(sk); - - /* We successfully started a dump, by returning -EINTR we - * signal the queue mangement to interrupt processing of - * any netlink messages so userspace gets a chance to read - * the results. */ - return -EINTR; + return 0; } void netlink_ack(struct sk_buff *in_skb, struct nlmsghdr *nlh, int err) @@ -1594,13 +1600,15 @@ void netlink_ack(struct sk_buff *in_skb, struct nlmsghdr *nlh, int err) netlink_unicast(in_skb->sk, skb, NETLINK_CB(in_skb).pid, MSG_DONTWAIT); } -static int netlink_rcv_skb(struct sk_buff *skb, int (*cb)(struct sk_buff *, +int netlink_rcv_skb(struct sk_buff *skb, int (*cb)(struct sk_buff *, struct nlmsghdr *)) { struct nlmsghdr *nlh; int err; while (skb->len >= nlmsg_total_size(0)) { + int msglen; + nlh = nlmsg_hdr(skb); err = 0; @@ -1616,85 +1624,19 @@ static int netlink_rcv_skb(struct sk_buff *skb, int (*cb)(struct sk_buff *, goto skip; err = cb(skb, nlh); - if (err == -EINTR) { - /* Not an error, but we interrupt processing */ - netlink_queue_skip(nlh, skb); - return err; - } skip: if (nlh->nlmsg_flags & NLM_F_ACK || err) netlink_ack(skb, nlh, err); - netlink_queue_skip(nlh, skb); + msglen = NLMSG_ALIGN(nlh->nlmsg_len); + if (msglen > skb->len) + msglen = skb->len; + skb_pull(skb, msglen); } return 0; } -/** - * nelink_run_queue - Process netlink receive queue. - * @sk: Netlink socket containing the queue - * @qlen: Initial queue length - * @cb: Callback function invoked for each netlink message found - * - * Processes as much as there was in the queue upon entry and invokes - * a callback function for each netlink message found. The callback - * function may refuse a message by returning a negative error code - * but setting the error pointer to 0 in which case this function - * returns with a qlen != 0. - * - * qlen must be initialized to 0 before the initial entry, afterwards - * the function may be called repeatedly until the returned qlen is 0. - * - * The callback function may return -EINTR to signal that processing - * of netlink messages shall be interrupted. In this case the message - * currently being processed will NOT be requeued onto the receive - * queue. - */ -unsigned int netlink_run_queue(struct sock *sk, unsigned int qlen, - int (*cb)(struct sk_buff *, struct nlmsghdr *)) -{ - struct sk_buff *skb; - - if (!qlen || qlen > skb_queue_len(&sk->sk_receive_queue)) - qlen = skb_queue_len(&sk->sk_receive_queue); - - for (; qlen; qlen--) { - skb = skb_dequeue(&sk->sk_receive_queue); - if (netlink_rcv_skb(skb, cb)) { - if (skb->len) - skb_queue_head(&sk->sk_receive_queue, skb); - else { - kfree_skb(skb); - qlen--; - } - break; - } - - kfree_skb(skb); - } - - return qlen; -} - -/** - * netlink_queue_skip - Skip netlink message while processing queue. - * @nlh: Netlink message to be skipped - * @skb: Socket buffer containing the netlink messages. - * - * Pulls the given netlink message off the socket buffer so the next - * call to netlink_queue_run() will not reconsider the message. - */ -static void netlink_queue_skip(struct nlmsghdr *nlh, struct sk_buff *skb) -{ - int msglen = NLMSG_ALIGN(nlh->nlmsg_len); - - if (msglen > skb->len) - msglen = skb->len; - - skb_pull(skb, msglen); -} - /** * nlmsg_notify - send a notification netlink message * @sk: netlink socket to use @@ -1998,7 +1940,7 @@ panic: core_initcall(netlink_proto_init); EXPORT_SYMBOL(netlink_ack); -EXPORT_SYMBOL(netlink_run_queue); +EXPORT_SYMBOL(netlink_rcv_skb); EXPORT_SYMBOL(netlink_broadcast); EXPORT_SYMBOL(netlink_dump_start); EXPORT_SYMBOL(netlink_kernel_create); diff --git a/net/netlink/genetlink.c b/net/netlink/genetlink.c index 3f1104dc128b..150579a21469 100644 --- a/net/netlink/genetlink.c +++ b/net/netlink/genetlink.c @@ -470,15 +470,11 @@ static int genl_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) return ops->doit(skb, &info); } -static void genl_rcv(struct sock *sk, int len) +static void genl_rcv(struct sk_buff *skb) { - unsigned int qlen = 0; - - do { - genl_lock(); - qlen = netlink_run_queue(sk, qlen, genl_rcv_msg); - genl_unlock(); - } while (qlen && genl_sock && genl_sock->sk_receive_queue.qlen); + genl_lock(); + netlink_rcv_skb(skb, &genl_rcv_msg); + genl_unlock(); } /************************************************************************** diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c index 5238f6a8dfad..d41588d101d0 100644 --- a/net/xfrm/xfrm_user.c +++ b/net/xfrm/xfrm_user.c @@ -1895,16 +1895,11 @@ static int xfrm_user_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) return link->doit(skb, nlh, attrs); } -static void xfrm_netlink_rcv(struct sock *sk, int len) +static void xfrm_netlink_rcv(struct sk_buff *skb) { - unsigned int qlen = 0; - - do { - mutex_lock(&xfrm_cfg_mutex); - qlen = netlink_run_queue(sk, qlen, &xfrm_user_rcv_msg); - mutex_unlock(&xfrm_cfg_mutex); - - } while (qlen); + mutex_lock(&xfrm_cfg_mutex); + netlink_rcv_skb(skb, &xfrm_user_rcv_msg); + mutex_unlock(&xfrm_cfg_mutex); } static inline size_t xfrm_expire_msgsize(void) -- cgit v1.2.3 From 9ef4429b31b86d486b56b6c179fe52b5c7152f13 Mon Sep 17 00:00:00 2001 From: Benjamin Thery Date: Wed, 10 Oct 2007 21:18:17 -0700 Subject: [NET]: Fix dev_put() and dev_hold() comments Trivial fix: Swap comments for dev_put() and dev_hold() to get them at the right place. Typo introduced by 4fa57c9ea9f36f9ca852f3a88ca5d2f1aebbc960. Signed-of-by: Benjamin Thery Signed-off-by: David S. Miller --- include/linux/netdevice.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 4848c7afa4e7..5a11f889e56a 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -1064,7 +1064,7 @@ extern void netdev_run_todo(void); * dev_put - release reference to device * @dev: network device * - * Hold reference to device to keep it from being freed. + * Release reference to device to allow it to be freed. */ static inline void dev_put(struct net_device *dev) { @@ -1075,7 +1075,7 @@ static inline void dev_put(struct net_device *dev) * dev_hold - get reference to device * @dev: network device * - * Release reference to device to allow it to be freed. + * Hold reference to device to keep it from being freed. */ static inline void dev_hold(struct net_device *dev) { -- cgit v1.2.3 From 31910575a9de61e78065e93846e8e7a4894a18bf Mon Sep 17 00:00:00 2001 From: Pierre Ynard Date: Wed, 10 Oct 2007 21:22:05 -0700 Subject: [IPv6]: Export userland ND options through netlink (RDNSS support) As discussed before, this patch provides userland with a way to access relevant options in Router Advertisements, after they are processed and validated by the kernel. Extra options are processed in a generic way; this patch only exports RDNSS options described in RFC5006, but support to control which options are exported could be easily added. A new rtnetlink message type is defined, to transport Neighbor Discovery options, along with optional context information. At the moment only the address of the router sending an RDNSS option is included, but additional attributes may be later defined, if needed by new use cases. Signed-off-by: Pierre Ynard Signed-off-by: David S. Miller --- include/linux/rtnetlink.h | 29 +++++++++++++ include/net/ndisc.h | 1 + net/ipv6/ndisc.c | 103 ++++++++++++++++++++++++++++++++++++++++++---- 3 files changed, 124 insertions(+), 9 deletions(-) (limited to 'include/linux') diff --git a/include/linux/rtnetlink.h b/include/linux/rtnetlink.h index dff3192374f8..5bf618241ab9 100644 --- a/include/linux/rtnetlink.h +++ b/include/linux/rtnetlink.h @@ -97,6 +97,9 @@ enum { RTM_SETNEIGHTBL, #define RTM_SETNEIGHTBL RTM_SETNEIGHTBL + RTM_NEWNDUSEROPT = 68, +#define RTM_NEWNDUSEROPT RTM_NEWNDUSEROPT + __RTM_MAX, #define RTM_MAX (((__RTM_MAX + 3) & ~3) - 1) }; @@ -479,6 +482,30 @@ enum #define TCA_RTA(r) ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct tcmsg)))) #define TCA_PAYLOAD(n) NLMSG_PAYLOAD(n,sizeof(struct tcmsg)) +/******************************************************************** + * Neighbor Discovery userland options + ****/ + +struct nduseroptmsg +{ + unsigned char nduseropt_family; + unsigned char nduseropt_pad1; + unsigned short nduseropt_opts_len; /* Total length of options */ + __u8 nduseropt_icmp_type; + __u8 nduseropt_icmp_code; + unsigned short nduseropt_pad2; + /* Followed by one or more ND options */ +}; + +enum +{ + NDUSEROPT_UNSPEC, + NDUSEROPT_SRCADDR, + __NDUSEROPT_MAX +}; + +#define NDUSEROPT_MAX (__NDUSEROPT_MAX - 1) + #ifndef __KERNEL__ /* RTnetlink multicast groups - backwards compatibility for userspace */ #define RTMGRP_LINK 1 @@ -542,6 +569,8 @@ enum rtnetlink_groups { #define RTNLGRP_IPV6_PREFIX RTNLGRP_IPV6_PREFIX RTNLGRP_IPV6_RULE, #define RTNLGRP_IPV6_RULE RTNLGRP_IPV6_RULE + RTNLGRP_ND_USEROPT, +#define RTNLGRP_ND_USEROPT RTNLGRP_ND_USEROPT __RTNLGRP_MAX }; #define RTNLGRP_MAX (__RTNLGRP_MAX - 1) diff --git a/include/net/ndisc.h b/include/net/ndisc.h index 475b10c575b3..6684f7efbeeb 100644 --- a/include/net/ndisc.h +++ b/include/net/ndisc.h @@ -24,6 +24,7 @@ enum { ND_OPT_MTU = 5, /* RFC2461 */ __ND_OPT_ARRAY_MAX, ND_OPT_ROUTE_INFO = 24, /* RFC4191 */ + ND_OPT_RDNSS = 25, /* RFC5006 */ __ND_OPT_MAX }; diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c index d4acd283111b..6cc33dc83d1c 100644 --- a/net/ipv6/ndisc.c +++ b/net/ipv6/ndisc.c @@ -15,9 +15,10 @@ /* * Changes: * + * Pierre Ynard : export userland ND options + * through netlink (RDNSS support) * Lars Fenneberg : fixed MTU setting on receipt * of an RA. - * * Janos Farkas : kmalloc failure checks * Alexey Kuznetsov : state machine reworked * and moved to net/core. @@ -78,6 +79,9 @@ #include #include +#include +#include + #include #include #include @@ -161,6 +165,8 @@ struct ndisc_options { struct nd_opt_hdr *nd_opts_ri; struct nd_opt_hdr *nd_opts_ri_end; #endif + struct nd_opt_hdr *nd_useropts; + struct nd_opt_hdr *nd_useropts_end; }; #define nd_opts_src_lladdr nd_opt_array[ND_OPT_SOURCE_LL_ADDR] @@ -225,6 +231,22 @@ static struct nd_opt_hdr *ndisc_next_option(struct nd_opt_hdr *cur, return (cur <= end && cur->nd_opt_type == type ? cur : NULL); } +static inline int ndisc_is_useropt(struct nd_opt_hdr *opt) +{ + return (opt->nd_opt_type == ND_OPT_RDNSS); +} + +static struct nd_opt_hdr *ndisc_next_useropt(struct nd_opt_hdr *cur, + struct nd_opt_hdr *end) +{ + if (!cur || !end || cur >= end) + return NULL; + do { + cur = ((void *)cur) + (cur->nd_opt_len << 3); + } while(cur < end && !ndisc_is_useropt(cur)); + return (cur <= end && ndisc_is_useropt(cur) ? cur : NULL); +} + static struct ndisc_options *ndisc_parse_options(u8 *opt, int opt_len, struct ndisc_options *ndopts) { @@ -267,14 +289,21 @@ static struct ndisc_options *ndisc_parse_options(u8 *opt, int opt_len, break; #endif default: - /* - * Unknown options must be silently ignored, - * to accommodate future extension to the protocol. - */ - ND_PRINTK2(KERN_NOTICE - "%s(): ignored unsupported option; type=%d, len=%d\n", - __FUNCTION__, - nd_opt->nd_opt_type, nd_opt->nd_opt_len); + if (ndisc_is_useropt(nd_opt)) { + ndopts->nd_useropts_end = nd_opt; + if (!ndopts->nd_useropts) + ndopts->nd_useropts = nd_opt; + } else { + /* + * Unknown options must be silently ignored, + * to accommodate future extension to the + * protocol. + */ + ND_PRINTK2(KERN_NOTICE + "%s(): ignored unsupported option; type=%d, len=%d\n", + __FUNCTION__, + nd_opt->nd_opt_type, nd_opt->nd_opt_len); + } } opt_len -= l; nd_opt = ((void *)nd_opt) + l; @@ -984,6 +1013,53 @@ out: in6_dev_put(idev); } +static void ndisc_ra_useropt(struct sk_buff *ra, struct nd_opt_hdr *opt) +{ + struct icmp6hdr *icmp6h = (struct icmp6hdr *)skb_transport_header(ra); + struct sk_buff *skb; + struct nlmsghdr *nlh; + struct nduseroptmsg *ndmsg; + int err; + int base_size = NLMSG_ALIGN(sizeof(struct nduseroptmsg) + + (opt->nd_opt_len << 3)); + size_t msg_size = base_size + nla_total_size(sizeof(struct in6_addr)); + + skb = nlmsg_new(msg_size, GFP_ATOMIC); + if (skb == NULL) { + err = -ENOBUFS; + goto errout; + } + + nlh = nlmsg_put(skb, 0, 0, RTM_NEWNDUSEROPT, base_size, 0); + if (nlh == NULL) { + goto nla_put_failure; + } + + ndmsg = nlmsg_data(nlh); + ndmsg->nduseropt_family = AF_INET6; + ndmsg->nduseropt_icmp_type = icmp6h->icmp6_type; + ndmsg->nduseropt_icmp_code = icmp6h->icmp6_code; + ndmsg->nduseropt_opts_len = opt->nd_opt_len << 3; + + memcpy(ndmsg + 1, opt, opt->nd_opt_len << 3); + + NLA_PUT(skb, NDUSEROPT_SRCADDR, sizeof(struct in6_addr), + &ipv6_hdr(ra)->saddr); + nlmsg_end(skb, nlh); + + err = rtnl_notify(skb, 0, RTNLGRP_ND_USEROPT, NULL, GFP_ATOMIC); + if (err < 0) + goto errout; + + return; + +nla_put_failure: + nlmsg_free(skb); + err = -EMSGSIZE; +errout: + rtnl_set_sk_err(RTNLGRP_ND_USEROPT, err); +} + static void ndisc_router_discovery(struct sk_buff *skb) { struct ra_msg *ra_msg = (struct ra_msg *)skb_transport_header(skb); @@ -1216,6 +1292,15 @@ skip_defrtr: } } + if (ndopts.nd_useropts) { + struct nd_opt_hdr *opt; + for (opt = ndopts.nd_useropts; + opt; + opt = ndisc_next_useropt(opt, ndopts.nd_useropts_end)) { + ndisc_ra_useropt(skb, opt); + } + } + if (ndopts.nd_opts_tgt_lladdr || ndopts.nd_opts_rh) { ND_PRINTK2(KERN_WARNING "ICMPv6 RA: invalid RA options"); -- cgit v1.2.3 From b08d6cb22c777c8c91c16d8e3b8aafc93c98cbd9 Mon Sep 17 00:00:00 2001 From: Ilpo Järvinen Date: Thu, 11 Oct 2007 17:36:13 -0700 Subject: [TCP]: Limit processing lost_retrans loop to work-to-do cases MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This addition of lost_retrans_low to tcp_sock might be unnecessary, it's not clear how often lost_retrans worker is executed when there wasn't work to do. Signed-off-by: Ilpo Järvinen Signed-off-by: David S. Miller --- include/linux/tcp.h | 2 ++ net/ipv4/tcp_input.c | 14 +++++++++++--- net/ipv4/tcp_output.c | 2 ++ 3 files changed, 15 insertions(+), 3 deletions(-) (limited to 'include/linux') diff --git a/include/linux/tcp.h b/include/linux/tcp.h index 9ff456e8d6c7..c5b94c1a5ee2 100644 --- a/include/linux/tcp.h +++ b/include/linux/tcp.h @@ -348,6 +348,8 @@ struct tcp_sock { int lost_cnt_hint; int retransmit_cnt_hint; + u32 lost_retrans_low; /* Sent seq after any rxmit (lowest) */ + u16 advmss; /* Advertised MSS */ u16 prior_ssthresh; /* ssthresh saved at recovery start */ u32 lost_out; /* Lost packets */ diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index d5e0fcc22a3b..0a42e9340346 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c @@ -1112,7 +1112,8 @@ static int tcp_is_sackblock_valid(struct tcp_sock *tp, int is_dsack, * * Search retransmitted skbs from write_queue that were sent when snd_nxt was * less than what is now known to be received by the other end (derived from - * SACK blocks by the caller). + * SACK blocks by the caller). Also calculate the lowest snd_nxt among the + * remaining retransmitted skbs to avoid some costly processing per ACKs. */ static int tcp_mark_lost_retrans(struct sock *sk, u32 received_upto) { @@ -1120,6 +1121,7 @@ static int tcp_mark_lost_retrans(struct sock *sk, u32 received_upto) struct sk_buff *skb; int flag = 0; int cnt = 0; + u32 new_low_seq = 0; tcp_for_write_queue(skb, sk) { u32 ack_seq = TCP_SKB_CB(skb)->ack_seq; @@ -1151,9 +1153,15 @@ static int tcp_mark_lost_retrans(struct sock *sk, u32 received_upto) NET_INC_STATS_BH(LINUX_MIB_TCPLOSTRETRANSMIT); } } else { + if (!new_low_seq || before(ack_seq, new_low_seq)) + new_low_seq = ack_seq; cnt += tcp_skb_pcount(skb); } } + + if (tp->retrans_out) + tp->lost_retrans_low = new_low_seq; + return flag; } @@ -1481,8 +1489,8 @@ tcp_sacktag_write_queue(struct sock *sk, struct sk_buff *ack_skb, u32 prior_snd_ } } - if (tp->retrans_out && highest_sack_end_seq && - after(highest_sack_end_seq, tp->high_seq) && + if (tp->retrans_out && + after(highest_sack_end_seq, tp->lost_retrans_low) && icsk->icsk_ca_state == TCP_CA_Recovery) flag |= tcp_mark_lost_retrans(sk, highest_sack_end_seq); diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index 53296753b0bd..324b4207254a 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c @@ -1914,6 +1914,8 @@ int tcp_retransmit_skb(struct sock *sk, struct sk_buff *skb) printk(KERN_DEBUG "retrans_out leaked.\n"); } #endif + if (!tp->retrans_out) + tp->lost_retrans_low = tp->snd_nxt; TCP_SKB_CB(skb)->sacked |= TCPCB_RETRANS; tp->retrans_out += tcp_skb_pcount(skb); -- cgit v1.2.3