* [PATCH v2 2/7] AMSO1100 WR / Event Definitions.
From: Steve Wise @ 2006-06-07 20:39 UTC (permalink / raw)
To: rdreier; +Cc: mshefty, linux-kernel, netdev, openib-general
In-Reply-To: <20060607200646.9259.24588.stgit@stevo-desktop>
[-- Attachment #1: Type: text/plain, Size: 240 bytes --]
Resending 2/7 gziped.
linux-kernel and netdev mailing lists didn't formward the plain text
patch...
If anywone knows how to address this issue, please email me directly cuz
I don't know why 2/7 didn't get forwarded.
Sorry.
Steve.
[-- Attachment #2: amso1100_wr.gz --]
[-- Type: application/x-gzip, Size: 10387 bytes --]
^ permalink raw reply
* Re: [PATCH v2 2/7] AMSO1100 WR / Event Definitions.
From: Roland Dreier @ 2006-06-07 20:43 UTC (permalink / raw)
To: Steve Wise; +Cc: mshefty, linux-kernel, netdev, openib-general
In-Reply-To: <1149712762.27684.82.camel@stevo-desktop>
I just realized it could be the spam filters. You have some comments
with three 'X's in a row which might be getting it blocked. Is that
possible?
- R.
^ permalink raw reply
* Re: Updated sysctl documentation take #2
From: Diego Calleja @ 2006-06-07 20:55 UTC (permalink / raw)
To: Stephen Hemminger; +Cc: linux-kernel, netdev
In-Reply-To: <20060607124641.516c7fff@localhost.localdomain>
El Wed, 7 Jun 2006 12:46:41 -0700,
Stephen Hemminger <shemminger@osdl.org> escribió:
> The network stuff was all in Documentation/networking/ip-sysctl.txt.
> Someone else has already started fixing it.
Darn, didn't know that. Anyway, I merged that file into
Documentation/sysctl/ because IMO all sysctls must be in the same
place.
^ permalink raw reply
* Re: [PATCH v2 2/7] AMSO1100 WR / Event Definitions.
From: Steve Wise @ 2006-06-07 20:59 UTC (permalink / raw)
To: Roland Dreier; +Cc: mshefty, linux-kernel, netdev, openib-general
In-Reply-To: <ada4pywg0ir.fsf@cisco.com>
On Wed, 2006-06-07 at 13:43 -0700, Roland Dreier wrote:
> I just realized it could be the spam filters. You have some comments
> with three 'X's in a row which might be getting it blocked. Is that
> possible?
There are other files that have comments with 'XXX' like c2_provider.c
and c2_qp.c which is in patch 3/7 and it made it though.
These 'XXX' comments need to be cleaned up anyway, so I'll remove them
(or address the issue if there is one) and we'll see next time I post a
new version.
Steve.
^ permalink raw reply
* [PATCH] Updated Documentation/networking/ip-sysctl.txt
From: Robert Fitzsimons @ 2006-06-07 21:24 UTC (permalink / raw)
To: Diego Calleja; +Cc: Stephen Hemminger, linux-kernel, netdev
In-Reply-To: <20060607225551.9b7e9688.diegocg@gmail.com>
Reformatted entries so they are now sorted alphabetical within a
/proc/sys/net/ sub-directory.
Synced with 2.6.17-rc6, added markers for new entries which are missing
a description or new descriptions which need to be checked.
Added some missing descriptions, also added descriptions suggested by
Stephen Hemminger <shemminger@osdl.org>.
Updated some existing descriptions.
Use consistant formatting and text wrapping, and updated default values
to match code.
Signed-off-by: Robert Fitzsimons <robfitz@273k.net>
---
Hello Diego
I was working on updating ip-sysctl.txt as a kernel-janitors project as
suggested by Stephen.
Here is my work so far.
Robert
Documentation/networking/ip-sysctl.txt | 1565 +++++++++++++++++++-------------
1 files changed, 907 insertions(+), 658 deletions(-)
diff --git a/Documentation/networking/ip-sysctl.txt b/Documentation/networking/ip-sysctl.txt
index f12007b..94e6916 100644
--- a/Documentation/networking/ip-sysctl.txt
+++ b/Documentation/networking/ip-sysctl.txt
@@ -1,667 +1,822 @@
+/proc/sys/net/core/* Variables:
+
+dev_weight - INTEGER
+ TODO Add description.
+ Default: 64
+
+divert_version - STRING
+ TODO Check description.
+ String returned by DIVCMD_GETVERSION ioctl().
+ Default: 0.46
+
+message_burst - INTEGER
+ TODO Check description.
+ Allow a burst of message_burst network warning messages before the
+ rate limiting starts. Also see message_cost.
+ Default: 10
+
+message_cost - INTEGER
+ TODO Check description.
+ Rate limit the number of network warning messages to one every
+ message_cost seconds. Also see message_burst.
+ Default: 5
+
+netdev_budget - INTEGER
+ TODO Check description.
+ Maximum number of packets processed per device per softirq. Used to
+ stop a device from overloading the system under massive packet load.
+ Default: 300
+
+netdev_max_backlog - INTEGER
+ TODO Check description.
+ Limit on the outstanding receive packets queued per cpu. Applies to
+ non-NAPI devices only.
+ Default: 1000
+
+optmem_max - INTEGER
+ TODO Add description.
+
+rmem_default - INTEGER
+ TODO Add description.
+
+rmem_max - INTEGER
+ TODO Add description.
+
+somaxconn - INTEGER
+ Limit of socket listen() backlog, known in userspace as SOMAXCONN.
+ See also tcp_max_syn_backlog for additional tuning for TCP sockets.
+ Default: 128
+
+wmem_default - INTEGER
+ TODO Add description.
+
+wmem_max - INTEGER
+ TODO Add description.
+
+xfrm_aevent_etime - u32
+ TODO Add description.
+ Default: 10
+
+xfrm_aevent_rseqth - u32
+ TODO Add description.
+ Default: 2
+
+
/proc/sys/net/ipv4/* Variables:
-ip_forward - BOOLEAN
- 0 - disabled (default)
- not 0 - enabled
+icmp_echo_ignore_all - BOOLEAN
+ If set non-zero, then the kernel will ignore all ICMP ECHO requests
+ sent to it.
+ Default: 0
- Forward Packets between interfaces.
+icmp_echo_ignore_broadcasts - BOOLEAN
+ If set non-zero, then the kernel will ignore all ICMP ECHO and
+ TIMESTAMP requests sent to it via broadcast/multicast.
+ Default: 1
- This variable is special, its change resets all configuration
- parameters to their default state (RFC1122 for hosts, RFC1812
- for routers)
+icmp_errors_use_inbound_ifaddr - BOOLEAN
+ If zero, ICMP error messages are sent with the primary address of
+ the exiting interface.
-ip_default_ttl - INTEGER
- default 64
+ If non-zero, the message will be sent with the primary address of
+ the interface that received the packet that caused the ICMP error.
+ This is the behaviour network many administrators will expect from
+ a router. And it can make debugging complicated network layouts
+ much easier.
-ip_no_pmtu_disc - BOOLEAN
- Disable Path MTU Discovery.
- default FALSE
+ Note that if no primary address exists for the interface selected,
+ then the primary address of the first non-loopback interface that
+ has one will be used regardless of this setting.
+ Default: 0
-min_pmtu - INTEGER
- default 562 - minimum discovered Path MTU
+icmp_ignore_bogus_error_responses - BOOLEAN
+ Some routers violate RFC1122 by sending bogus responses to broadcast
+ frames. Such violations are normally logged via a kernel warning.
+ If this is set to TRUE, the kernel will not give such warnings,
+ which will avoid log file clutter.
+ Default: 1
-mtu_expires - INTEGER
- Time, in seconds, that cached PMTU information is kept.
+icmp_ratelimit - INTEGER
+ Limit the maximal rates for sending ICMP packets whose type matches
+ icmp_ratemask to specific targets.
+ 0 to disable any limiting, otherwise the maximal rate in jiffies(1)
+ Default: jiffies in one second
-min_adv_mss - INTEGER
- The advertised MSS depends on the first hop route MTU, but will
- never be lower than this setting.
+icmp_ratemask - INTEGER
+ Mask made of ICMP types for which rates are being limited.
-IP Fragmentation:
+ Bit definitions (see include/linux/icmp.h):
+ 0 Echo Reply
+ 3 Destination Unreachable *
+ 4 Source Quench *
+ 5 Redirect
+ 8 Echo Request
+ B Time Exceeded *
+ C Parameter Problem *
+ D Timestamp Request
+ E Timestamp Reply
+ F Info Request
+ G Info Reply
+ H Address Mask Request
+ I Address Mask Reply
+ * These are rate limited by default (see default mask above)
-ipfrag_high_thresh - INTEGER
- Maximum memory used to reassemble IP fragments. When
- ipfrag_high_thresh bytes of memory is allocated for this purpose,
- the fragment handler will toss packets until ipfrag_low_thresh
- is reached.
-
-ipfrag_low_thresh - INTEGER
- See ipfrag_high_thresh
+ Significant bits: IHGFEDCBA9876543210
+ Default mask: 0000001100000011000 (6168)
-ipfrag_time - INTEGER
- Time in seconds to keep an IP fragment in memory.
+igmp_max_memberships - INTEGER
+ Change the maximum number of multicast groups we can subscribe to.
+ Default: 20
-ipfrag_secret_interval - INTEGER
- Regeneration interval (in seconds) of the hash secret (or lifetime
- for the hash secret) for IP fragments.
- Default: 600
+igmp_max_msf - INTEGER
+ TODO Check description.
+ Limit on the number of multicast source filters.
+ Default: 10
-ipfrag_max_dist - INTEGER
- ipfrag_max_dist is a non-negative integer value which defines the
- maximum "disorder" which is allowed among fragments which share a
- common IP source address. Note that reordering of packets is
- not unusual, but if a large number of fragments arrive from a source
- IP address while a particular fragment queue remains incomplete, it
- probably indicates that one or more fragments belonging to that queue
- have been lost. When ipfrag_max_dist is positive, an additional check
- is done on fragments before they are added to a reassembly queue - if
- ipfrag_max_dist (or more) fragments have arrived from a particular IP
- address between additions to any IP fragment queue using that source
- address, it's presumed that one or more fragments in the queue are
- lost. The existing fragment queue will be dropped, and a new one
- started. An ipfrag_max_dist value of zero disables this check.
+inet_peer_gc_maxtime - INTEGER
+ Maximum interval between garbage collection passes. This interval
+ is in effect under low (or absent) memory pressure on the pool.
+ Default: 120 sec
- Using a very small value, e.g. 1 or 2, for ipfrag_max_dist can
- result in unnecessarily dropping fragment queues when normal
- reordering of packets occurs, which could lead to poor application
- performance. Using a very large value, e.g. 50000, increases the
- likelihood of incorrectly reassembling IP fragments that originate
- from different IP datagrams, which could result in data corruption.
- Default: 64
+inet_peer_gc_mintime - INTEGER
+ Minimum interval between garbage collection passes. This interval
+ is in effect under high memory pressure on the pool.
+ Default: 10 sec
-INET peer storage:
+inet_peer_maxttl - INTEGER
+ Maximum time-to-live of entries. Unused entries will expire after
+ this period of time if there is no memory pressure on the pool (i.e.
+ when the number of entries in the pool is very small).
+ Default: 600 sec
+
+inet_peer_minttl - INTEGER
+ Minimum time-to-live of entries. Should be enough to cover fragment
+ time-to-live on the reassembling side. This minimum time-to-live is
+ guaranteed if the pool size is less than inet_peer_threshold.
+ Default: 120 sec
inet_peer_threshold - INTEGER
- The approximate size of the storage. Starting from this threshold
+ The approximate size of the storage. Starting from this threshold
entries will be thrown aggressively. This threshold also determines
entries' time-to-live and time intervals between garbage collection
passes. More entries, less time-to-live, less GC interval.
+ Default: dependent on system memory
-inet_peer_minttl - INTEGER
- Minimum time-to-live of entries. Should be enough to cover fragment
- time-to-live on the reassembling side. This minimum time-to-live is
- guaranteed if the pool size is less than inet_peer_threshold.
- Measured in jiffies(1).
+ip_autoconfig - ????
+ TODO Add description.
-inet_peer_maxttl - INTEGER
- Maximum time-to-live of entries. Unused entries will expire after
- this period of time if there is no memory pressure on the pool (i.e.
- when the number of entries in the pool is very small).
- Measured in jiffies(1).
+ip_default_ttl - INTEGER
+ Default: 64
-inet_peer_gc_mintime - INTEGER
- Minimum interval between garbage collection passes. This interval is
- in effect under high memory pressure on the pool.
- Measured in jiffies(1).
+ip_dynaddr - BOOLEAN
+ If non-zero, enables support for dynamic addresses. If set to a
+ non-zero value larger than 1, a kernel log message will be printed
+ when dynamic address rewriting occurs.
+ Default: 0
-inet_peer_gc_maxtime - INTEGER
- Minimum interval between garbage collection passes. This interval is
- in effect under low (or absent) memory pressure on the pool.
- Measured in jiffies(1).
+ip_forward - BOOLEAN
+ If non-zero, forward packets between interfaces. This variable is
+ special, its change resets all configuration parameters to their
+ default state (RFC1122 for hosts, RFC1812 for routers).
+ Default: 0
-TCP variables:
+ipfrag_high_thresh - INTEGER
+ Maximum memory used to reassemble IP fragments. When
+ ipfrag_high_thresh bytes of memory is allocated for this purpose,
+ the fragment handler will toss packets until ipfrag_low_thresh is
+ reached.
+ Default: 256k
+
+ipfrag_low_thresh - INTEGER
+ See ipfrag_high_thresh.
+ Default: 192k
+
+ipfrag_max_dist - INTEGER
+ ipfrag_max_dist is a non-negative integer value which defines the
+ maximum "disorder" which is allowed among fragments which share a
+ common IP source address. Note that reordering of packets is not
+ unusual, but if a large number of fragments arrive from a source IP
+ address while a particular fragment queue remains incomplete, it
+ probably indicates that one or more fragments belonging to that
+ queue have been lost.
+
+ When ipfrag_max_dist is positive, an additional check is done on
+ fragments before they are added to a reassembly queue - if
+ ipfrag_max_dist (or more) fragments have arrived from a particular
+ IP address between additions to any IP fragment queue using that
+ source address, it's presumed that one or more fragments in the
+ queue are lost. The existing fragment queue will be dropped, and a
+ new one started. An ipfrag_max_dist value of zero disables this
+ check.
+
+ Using a very small value, e.g. 1 or 2, for ipfrag_max_dist can
+ result in unnecessarily dropping fragment queues when normal
+ reordering of packets occurs, which could lead to poor application
+ performance. Using a very large value, e.g. 50000, increases the
+ likelihood of incorrectly reassembling IP fragments that originate
+ from different IP datagrams, which could result in data corruption.
+ Default: 64
+
+ipfrag_secret_interval - INTEGER
+ Regeneration interval (in seconds) of the hash secret (or lifetime
+ for the hash secret) for IP fragments.
+ Default: 600
+
+ipfrag_time - INTEGER
+ Time in seconds to keep an IP fragment in memory.
+ Default: 30
+
+ip_local_port_range - 2 INTEGERS
+ Defines the local port range that is used by TCP and UDP to choose
+ the local port. The first number is the first, the second the last
+ local port number.
+
+ This number defines number of active connections, which this system
+ can issue simultaneously to systems not supporting TCP extensions
+ (timestamps). With tcp_tw_recycle enabled (i.e. by default) range
+ 1024-4999 is enough to issue up to 2000 connections per second to
+ systems supporting timestamps.
+ Default: dependent on system memory
+ > 128Mb 32768-61000
+ < 128Mb 1024-4999 or even less.
+
+ip_nonlocal_bind - BOOLEAN
+ If set, allows processes to bind() to non-local IP addresses, which
+ can be quite useful - but may break some applications.
+ Default: 0
+
+ip_no_pmtu_disc - BOOLEAN
+ Disable Path MTU Discovery.
+ Default: 0
tcp_abc - INTEGER
- Controls Appropriate Byte Count defined in RFC3465. If set to
- 0 then does congestion avoid once per ack. 1 is conservative
- value, and 2 is more agressive.
+ Controls Appropriate Byte Count defined in RFC3465. If set to 0
+ then does congestion avoid once per ACK. 1 is conservative value,
+ and 2 is more aggressive.
+ Default: 1
-tcp_syn_retries - INTEGER
- Number of times initial SYNs for an active TCP connection attempt
- will be retransmitted. Should not be higher than 255. Default value
- is 5, which corresponds to ~180seconds.
+tcp_abort_on_overflow - BOOLEAN
+ If listening service is too slow to accept new connections, reset
+ them. It means that if overflow occurred due to a burst, connection
+ will recover. Enable this option _only_ if you are really sure that
+ listening daemon cannot be tuned to accept connections faster.
+ Enabling this option can harm clients of your server.
+ Default: 0
-tcp_synack_retries - INTEGER
- Number of times SYNACKs for a passive TCP connection attempt will
- be retransmitted. Should not be higher than 255. Default value
- is 5, which corresponds to ~180seconds.
+tcp_adv_win_scale - INTEGER
+ Count buffering overhead as bytes/2^tcp_adv_win_scale
+ (if tcp_adv_win_scale > 0) or bytes-bytes/2^(-tcp_adv_win_scale),
+ if it is <= 0.
+ Default: 2
-tcp_keepalive_time - INTEGER
- How often TCP sends out keepalive messages when keepalive is enabled.
- Default: 2hours.
+tcp_app_win - INTEGER
+ Reserve max(window/2^tcp_app_win, mss) of window for application
+ buffer. Value 0 is special, it means that nothing is reserved.
+ Default: 31
-tcp_keepalive_probes - INTEGER
- How many keepalive probes TCP sends out, until it decides that the
- connection is broken. Default value: 9.
+tcp_base_mss - INTEGER
+ TODO Check description.
+ Lower bound for TCP path MTU discovery probing.
+ Default: 512
-tcp_keepalive_intvl - INTEGER
- How frequently the probes are send out. Multiplied by
- tcp_keepalive_probes it is time to kill not responding connection,
- after probes started. Default value: 75sec i.e. connection
- will be aborted after ~11 minutes of retries.
+tcp_congestion_control - STRING
+ Set the congestion control algorithm to be used for new connections.
+ The algorithm "reno" is always available, but additional choices may
+ be available based on kernel configuration.
-tcp_retries1 - INTEGER
- How many times to retry before deciding that something is wrong
- and it is necessary to report this suspicion to network layer.
- Minimal RFC value is 3, it is default, which corresponds
- to ~3sec-8min depending on RTO.
+tcp_dsack - BOOLEAN
+ Allows TCP to send "duplicate" SACKs.
+ Default: 1
-tcp_retries2 - INTEGER
- How may times to retry before killing alive TCP connection.
- RFC1122 says that the limit should be longer than 100 sec.
- It is too small number. Default value 15 corresponds to ~13-30min
- depending on RTO.
+tcp_ecn - BOOLEAN
+ Enable Explicit Congestion Notification in TCP.
+ Default: 0
-tcp_orphan_retries - INTEGER
- How may times to retry before killing TCP connection, closed
- by our side. Default value 7 corresponds to ~50sec-16min
- depending on RTO. If you machine is loaded WEB server,
- you should think about lowering this value, such sockets
- may consume significant resources. Cf. tcp_max_orphans.
+tcp_fack - BOOLEAN
+ Enable FACK congestion avoidance and fast retransmission. The value
+ is not used, if tcp_sack is not enabled.
+ Default: 1
tcp_fin_timeout - INTEGER
- Time to hold socket in state FIN-WAIT-2, if it was closed
- by our side. Peer can be broken and never close its side,
- or even died unexpectedly. Default value is 60sec.
- Usual value used in 2.2 was 180 seconds, you may restore
- it, but remember that if your machine is even underloaded WEB server,
- you risk to overflow memory with kilotons of dead sockets,
- FIN-WAIT-2 sockets are less dangerous than FIN-WAIT-1,
- because they eat maximum 1.5K of memory, but they tend
- to live longer. Cf. tcp_max_orphans.
+ Time in seconds to hold socket in state FIN-WAIT-2, if it was closed
+ by our side. Peer can be broken and never close its side, or even
+ died unexpectedly.
+
+ Usual value used in 2.2 was 180 seconds, you may restore it, but
+ remember that if your machine is even underloaded WEB server, you
+ risk to overflow memory with kilotons of dead sockets, FIN-WAIT-2
+ sockets are less dangerous than FIN-WAIT-1, because they eat maximum
+ 1.5K of memory, but they tend to live longer. See tcp_max_orphans.
+ Default: 60
-tcp_max_tw_buckets - INTEGER
- Maximal number of timewait sockets held by system simultaneously.
- If this number is exceeded time-wait socket is immediately destroyed
- and warning is printed. This limit exists only to prevent
- simple DoS attacks, you _must_ not lower the limit artificially,
- but rather increase it (probably, after increasing installed memory),
- if network conditions require more than default value.
+tcp_frto - BOOLEAN
+ Enables F-RTO, an enhanced recovery algorithm for TCP retransmission
+ timeouts. It is particularly beneficial in wireless environments
+ where packet loss is typically due to random radio interference
+ rather than intermediate router congestion.
+ Default: 0
-tcp_tw_recycle - BOOLEAN
- Enable fast recycling TIME-WAIT sockets. Default value is 0.
- It should not be changed without advice/request of technical
- experts.
+tcp_keepalive_intvl - INTEGER
+ How frequently the probes are send out. Multiplied by
+ tcp_keepalive_probes it is time to kill not responding connection,
+ after probes started.
+ Default: 75 secs
-tcp_tw_reuse - BOOLEAN
- Allow to reuse TIME-WAIT sockets for new connections when it is
- safe from protocol viewpoint. Default value is 0.
- It should not be changed without advice/request of technical
- experts.
+tcp_keepalive_probes - INTEGER
+ How many keepalive probes TCP sends out, until it decides that the
+ connection is broken.
+ Default: 9
+
+tcp_keepalive_time - INTEGER
+ How often TCP sends out keepalive messages when keepalive is
+ enabled.
+ Default: 2 hours
+
+tcp_low_latency - BOOLEAN
+ If set, the TCP stack makes decisions that prefer lower latency as
+ opposed to higher throughput. By default, this option is not set
+ meaning that higher throughput is preferred. An example of an
+ application where this default should be changed would be a Beowulf
+ compute cluster.
+ Default: 0
tcp_max_orphans - INTEGER
Maximal number of TCP sockets not attached to any user file handle,
- held by system. If this number is exceeded orphaned connections are
- reset immediately and warning is printed. This limit exists
- only to prevent simple DoS attacks, you _must_ not rely on this
- or lower the limit artificially, but rather increase it
- (probably, after increasing installed memory),
- if network conditions require more than default value,
- and tune network services to linger and kill such states
- more aggressively. Let me to remind again: each orphan eats
- up to ~64K of unswappable memory.
+ held by system. If this number is exceeded orphaned connections are
+ reset immediately and warning is printed. This limit exists only to
+ prevent simple DoS attacks, you _must_ not rely on this or lower the
+ limit artificially, but rather increase it (probably, after
+ increasing installed memory), if network conditions require more
+ than default value, and tune network services to linger and kill
+ such states more aggressively. Let me to remind again: each orphan
+ eats up to ~64K of unswappable memory.
-tcp_abort_on_overflow - BOOLEAN
- If listening service is too slow to accept new connections,
- reset them. Default state is FALSE. It means that if overflow
- occurred due to a burst, connection will recover. Enable this
- option _only_ if you are really sure that listening daemon
- cannot be tuned to accept connections faster. Enabling this
- option can harm clients of your server.
+tcp_max_syn_backlog - INTEGER
+ Maximal number of remembered connection requests, which are still
+ did not receive an acknowledgment from connecting client. If server
+ suffers of overload, try to increase this number.
+ Default: dependent on system memory
+ > 128Mb 1024
+ < 128Mb 128
-tcp_syncookies - BOOLEAN
- Only valid when the kernel was compiled with CONFIG_SYNCOOKIES
- Send out syncookies when the syn backlog queue of a socket
- overflows. This is to prevent against the common 'syn flood attack'
- Default: FALSE
+tcp_max_tw_buckets - INTEGER
+ Maximal number of time-wait sockets held by system simultaneously.
+ If this number is exceeded time-wait socket is immediately destroyed
+ and warning is printed. This limit exists only to prevent simple
+ DoS attacks, you _must_ not lower the limit artificially, but rather
+ increase it (probably, after increasing installed memory), if
+ network conditions require more than default value.
- Note, that syncookies is fallback facility.
- It MUST NOT be used to help highly loaded servers to stand
- against legal connection rate. If you see synflood warnings
- in your logs, but investigation shows that they occur
- because of overload with legal connections, you should tune
- another parameters until this warning disappear.
- See: tcp_max_syn_backlog, tcp_synack_retries, tcp_abort_on_overflow.
-
- syncookies seriously violate TCP protocol, do not allow
- to use TCP extensions, can result in serious degradation
- of some services (f.e. SMTP relaying), visible not by you,
- but your clients and relays, contacting you. While you see
- synflood warnings in logs not being really flooded, your server
- is seriously misconfigured.
+tcp_mem - vector of 3 INTEGERs: low, pressure, max
+ low: Below this number of pages TCP is not bothered about its memory
+ appetite.
-tcp_stdurg - BOOLEAN
- Use the Host requirements interpretation of the TCP urg pointer field.
- Most hosts use the older BSD interpretation, so if you turn this on
- Linux might not communicate correctly with them.
- Default: FALSE
-
-tcp_max_syn_backlog - INTEGER
- Maximal number of remembered connection requests, which are
- still did not receive an acknowledgment from connecting client.
- Default value is 1024 for systems with more than 128Mb of memory,
- and 128 for low memory machines. If server suffers of overload,
- try to increase this number.
+ pressure: When amount of memory allocated by TCP exceeds this number
+ of pages, TCP moderates its memory consumption and enters memory
+ pressure mode, which is exited when memory consumption falls under
+ "low".
-tcp_window_scaling - BOOLEAN
- Enable window scaling as defined in RFC1323.
+ max: Number of pages allowed for queueing by all TCP sockets.
-tcp_timestamps - BOOLEAN
- Enable timestamps as defined in RFC1323.
+ See tcp_rmem, tcp_wmem.
+ Default: dependent on system memory
-tcp_sack - BOOLEAN
- Enable select acknowledgments (SACKS).
+tcp_moderate_rcvbuf - BOOLEAN
+ TODO Check description.
+ If set TCP automatically adjusts the size of the socket receive
+ window based on the amount of space used in the receive queue.
+ Default: 1
-tcp_fack - BOOLEAN
- Enable FACK congestion avoidance and fast retransmission.
- The value is not used, if tcp_sack is not enabled.
+tcp_mtu_probing - INTEGER
+ TODO Check description.
+ If non-zero, then TCP attempts to discover routers that do not
+ correctly return ICMP fragmentation needed when receiving oversize
+ packets "black-holes". If the value is greater than one, don't use
+ the cached pmtu value before attempting to probe.
+ Default: 0
-tcp_dsack - BOOLEAN
- Allows TCP to send "duplicate" SACKs.
+tcp_no_metrics_save - BOOLEAN
+ TODO Check description.
+ Normally, TCP will remember some characteristics about the last
+ connection in the flow cache. If tcp_no_metrics_save is set, then
+ it doesn't. Useful for benchmarks or other tests.
+ Default: 0
-tcp_ecn - BOOLEAN
- Enable Explicit Congestion Notification in TCP.
+tcp_orphan_retries - INTEGER
+ How may times to retry before killing TCP connection, closed by our
+ side. If you machine is a loaded WEB server, you should think about
+ lowering this value, such sockets may consume significant resources.
+ See tcp_max_orphans.
+ Default: 0
tcp_reordering - INTEGER
Maximal reordering of packets in a TCP stream.
- Default: 3
+ Default: 3
tcp_retrans_collapse - BOOLEAN
- Bug-to-bug compatibility with some broken printers.
- On retransmit try to send bigger packets to work around bugs in
- certain TCP stacks.
+ Bug-to-bug compatibility with some broken printers. On retransmit
+ try to send bigger packets to work around bugs in certain TCP
+ stacks.
+ Default: 1
-tcp_wmem - vector of 3 INTEGERs: min, default, max
- min: Amount of memory reserved for send buffers for TCP socket.
- Each TCP socket has rights to use it due to fact of its birth.
- Default: 4K
+tcp_retries1 - INTEGER
+ How many times to retry before deciding that something is wrong and
+ it is necessary to report this suspicion to network layer. Minimal
+ RFC value is 3.
+ Default: 3
- default: Amount of memory allowed for send buffers for TCP socket
- by default. This value overrides net.core.wmem_default used
- by other protocols, it is usually lower than net.core.wmem_default.
- Default: 16K
+tcp_retries2 - INTEGER
+ How may times to retry before killing alive TCP connection. RFC1122
+ says that the limit should be longer than 100 sec. It is too small
+ number.
+ Default: 15
- max: Maximal amount of memory allowed for automatically selected
- send buffers for TCP socket. This value does not override
- net.core.wmem_max, "static" selection via SO_SNDBUF does not use this.
- Default: 128K
+tcp_rfc1337 - BOOLEAN
+ If set, the TCP stack behaves conforming to RFC1337. If unset, we
+ are not conforming to RFC, but prevent TCP TIME_WAIT assassination.
+ Default: 0
tcp_rmem - vector of 3 INTEGERs: min, default, max
- min: Minimal size of receive buffer used by TCP sockets.
- It is guaranteed to each TCP socket, even under moderate memory
- pressure.
- Default: 8K
-
- default: default size of receive buffer used by TCP sockets.
- This value overrides net.core.rmem_default used by other protocols.
- Default: 87380 bytes. This value results in window of 65535 with
+ min: Minimal size of receive buffer used by TCP sockets. It is
+ guaranteed to each TCP socket, even under moderate memory pressure.
+
+ default: Default size of receive buffer used by TCP sockets. This
+ value overrides net.core.rmem_default used by other protocols. The
+ default value of 87380 bytes, results in window of 65535 with
default setting of tcp_adv_win_scale and tcp_app_win:0 and a bit
- less for default tcp_app_win. See below about these variables.
+ less for default tcp_app_win.
- max: maximal size of receive buffer allowed for automatically
- selected receiver buffers for TCP socket. This value does not override
- net.core.rmem_max, "static" selection via SO_RCVBUF does not use this.
- Default: 87380*2 bytes.
+ max: Maximal size of receive buffer allowed for automatically
+ selected receiver buffers for TCP socket. This value does not
+ override net.core.rmem_max, "static" selection via SO_RCVBUF does
+ not use this.
+ See tcp_mem, tcp_wmem.
+ Default: 1 page, 16k, dependent on tcp_mem default
-tcp_mem - vector of 3 INTEGERs: min, pressure, max
- low: below this number of pages TCP is not bothered about its
- memory appetite.
+tcp_sack - BOOLEAN
+ Enable select acknowledgments (SACKS).
+ Default: 1
- pressure: when amount of memory allocated by TCP exceeds this number
- of pages, TCP moderates its memory consumption and enters memory
- pressure mode, which is exited when memory consumption falls
- under "low".
+tcp_stdurg - BOOLEAN
+ Use the Host requirements interpretation of the TCP urg pointer
+ field. Most hosts use the older BSD interpretation, so if you turn
+ this on Linux might not communicate correctly with them.
+ Default: 0
- high: number of pages allowed for queueing by all TCP sockets.
+tcp_synack_retries - INTEGER
+ Number of times SYNACKs for a passive TCP connection attempt will be
+ retransmitted. Should not be higher than 255.
+ Default: 5
- Defaults are calculated at boot time from amount of available
- memory.
+tcp_syncookies - BOOLEAN
+ Only valid when the kernel was compiled with CONFIG_SYNCOOKIES Send
+ out syncookies when the syn backlog queue of a socket overflows.
+ This is to prevent against the common 'syn flood attack'
-tcp_app_win - INTEGER
- Reserve max(window/2^tcp_app_win, mss) of window for application
- buffer. Value 0 is special, it means that nothing is reserved.
- Default: 31
+ Note, that syncookies is fallback facility.
+ It MUST NOT be used to help highly loaded servers to stand against
+ legal connection rate. If you see synflood warnings in your logs,
+ but investigation shows that they occur because of overload with
+ legal connections, you should tune another parameters until this
+ warning disappear. See tcp_max_syn_backlog, tcp_synack_retries,
+ tcp_abort_on_overflow.
+
+ syncookies seriously violate TCP protocol, do not allow to use TCP
+ extensions, can result in serious degradation of some services (f.e.
+ SMTP relaying), visible not by you, but your clients and relays,
+ contacting you. While you see synflood warnings in logs not being
+ really flooded, your server is seriously misconfigured.
+ Default: 0
-tcp_adv_win_scale - INTEGER
- Count buffering overhead as bytes/2^tcp_adv_win_scale
- (if tcp_adv_win_scale > 0) or bytes-bytes/2^(-tcp_adv_win_scale),
- if it is <= 0.
- Default: 2
+tcp_syn_retries - INTEGER
+ Number of times initial SYNs for an active TCP connection attempt
+ will be retransmitted. Should not be higher than 255.
+ Default: 5
-tcp_rfc1337 - BOOLEAN
- If set, the TCP stack behaves conforming to RFC1337. If unset,
- we are not conforming to RFC, but prevent TCP TIME_WAIT
- assassination.
+tcp_timestamps - BOOLEAN
+ Enable timestamps as defined in RFC1323.
+ Default: 1
+
+tcp_tso_win_divisor - INTEGER
+ This allows control over what percentage of the congestion window
+ can be consumed by a single TSO frame. The setting of this
+ parameter is a choice between burstiness and building larger TSO
+ frames.
+ Default: 3
+
+tcp_tw_recycle - BOOLEAN
+ Enable fast recycling TIME-WAIT sockets. The default value should
+ not be changed without advice/request of technical experts.
Default: 0
-tcp_low_latency - BOOLEAN
- If set, the TCP stack makes decisions that prefer lower
- latency as opposed to higher throughput. By default, this
- option is not set meaning that higher throughput is preferred.
- An example of an application where this default should be
- changed would be a Beowulf compute cluster.
+tcp_tw_reuse - BOOLEAN
+ Allow to reuse TIME-WAIT sockets for new connections when it is safe
+ from protocol viewpoint. The default value should not be changed
+ without advice/request of technical experts.
Default: 0
-tcp_tso_win_divisor - INTEGER
- This allows control over what percentage of the congestion window
- can be consumed by a single TSO frame.
- The setting of this parameter is a choice between burstiness and
- building larger TSO frames.
- Default: 3
+tcp_window_scaling - BOOLEAN
+ Enable window scaling as defined in RFC1323.
+ Default: 1
-tcp_frto - BOOLEAN
- Enables F-RTO, an enhanced recovery algorithm for TCP retransmission
- timeouts. It is particularly beneficial in wireless environments
- where packet loss is typically due to random radio interference
- rather than intermediate router congestion.
+tcp_wmem - vector of 3 INTEGERs: min, default, max
+ min: Amount of memory reserved for send buffers for TCP socket.
+ Each TCP socket has rights to use it due to fact of its birth.
-tcp_congestion_control - STRING
- Set the congestion control algorithm to be used for new
- connections. The algorithm "reno" is always available, but
- additional choices may be available based on kernel configuration.
+ default: Amount of memory allowed for send buffers for TCP socket by
+ default. This value overrides net.core.wmem_default used by other
+ protocols, it is usually lower than net.core.wmem_default.
-somaxconn - INTEGER
- Limit of socket listen() backlog, known in userspace as SOMAXCONN.
- Defaults to 128. See also tcp_max_syn_backlog for additional tuning
- for TCP sockets.
+ max: Maximal amount of memory allowed for automatically selected
+ send buffers for TCP socket. This value does not override
+ net.core.wmem_max, "static" selection via SO_SNDBUF does not use
+ this.
+ See tcp_mem, tcp_rmem.
+ Default: 1 page, 16k, dependent on tcp_mem default
tcp_workaround_signed_windows - BOOLEAN
If set, assume no receipt of a window scaling option means the
- remote TCP is broken and treats the window as a signed quantity.
- If unset, assume the remote TCP is not broken even if we do
- not receive a window scaling option from them.
+ remote TCP is broken and treats the window as a signed quantity. If
+ unset, assume the remote TCP is not broken even if we do not receive
+ a window scaling option from them.
Default: 0
-IP Variables:
-ip_local_port_range - 2 INTEGERS
- Defines the local port range that is used by TCP and UDP to
- choose the local port. The first number is the first, the
- second the last local port number. Default value depends on
- amount of memory available on the system:
- > 128Mb 32768-61000
- < 128Mb 1024-4999 or even less.
- This number defines number of active connections, which this
- system can issue simultaneously to systems not supporting
- TCP extensions (timestamps). With tcp_tw_recycle enabled
- (i.e. by default) range 1024-4999 is enough to issue up to
- 2000 connections per second to systems supporting timestamps.
-
-ip_nonlocal_bind - BOOLEAN
- If set, allows processes to bind() to non-local IP addresses,
- which can be quite useful - but may break some applications.
- Default: 0
+/proc/sys/net/ipv4/route/* Variables:
-ip_dynaddr - BOOLEAN
- If set non-zero, enables support for dynamic addresses.
- If set to a non-zero value larger than 1, a kernel log
- message will be printed when dynamic address rewriting
- occurs.
- Default: 0
-
-icmp_echo_ignore_all - BOOLEAN
- If set non-zero, then the kernel will ignore all ICMP ECHO
- requests sent to it.
- Default: 0
+error_burst - INTEGER
+ TODO Add description.
+ Default: 5
-icmp_echo_ignore_broadcasts - BOOLEAN
- If set non-zero, then the kernel will ignore all ICMP ECHO and
- TIMESTAMP requests sent to it via broadcast/multicast.
+error_cost - INTEGER
+ TODO Add description.
Default: 1
-icmp_ratelimit - INTEGER
- Limit the maximal rates for sending ICMP packets whose type matches
- icmp_ratemask (see below) to specific targets.
- 0 to disable any limiting, otherwise the maximal rate in jiffies(1)
- Default: 100
-
-icmp_ratemask - INTEGER
- Mask made of ICMP types for which rates are being limited.
- Significant bits: IHGFEDCBA9876543210
- Default mask: 0000001100000011000 (6168)
-
- Bit definitions (see include/linux/icmp.h):
- 0 Echo Reply
- 3 Destination Unreachable *
- 4 Source Quench *
- 5 Redirect
- 8 Echo Request
- B Time Exceeded *
- C Parameter Problem *
- D Timestamp Request
- E Timestamp Reply
- F Info Request
- G Info Reply
- H Address Mask Request
- I Address Mask Reply
+flush - INTEGER
+ TODO Add description.
+ Default: 0
- * These are rate limited by default (see default mask above)
+gc_elasticity - INTEGER
+ TODO Add description.
+ Default: 8
-icmp_ignore_bogus_error_responses - BOOLEAN
- Some routers violate RFC1122 by sending bogus responses to broadcast
- frames. Such violations are normally logged via a kernel warning.
- If this is set to TRUE, the kernel will not give such warnings, which
- will avoid log file clutter.
- Default: FALSE
+gc_interval - INTEGER
+ TODO Add description.
+ Default: 60
-icmp_errors_use_inbound_ifaddr - BOOLEAN
+gc_min_interval - INTEGER
+ TODO Check description.
+ Deprecated. Use gc_min_interval_ms.
- If zero, icmp error messages are sent with the primary address of
- the exiting interface.
-
- If non-zero, the message will be sent with the primary address of
- the interface that received the packet that caused the icmp error.
- This is the behaviour network many administrators will expect from
- a router. And it can make debugging complicated network layouts
- much easier.
+gc_min_interval_ms - INTEGER
+ TODO Add description.
+ Default: 500
- Note that if no primary address exists for the interface selected,
- then the primary address of the first non-loopback interface that
- has one will be used regarldess of this setting.
+gc_thresh - INTEGER
+ TODO Add description.
- Default: 0
+gc_timeout - INTEGER
+ TODO Add description.
+ Default: 300
-igmp_max_memberships - INTEGER
- Change the maximum number of multicast groups we can subscribe to.
- Default: 20
+max_delay - INTEGER
+ TODO Add description.
+ Default: 10
-conf/interface/* changes special settings per interface (where "interface" is
- the name of your network interface)
-conf/all/* is special, changes the settings for all interfaces
+max_size - INTEGER
+ TODO Add description.
+min_adv_mss - INTEGER
+ The advertised MSS depends on the first hop route MTU, but will
+ never be lower than this setting.
+ Default: 256
-log_martians - BOOLEAN
- Log packets with impossible addresses to kernel log.
- log_martians for the interface will be enabled if at least one of
- conf/{all,interface}/log_martians is set to TRUE,
- it will be disabled otherwise
+min_delay - INTEGER
+ TODO Add description.
+ Default: 2
-accept_redirects - BOOLEAN
- Accept ICMP redirect messages.
- accept_redirects for the interface will be enabled if:
- - both conf/{all,interface}/accept_redirects are TRUE in the case forwarding
- for the interface is enabled
- or
- - at least one of conf/{all,interface}/accept_redirects is TRUE in the case
- forwarding for the interface is disabled
- accept_redirects for the interface will be disabled otherwise
- default TRUE (host)
- FALSE (router)
+min_pmtu - INTEGER
+ Minimum discovered Path MTU
+ Default: 552
-forwarding - BOOLEAN
- Enable IP forwarding on this interface.
+mtu_expires - INTEGER
+ Time, in seconds, that cached PMTU information is kept.
+ Default: 600
-mc_forwarding - BOOLEAN
- Do multicast routing. The kernel needs to be compiled with CONFIG_MROUTE
- and a multicast routing daemon is required.
- conf/all/mc_forwarding must also be set to TRUE to enable multicast routing
- for the interface
+redirect_load - INTEGER
+ TODO Add description.
+ Default: 5
-medium_id - INTEGER
- Integer value used to differentiate the devices by the medium they
- are attached to. Two devices can have different id values when
- the broadcast packets are received only on one of them.
- The default value 0 means that the device is the only interface
- to its medium, value of -1 means that medium is not known.
-
- Currently, it is used to change the proxy_arp behavior:
- the proxy_arp feature is enabled for packets forwarded between
- two devices attached to different media.
+redirect_number - INTEGER
+ TODO Add description.
+ Default: 9
-proxy_arp - BOOLEAN
- Do proxy arp.
- proxy_arp for the interface will be enabled if at least one of
- conf/{all,interface}/proxy_arp is set to TRUE,
- it will be disabled otherwise
+redirect_silence - INTEGER
+ TODO Add description.
-shared_media - BOOLEAN
- Send(router) or accept(host) RFC1620 shared media redirects.
- Overrides ip_secure_redirects.
- shared_media for the interface will be enabled if at least one of
- conf/{all,interface}/shared_media is set to TRUE,
- it will be disabled otherwise
- default TRUE
+secret_interval - INTEGER
+ TODO Add description.
+ Default: 600
-secure_redirects - BOOLEAN
- Accept ICMP redirect messages only for gateways,
- listed in default gateway list.
- secure_redirects for the interface will be enabled if at least one of
- conf/{all,interface}/secure_redirects is set to TRUE,
- it will be disabled otherwise
- default TRUE
-send_redirects - BOOLEAN
- Send redirects, if router.
- send_redirects for the interface will be enabled if at least one of
- conf/{all,interface}/send_redirects is set to TRUE,
- it will be disabled otherwise
- Default: TRUE
+/proc/sys/net/ipv4/conf/*/*
+/proc/sys/net/ipv4/conf/all/*
+/proc/sys/net/ipv4/conf/default/*
-bootp_relay - BOOLEAN
- Accept packets with source address 0.b.c.d destined
- not to this host as local ones. It is supposed, that
- BOOTP relay daemon will catch and forward such packets.
- conf/all/bootp_relay must also be set to TRUE to enable BOOTP relay
- for the interface
- default FALSE
- Not Implemented Yet.
+accept_redirects - BOOLEAN
+ Accept ICMP redirect messages.
+ accept_redirects for the interface will be enabled if:
+ - both conf/{all,interface}/accept_redirects are TRUE in the case
+ forwarding for the interface is enabled
+ or
+ - at least one of conf/{all,interface}/accept_redirects is TRUE in
+ the case forwarding for the interface is disabled
+ accept_redirects for the interface will be disabled otherwise value
+ 1 (host) and 0 (router).
+ Default: 1
accept_source_route - BOOLEAN
- Accept packets with SRR option.
- conf/all/accept_source_route must also be set to TRUE to accept packets
- with SRR option on the interface
- default TRUE (router)
- FALSE (host)
+ Accept packets with SRR option. conf/all/accept_source_route must
+ also be set to 1 to accept packets with SRR option on the interface
+ value 1 (router) and 0 (host).
+ Default: 1
-rp_filter - BOOLEAN
- 1 - do source validation by reversed path, as specified in RFC1812
- Recommended option for single homed hosts and stub network
- routers. Could cause troubles for complicated (not loop free)
- networks running a slow unreliable protocol (sort of RIP),
- or using static routes.
+arp_accept - BOOLEAN
+ Define behavior when gratuitous ARP replies are received:
+ 0 - drop gratuitous ARP frames
+ 1 - accept gratuitous ARP frames
+ Default: 0
- 0 - No source validation.
+arp_announce - INTEGER
+ Define different restriction levels for announcing the local source
+ IP address from IP packets in ARP requests sent on interface:
+ 0 - Use any local address, configured on any interface.
+ 1 - Try to avoid local addresses that are not in the target's subnet
+ for this interface. This mode is useful when target hosts
+ reachable via this interface require the source IP address in
+ ARP requests to be part of their logical network configured on
+ the receiving interface. When we generate the request we will
+ check all our subnets that include the target IP and will
+ preserve the source address if it is from such subnet. If there
+ is no such subnet we select source address according to the
+ rules for level 2.
+ 2 - Always use the best local address for this target. In this mode
+ we ignore the source address in the IP packet and try to select
+ local address that we prefer for talks with the target host.
+ Such local address is selected by looking for primary IP
+ addresses on all our subnets on the outgoing interface that
+ include the target IP address. If no suitable local address is
+ found we select the first local address we have on the outgoing
+ interface or on all other interfaces, with the hope we will
+ receive reply for our request and even sometimes no matter the
+ source IP address we announce.
- conf/all/rp_filter must also be set to TRUE to do source validation
- on the interface
+ The max value from conf/{all,interface}/arp_announce is used.
- Default value is 0. Note that some distributions enable it
- in startup scripts.
+ Increasing the restriction level gives more chance for receiving
+ answer from the resolved target while decreasing the level announces
+ more valid sender's information.
+ Default: 0
arp_filter - BOOLEAN
1 - Allows you to have multiple network interfaces on the same
- subnet, and have the ARPs for each interface be answered
- based on whether or not the kernel would route a packet from
- the ARP'd IP out that interface (therefore you must use source
- based routing for this to work). In other words it allows control
- of which cards (usually 1) will respond to an arp request.
-
- 0 - (default) The kernel can respond to arp requests with addresses
- from other interfaces. This may seem wrong but it usually makes
- sense, because it increases the chance of successful communication.
- IP addresses are owned by the complete host on Linux, not by
- particular interfaces. Only for more complex setups like load-
- balancing, does this behaviour cause problems.
+ subnet, and have the ARPs for each interface be answered based
+ on whether or not the kernel would route a packet from the ARP'd
+ IP out that interface (therefore you must use source based
+ routing for this to work). In other words it allows control of
+ which cards (usually 1) will respond to an ARP request.
+
+ 0 - The kernel can respond to ARP requests with addresses from other
+ interfaces. This may seem wrong but it usually makes sense,
+ because it increases the chance of successful communication. IP
+ addresses are owned by the complete host on Linux, not by
+ particular interfaces. Only for more complex setups like load-
+ balancing, does this behaviour cause problems.
arp_filter for the interface will be enabled if at least one of
- conf/{all,interface}/arp_filter is set to TRUE,
- it will be disabled otherwise
-
-arp_announce - INTEGER
- Define different restriction levels for announcing the local
- source IP address from IP packets in ARP requests sent on
- interface:
- 0 - (default) Use any local address, configured on any interface
- 1 - Try to avoid local addresses that are not in the target's
- subnet for this interface. This mode is useful when target
- hosts reachable via this interface require the source IP
- address in ARP requests to be part of their logical network
- configured on the receiving interface. When we generate the
- request we will check all our subnets that include the
- target IP and will preserve the source address if it is from
- such subnet. If there is no such subnet we select source
- address according to the rules for level 2.
- 2 - Always use the best local address for this target.
- In this mode we ignore the source address in the IP packet
- and try to select local address that we prefer for talks with
- the target host. Such local address is selected by looking
- for primary IP addresses on all our subnets on the outgoing
- interface that include the target IP address. If no suitable
- local address is found we select the first local address
- we have on the outgoing interface or on all other interfaces,
- with the hope we will receive reply for our request and
- even sometimes no matter the source IP address we announce.
-
- The max value from conf/{all,interface}/arp_announce is used.
-
- Increasing the restriction level gives more chance for
- receiving answer from the resolved target while decreasing
- the level announces more valid sender's information.
+ conf/{all,interface}/arp_filter is set to 1, it will be disabled
+ otherwise.
+ Default: 0
arp_ignore - INTEGER
- Define different modes for sending replies in response to
- received ARP requests that resolve local target IP addresses:
- 0 - (default): reply for any local target IP address, configured
- on any interface
- 1 - reply only if the target IP address is local address
- configured on the incoming interface
- 2 - reply only if the target IP address is local address
- configured on the incoming interface and both with the
- sender's IP address are part from same subnet on this interface
- 3 - do not reply for local addresses configured with scope host,
- only resolutions for global and link addresses are replied
+ Define different modes for sending replies in response to received
+ ARP requests that resolve local target IP addresses:
+ 0 - reply for any local target IP address, configured on any
+ interface
+ 1 - reply only if the target IP address is local address
+ configured on the incoming interface
+ 2 - reply only if the target IP address is local address
+ configured on the incoming interface and both with the
+ sender's IP address are part from same subnet on this
+ interface
+ 3 - do not reply for local addresses configured with scope host,
+ only resolutions for global and link addresses are replied
4-7 - reserved
- 8 - do not reply for all local addresses
+ 8 - do not reply for all local addresses
- The max value from conf/{all,interface}/arp_ignore is used
- when ARP request is received on the {interface}
-
-arp_accept - BOOLEAN
- Define behavior when gratuitous arp replies are received:
- 0 - drop gratuitous arp frames
- 1 - accept gratuitous arp frames
+ The max value from conf/{all,interface}/arp_ignore is used when ARP
+ request is received on the {interface}.
+ Default: 0
-app_solicit - INTEGER
- The maximum number of probes to send to the user space ARP daemon
- via netlink before dropping back to multicast probes (see
- mcast_solicit). Defaults to 0.
+bootp_relay - BOOLEAN
+ Accept packets with source address 0.b.c.d destined not to this host
+ as local ones. It is supposed, that BOOTP relay daemon will catch
+ and forward such packets. conf/all/bootp_relay must also be set to
+ 1 to enable BOOTP relay for the interface.
+ Default: 0
+ Not Implemented Yet.
disable_policy - BOOLEAN
Disable IPSEC policy (SPD) for this interface
+ Default: 0
disable_xfrm - BOOLEAN
Disable IPSEC encryption on this interface, whatever the policy
+ Default: 0
+force_igmp_version - INTEGER
+ TODO Add description.
+forwarding - BOOLEAN
+ Enable IP forwarding on this interface.
+ Default: 0
-tag - INTEGER
- Allows you to write a number, which can be used as required.
- Default value is 0.
+log_martians - BOOLEAN
+ Log packets with impossible addresses to kernel log. log_martians
+ for the interface will be enabled if at least one of
+ conf/{all,interface}/log_martians is set to 1, it will be disabled
+ otherwise
+ Default: 0
-(1) Jiffie: internal timeunit for the kernel. On the i386 1/100s, on the
-Alpha 1/1024s. See the HZ define in /usr/include/asm/param.h for the exact
-value on your system.
+mc_forwarding - BOOLEAN
+ Do multicast routing. The kernel needs to be compiled with
+ CONFIG_MROUTE and a multicast routing daemon is required.
+ conf/all/mc_forwarding must also be set to 1 to enable multicast
+ routing for the interface
+ Default: 0
-Alexey Kuznetsov.
-kuznet@ms2.inr.ac.ru
+medium_id - INTEGER
+ Integer value used to differentiate the devices by the medium they
+ are attached to. Two devices can have different id values when the
+ broadcast packets are received only on one of them. The value 0
+ means that the device is the only interface to its medium, value of
+ -1 means that medium is not known.
+
+ Currently, it is used to change the proxy_arp behavior: the
+ proxy_arp feature is enabled for packets forwarded between two
+ devices attached to different media.
+ Default: 0
+
+promote_secondaries - ????
+ TODO Add description.
+
+proxy_arp - BOOLEAN
+ Do proxy ARP.
+ proxy_arp for the interface will be enabled if at least one of
+ conf/{all,interface}/proxy_arp is set to 1, it will be disabled
+ otherwise.
+ Default: 0
+
+rp_filter - BOOLEAN
+ 1 - do source validation by reversed path, as specified in RFC1812
+ Recommended option for single homed hosts and stub network
+ routers. Could cause troubles for complicated (not loop free)
+ networks running a slow unreliable protocol (sort of RIP), or
+ using static routes.
+ 0 - No source validation.
+
+ conf/all/rp_filter must also be set to 1 to do source validation on
+ the interface
+
+ Default: 0. Note that some distributions enable it in startup
+ scripts.
+
+secure_redirects - BOOLEAN
+ Accept ICMP redirect messages only for gateways, listed in default
+ gateway list.
+ secure_redirects for the interface will be enabled if at least one
+ of conf/{all,interface}/secure_redirects is set to 1, it will be
+ disabled otherwise
+ Default: 1
-Updated by:
-Andi Kleen
-ak@muc.de
-Nicolas Delon
-delon.nicolas@wanadoo.fr
+send_redirects - BOOLEAN
+ Send redirects, if router.
+ send_redirects for the interface will be enabled if at least one of
+ conf/{all,interface}/send_redirects is set to 1, it will be disabled
+ otherwise
+ Default: 1
+shared_media - BOOLEAN
+ Send(router) or accept(host) RFC1620 shared media redirects.
+ Overrides ip_secure_redirects.
+ shared_media for the interface will be enabled if at least one of
+ conf/{all,interface}/shared_media is set to 1, it will be disabled
+ otherwise
+ Default: 1
+tag - INTEGER
+ Allows you to write a number, which can be used as required.
+ Default: 0
/proc/sys/net/ipv6/* Variables:
@@ -670,155 +825,208 @@ IPv6 has no global variables such as tcp
apply to IPv6 [XXX?].
bindv6only - BOOLEAN
- Default value for IPV6_V6ONLY socket option,
- which restricts use of the IPv6 socket to IPv6 communication
- only.
- TRUE: disable IPv4-mapped address feature
- FALSE: enable IPv4-mapped address feature
-
- Default: FALSE (as specified in RFC2553bis)
-
-IPv6 Fragmentation:
+ Default value for IPV6_V6ONLY socket option, which restricts use of
+ the IPv6 socket to IPv6 communication only.
+ 1: disable IPv4-mapped address feature
+ 0: enable IPv4-mapped address feature
+ Default: 0 (as specified in RFC2553bis)
ip6frag_high_thresh - INTEGER
- Maximum memory used to reassemble IPv6 fragments. When
+ Maximum memory used to reassemble IPv6 fragments. When
ip6frag_high_thresh bytes of memory is allocated for this purpose,
- the fragment handler will toss packets until ip6frag_low_thresh
- is reached.
-
-ip6frag_low_thresh - INTEGER
- See ip6frag_high_thresh
+ the fragment handler will toss packets until ip6frag_low_thresh is
+ reached.
+ Default: 256k
-ip6frag_time - INTEGER
- Time in seconds to keep an IPv6 fragment in memory.
+ip6frag_low_thresh - INTEGER
+ See ip6frag_high_thresh
+ Default: 192k
ip6frag_secret_interval - INTEGER
- Regeneration interval (in seconds) of the hash secret (or lifetime
+ Regeneration interval (in seconds) of the hash secret (or lifetime
for the hash secret) for IPv6 fragments.
Default: 600
-conf/default/*:
- Change the interface-specific default settings.
+ip6frag_time - INTEGER
+ Time in seconds to keep an IPv6 fragment in memory.
+ Default: 60
+
+mld_max_msf - INTEGER
+ TODO Add description.
-conf/all/*:
- Change all the interface-specific settings.
+/proc/sys/net/ipv6/icmp/* Variables:
- [XXX: Other special features than forwarding?]
+ratelimit - INTEGER
+ Limit the maximal rates for sending ICMPv6 packets.
+ 0 to disable any limiting, otherwise the maximal rate in jiffies(1).
+ Default: jiffies in one second
-conf/all/forwarding - BOOLEAN
- Enable global IPv6 forwarding between all interfaces.
- IPv4 and IPv6 work differently here; e.g. netfilter must be used
- to control which interfaces may forward packets and which not.
+/proc/sys/net/ipv6/route/* Variables:
- This also sets all interfaces' Host/Router setting
- 'forwarding' to the specified value. See below for details.
+flush - INTEGER
+ TODO Add description.
+ See ipv4/route/flush description.
- This referred to as global forwarding.
+gc_elasticity - INTEGER
+ TODO Add description.
+ See ipv4/route/gc_elasticity description.
-conf/interface/*:
- Change special settings per interface.
+gc_interval - INTEGER
+ TODO Add description.
+ See ipv4/route/gc_interval description.
- The functional behaviour for certain settings is different
- depending on whether local forwarding is enabled or not.
+gc_min_interval - INTEGER
+ TODO Add description.
+ See ipv4/route/gc_min_interval description.
+
+gc_min_interval_ms - INTEGER
+ TODO Add description.
+ See ipv4/route/gc_min_interval_ms description.
+
+gc_thresh - INTEGER
+ TODO Add description.
+ See ipv4/route/gc_thresh description.
+
+gc_timeout - INTEGER
+ TODO Add description.
+ See ipv4/route/gc_timeout description.
+
+max_size - INTEGER
+ TODO Add description.
+ See ipv4/route/max_size description.
+
+min_adv_mss - INTEGER
+ TODO Add description.
+ See ipv4/route/min_adv_mss description.
+
+mtu_expires - INTEGER
+ TODO Add description.
+ See ipv4/route/mtu_expires description.
+
+
+/proc/sys/net/ipv6/conf/*/*
+/proc/sys/net/ipv6/conf/all/*
+/proc/sys/net/ipv6/conf/default/*
accept_ra - BOOLEAN
Accept Router Advertisements; autoconfigure using them.
-
- Functional default: enabled if local forwarding is disabled.
- disabled if local forwarding is enabled.
+
+ Default: enabled if local forwarding is disabled.
+ disabled if local forwarding is enabled.
accept_ra_defrtr - BOOLEAN
Learn default router in Router Advertisement.
- Functional default: enabled if accept_ra is enabled.
- disabled if accept_ra is disabled.
+ Default: enabled if accept_ra is enabled.
+ disabled if accept_ra is disabled.
accept_ra_pinfo - BOOLEAN
Learn Prefix Inforamtion in Router Advertisement.
- Functional default: enabled if accept_ra is enabled.
- disabled if accept_ra is disabled.
+ Default: enabled if accept_ra is enabled.
+ disabled if accept_ra is disabled.
accept_ra_rt_info_max_plen - INTEGER
Maximum prefix length of Route Information in RA.
- Route Information w/ prefix larger than or equal to this
- variable shall be ignored.
+ Route Information with prefix larger than or equal to this variable
+ shall be ignored.
- Functional default: 0 if accept_ra_rtr_pref is enabled.
- -1 if accept_ra_rtr_pref is disabled.
+ Default: 0 if accept_ra_rtr_pref is enabled.
+ -1 if accept_ra_rtr_pref is disabled.
accept_ra_rtr_pref - BOOLEAN
Accept Router Preference in RA.
- Functional default: enabled if accept_ra is enabled.
- disabled if accept_ra is disabled.
+ Default: enabled if accept_ra is enabled.
+ disabled if accept_ra is disabled.
accept_redirects - BOOLEAN
Accept Redirects.
- Functional default: enabled if local forwarding is disabled.
- disabled if local forwarding is enabled.
+ Default: enabled if local forwarding is disabled.
+ disabled if local forwarding is enabled.
autoconf - BOOLEAN
- Autoconfigure addresses using Prefix Information in Router
+ Autoconfigure addresses using Prefix Information in Router
Advertisements.
- Functional default: enabled if accept_ra_pinfo is enabled.
- disabled if accept_ra_pinfo is disabled.
+ Default: enabled if accept_ra_pinfo is enabled.
+ disabled if accept_ra_pinfo is disabled.
dad_transmits - INTEGER
The amount of Duplicate Address Detection probes to send.
Default: 1
-
+
+force_mld_version - INTEGER
+ TODO Add description.
+ Default: 0
+
forwarding - BOOLEAN
- Configure interface-specific Host/Router behaviour.
+ Configure interface-specific Host/Router behaviour.
- Note: It is recommended to have the same setting on all
- interfaces; mixed router/host scenarios are rather uncommon.
+ Note: It is recommended to have the same setting on all interfaces;
+ mixed router/host scenarios are rather uncommon.
- FALSE:
+ FALSE (0):
By default, Host behaviour is assumed. This means:
1. IsRouter flag is not set in Neighbour Advertisements.
2. Router Solicitations are being sent when necessary.
- 3. If accept_ra is TRUE (default), accept Router
- Advertisements (and do autoconfiguration).
- 4. If accept_redirects is TRUE (default), accept Redirects.
+ 3. If accept_ra is 1 (default), accept Router Advertisements (and
+ do autoconfiguration).
+ 4. If accept_redirects is 1 (default), accept Redirects.
- TRUE:
+ TRUE (1):
- If local forwarding is enabled, Router behaviour is assumed.
- This means exactly the reverse from the above:
+ If local forwarding is enabled, Router behaviour is assumed. This
+ means exactly the reverse from the above:
1. IsRouter flag is set in Neighbour Advertisements.
2. Router Solicitations are not sent.
3. Router Advertisements are ignored.
4. Redirects are ignored.
- Default: FALSE if global forwarding is disabled (default),
- otherwise TRUE.
+ Default: 0 if global forwarding is disabled (default),
+ otherwise 1.
hop_limit - INTEGER
Default Hop Limit to set.
Default: 64
+max_addresses - INTEGER
+ Number of maximum addresses per interface. 0 disables limitation.
+ It is recommended not set too large value (or 0) because it would be
+ too easy way to crash kernel to allow to create too much of
+ autoconfigured addresses.
+ Default: 16
+
+max_desync_factor - INTEGER
+ Maximum value in seconds for DESYNC_FACTOR, which is a random value
+ that ensures that clients don't synchronize with each other and
+ generate new addresses at exactly the same time.
+ Default: 600
+
mtu - INTEGER
Default Maximum Transfer Unit
Default: 1280 (IPv6 required minimum)
+regen_max_retry - INTEGER
+ Number of attempts before give up attempting to generate valid
+ temporary addresses.
+ Default: 5
+
router_probe_interval - INTEGER
Minimum interval (in seconds) between Router Probing described
in RFC4191.
-
Default: 60
router_solicitation_delay - INTEGER
- Number of seconds to wait after interface is brought up
- before sending Router Solicitations.
+ Number of seconds to wait after interface is brought up before
+ sending Router Solicitations.
Default: 1
router_solicitation_interval - INTEGER
@@ -826,57 +1034,102 @@ router_solicitation_interval - INTEGER
Default: 4
router_solicitations - INTEGER
- Number of Router Solicitations to send until assuming no
- routers are present.
+ Number of Router Solicitations to send until assuming no routers are
+ present.
Default: 3
+temp_prefered_lft - INTEGER
+ Preferred lifetime (in seconds) for temporary addresses.
+ Default: 86400 (1 day)
+
+temp_valid_lft - INTEGER
+ Valid lifetime (in seconds) for temporary addresses.
+ Default: 604800 (7 days)
+
use_tempaddr - INTEGER
Preference for Privacy Extensions (RFC3041).
<= 0 : disable Privacy Extensions
- == 1 : enable Privacy Extensions, but prefer public
- addresses over temporary addresses.
- > 1 : enable Privacy Extensions and prefer temporary
- addresses over public addresses.
- Default: 0 (for most devices)
- -1 (for point-to-point devices and loopback devices)
+ == 1 : enable Privacy Extensions, but prefer public addresses over
+ temporary addresses.
+ > 1 : enable Privacy Extensions and prefer temporary addresses
+ over public addresses.
+ Values 0 for most devices and -1 for point-to-point devices and
+ loopback devices.
+ Default: 0
-temp_valid_lft - INTEGER
- valid lifetime (in seconds) for temporary addresses.
- Default: 604800 (7 days)
-temp_prefered_lft - INTEGER
- Preferred lifetime (in seconds) for temporary addresses.
- Default: 86400 (1 day)
+/proc/sys/net/unix/* Variables:
-max_desync_factor - INTEGER
- Maximum value for DESYNC_FACTOR, which is a random value
- that ensures that clients don't synchronize with each
- other and generate new addresses at exactly the same time.
- value is in seconds.
- Default: 600
-
-regen_max_retry - INTEGER
- Number of attempts before give up attempting to generate
- valid temporary addresses.
- Default: 5
+max_dgram_qlen - INTEGER
+ TODO Add description.
+ Default: 10
-max_addresses - INTEGER
- Number of maximum addresses per interface. 0 disables limitation.
- It is recommended not set too large value (or 0) because it would
- be too easy way to crash kernel to allow to create too much of
- autoconfigured addresses.
- Default: 16
-icmp/*:
-ratelimit - INTEGER
- Limit the maximal rates for sending ICMPv6 packets.
- 0 to disable any limiting, otherwise the maximal rate in jiffies(1)
- Default: 100
+/proc/sys/net/ipv[46]/neigh/*/*
+/proc/sys/net/ipv[46]/neigh/default/*
+anycast_delay - INTEGER
+ TODO Add description.
-IPv6 Update by:
-Pekka Savola <pekkas@netcore.fi>
-YOSHIFUJI Hideaki / USAGI Project <yoshfuji@linux-ipv6.org>
+app_solicit - INTEGER
+ The maximum number of probes to send to the user space ARP daemon
+ via netlink before dropping back to multicast probes (see
+ mcast_solicit).
+ Default: 0
+
+base_reachable_time - INTEGER
+ TODO Check description.
+ See base_reachable_time_ms.
+
+base_reachable_time_ms - INTEGER
+ TODO Add description.
+ Default: 30000
+
+delay_first_probe_time - ????
+ TODO Add description.
+
+gc_interval - INTEGER
+ TODO Add description.
+ Default: 30
+
+gc_stale_time - ????
+ TODO Add description.
+
+gc_thresh1 - ????
+ TODO Add description.
+
+gc_thresh2 - ????
+ TODO Add description.
+
+gc_thresh3 - ????
+ TODO Add description.
+
+locktime - ????
+ TODO Add description.
+
+mcast_solicit - ????
+ TODO Add description.
+
+proxy_delay - INTEGER
+ TODO Add description.
+ Default: 80
+
+proxy_qlen - INTEGER
+ TODO Add description.
+ Default: 64
+
+retrans_time - ????
+ TODO Check description.
+ See retrans_time_ms.
+
+retrans_time_ms - ????
+ TODO Add description.
+
+ucast_solicit - ????
+ TODO Add description.
+
+unres_qlen - ????
+ TODO Add description.
/proc/sys/net/bridge/* Variables:
@@ -886,13 +1139,13 @@ bridge-nf-call-arptables - BOOLEAN
0 : disable this.
Default: 1
-bridge-nf-call-iptables - BOOLEAN
- 1 : pass bridged IPv4 traffic to iptables' chains.
+bridge-nf-call-ip6tables - BOOLEAN
+ 1 : pass bridged IPv6 traffic to ip6tables' chains.
0 : disable this.
Default: 1
-bridge-nf-call-ip6tables - BOOLEAN
- 1 : pass bridged IPv6 traffic to ip6tables' chains.
+bridge-nf-call-iptables - BOOLEAN
+ 1 : pass bridged IPv4 traffic to iptables' chains.
0 : disable this.
Default: 1
@@ -902,25 +1155,21 @@ bridge-nf-filter-vlan-tagged - BOOLEAN
Default: 1
-UNDOCUMENTED:
-
-dev_weight FIXME
-discovery_slots FIXME
-discovery_timeout FIXME
-fast_poll_increase FIXME
-ip6_queue_maxlen FIXME
-lap_keepalive_time FIXME
-lo_cong FIXME
-max_baud_rate FIXME
-max_dgram_qlen FIXME
-max_noreply_time FIXME
-max_tx_data_size FIXME
-max_tx_window FIXME
-min_tx_turn_time FIXME
-mod_cong FIXME
-no_cong FIXME
-no_cong_thresh FIXME
-slot_timeout FIXME
-warn_noreply_time FIXME
-
-$Id: ip-sysctl.txt,v 1.20 2001/12/13 09:00:18 davem Exp $
+(1) Jiffie: internal timeunit for the kernel. On the i386 1/100s, on the
+Alpha 1/1024s. See the HZ define in /usr/include/asm/param.h for the exact
+value on your system.
+
+
+IPv4:
+Alexey Kuznetsov <kuznet@ms2.inr.ac.ru>
+IPv4 Updated by:
+Andi Kleen <ak@muc.de>
+Nicolas Delon <delon.nicolas@wanadoo.fr>
+
+IPv6 Updated by:
+Pekka Savola <pekkas@netcore.fi>
+YOSHIFUJI Hideaki / USAGI Project <yoshfuji@linux-ipv6.org>
+
+Reformatted/Updated:
+Robert Fitzsimons <robfitz@273k.net>, June 2006 synced with 2.6.17-rc6.
+
--
1.3.3.g16a4-dirty
^ permalink raw reply related
* Re: [PATCH] pcnet32 driver NAPI support
From: Don Fry @ 2006-06-07 21:52 UTC (permalink / raw)
To: Lennart Sorensen; +Cc: netdev
In-Reply-To: <20060607193456.GN7857@csclub.uwaterloo.ca>
On Wed, Jun 07, 2006 at 03:34:56PM -0400, Lennart Sorensen wrote:
> On Wed, Jun 07, 2006 at 11:20:40AM -0700, Don Fry wrote:
>
> > Some areas of concern that you may have addressed already, I have not
> > scanned your changes yet, are what happens if the ring size is changed
> > without bringing down the interface (via ethtool), or if the loopback
> > test is run in a similar fashion, or a tx timeout occurs.
>
> The same thing as if it was done before enabling napi. From a few
> messages I have seen, it doesn't work right now, and it won't work any
> better with my changes. I have never tried changing the ring size on
> the fly, so I don't know.
Today without your NAPI changes the device can be up and operational,
and change the ring size without hanging or causing a panic or causing
problems with the driver. The same can be said for running the loopback
test, or when a tx timeout occurs.
It does not look like the same can be said for your NAPI changes, yet.
Try changing the ring size a dozen times during a receive storm and see
what happens.
>
> It appears that the port is stopped before the ring size change is done,
> although I can't really tell how it handles things if the queue is not
> empty when it stops the port. Does it try to handle anything left in
> the ring first or does it just toss those packets? (That I would
> consider wrong).
>
> > The lp->lock MUST be held whenever accessing the csr or bcr registers as
> > this is a multi-step process, and has been the source of problems in the
> > past. Even on UP systems.
>
> Hmm, I just followed what appeared to be in pcnet32_rx and how tulip and
> a few other drivers had done their napi conversions. It certainly works
> for me the way I did it. Haven't seen any lockups yet. I do see that I
> am not holding the lock when I acknowledge IRQs in pcnet32_poll, which
> pcnet32_rx doesn't need to worry about since it is called from the
> interrupt handler which already holds the lock. That should be fixed
> then.
Yes, that is the minimum that needs to be changed.
There have been a lot of changes made to the driver, by myself included,
that seem to work just fine, but later the timing changes and you lose
the race, resulting in problems. Changing one part of the driver
without understanding the whole thing is very risky.
>
> So I can do:
> // Clear RX interrupts
> spin_lock(&lp->lock);
> lp->a.write_csr (ioaddr, 0, 0x1400);
> spin_unlock(&lp->lock);
> That part seems simple enough to protect.
>
> Is this safe without holding the lock?
> } while(lp->a.read_csr (ioaddr, 0) & 0x1400);
No, see below.
> Not sure how to wrap a lock around that one without holding the lock for
> way too long.
>
> perhaps:
> spin_lock(&lp->lock);
> state=lp->a.read_csr (ioaddr, 0) & 0x1400;
> spin_unlock(&lp->lock);
> } while(state);
> Does that seem more reasonable?
The lock must be held during ANY read or write to a csr or bcr.
The problem is that accessing a csr/bcr takes two steps. One is to
write the address register indicating which register to read or write,
and second, read or write the register. The problem is that without the
lock, entity A writes to the rap to access register X, then before it
can access that register entity B writes the rap to access register Y,
At that point entity A will read, or worse write, the contents of the
wrong register.
This problem is even worse when reading/writing a PHY register because
it entails writing bcr 33 and reading/writing bcr 34, without being
interrupted by something that might change bcr 33. Not likely, but not
something that can be ignored. It may not happen often, but it will
happen eventually.
>
> Len Sorensen
--
Don Fry
brazilnut@us.ibm.com
^ permalink raw reply
* Re: [PATCH v2 2/2] iWARP Core Changes.
From: Tom Tucker @ 2006-06-07 22:13 UTC (permalink / raw)
To: Steve Wise; +Cc: rdreier, mshefty, linux-kernel, netdev, openib-general
In-Reply-To: <20060607200610.9003.54068.stgit@stevo-desktop>
A reference is being taken on an iWARP device that is never getting
released. This prevents a participating iWARP netdev device from being
unloaded after a connection has been established on the passive side.
Search for ip_dev_find below...
On Wed, 2006-06-07 at 15:06 -0500, Steve Wise wrote:
> This patch contains modifications to the existing rdma header files,
> core files, drivers, and ulp files to support iWARP.
>
> Review updates:
>
> - copy_addr() -> rdma_copy_addr()
>
> - dst_dev_addr param in rdma_copy_addr to const.
>
> - various spacing nits with recasting
>
> - include linux/inetdevice.h to get ip_dev_find() prototype.
> ---
>
> drivers/infiniband/core/Makefile | 4
> drivers/infiniband/core/addr.c | 19 +
> drivers/infiniband/core/cache.c | 8 -
> drivers/infiniband/core/cm.c | 3
> drivers/infiniband/core/cma.c | 353 +++++++++++++++++++++++---
> drivers/infiniband/core/device.c | 6
> drivers/infiniband/core/mad.c | 11 +
> drivers/infiniband/core/sa_query.c | 5
> drivers/infiniband/core/smi.c | 18 +
> drivers/infiniband/core/sysfs.c | 18 +
> drivers/infiniband/core/ucm.c | 5
> drivers/infiniband/core/user_mad.c | 9 -
> drivers/infiniband/hw/ipath/ipath_verbs.c | 2
> drivers/infiniband/hw/mthca/mthca_provider.c | 2
> drivers/infiniband/ulp/ipoib/ipoib_main.c | 8 +
> drivers/infiniband/ulp/srp/ib_srp.c | 2
> include/rdma/ib_addr.h | 15 +
> include/rdma/ib_verbs.h | 39 +++
> 18 files changed, 435 insertions(+), 92 deletions(-)
>
> diff --git a/drivers/infiniband/core/Makefile b/drivers/infiniband/core/Makefile
> index 68e73ec..163d991 100644
> --- a/drivers/infiniband/core/Makefile
> +++ b/drivers/infiniband/core/Makefile
> @@ -1,7 +1,7 @@
> infiniband-$(CONFIG_INFINIBAND_ADDR_TRANS) := ib_addr.o rdma_cm.o
>
> obj-$(CONFIG_INFINIBAND) += ib_core.o ib_mad.o ib_sa.o \
> - ib_cm.o $(infiniband-y)
> + ib_cm.o iw_cm.o $(infiniband-y)
> obj-$(CONFIG_INFINIBAND_USER_MAD) += ib_umad.o
> obj-$(CONFIG_INFINIBAND_USER_ACCESS) += ib_uverbs.o ib_ucm.o
>
> @@ -14,6 +14,8 @@ ib_sa-y := sa_query.o
>
> ib_cm-y := cm.o
>
> +iw_cm-y := iwcm.o
> +
> rdma_cm-y := cma.o
>
> ib_addr-y := addr.o
> diff --git a/drivers/infiniband/core/addr.c b/drivers/infiniband/core/addr.c
> index d294bbc..83f84ef 100644
> --- a/drivers/infiniband/core/addr.c
> +++ b/drivers/infiniband/core/addr.c
> @@ -32,6 +32,7 @@ #include <linux/mutex.h>
> #include <linux/inetdevice.h>
> #include <linux/workqueue.h>
> #include <linux/if_arp.h>
> +#include <linux/inetdevice.h>
> #include <net/arp.h>
> #include <net/neighbour.h>
> #include <net/route.h>
> @@ -60,12 +61,15 @@ static LIST_HEAD(req_list);
> static DECLARE_WORK(work, process_req, NULL);
> static struct workqueue_struct *addr_wq;
>
> -static int copy_addr(struct rdma_dev_addr *dev_addr, struct net_device *dev,
> - unsigned char *dst_dev_addr)
> +int rdma_copy_addr(struct rdma_dev_addr *dev_addr, struct net_device *dev,
> + const unsigned char *dst_dev_addr)
> {
> switch (dev->type) {
> case ARPHRD_INFINIBAND:
> - dev_addr->dev_type = IB_NODE_CA;
> + dev_addr->dev_type = RDMA_NODE_IB_CA;
> + break;
> + case ARPHRD_ETHER:
> + dev_addr->dev_type = RDMA_NODE_RNIC;
> break;
> default:
> return -EADDRNOTAVAIL;
> @@ -77,6 +81,7 @@ static int copy_addr(struct rdma_dev_add
> memcpy(dev_addr->dst_dev_addr, dst_dev_addr, MAX_ADDR_LEN);
> return 0;
> }
> +EXPORT_SYMBOL(rdma_copy_addr);
>
> int rdma_translate_ip(struct sockaddr *addr, struct rdma_dev_addr *dev_addr)
> {
> @@ -88,7 +93,7 @@ int rdma_translate_ip(struct sockaddr *a
> if (!dev)
> return -EADDRNOTAVAIL;
>
> - ret = copy_addr(dev_addr, dev, NULL);
> + ret = rdma_copy_addr(dev_addr, dev, NULL);
> dev_put(dev);
> return ret;
> }
> @@ -160,7 +165,7 @@ static int addr_resolve_remote(struct so
>
> /* If the device does ARP internally, return 'done' */
> if (rt->idev->dev->flags & IFF_NOARP) {
> - copy_addr(addr, rt->idev->dev, NULL);
> + rdma_copy_addr(addr, rt->idev->dev, NULL);
> goto put;
> }
>
> @@ -180,7 +185,7 @@ static int addr_resolve_remote(struct so
> src_in->sin_addr.s_addr = rt->rt_src;
> }
>
> - ret = copy_addr(addr, neigh->dev, neigh->ha);
> + ret = rdma_copy_addr(addr, neigh->dev, neigh->ha);
> release:
> neigh_release(neigh);
> put:
> @@ -244,7 +249,7 @@ static int addr_resolve_local(struct soc
> if (ZERONET(src_ip)) {
> src_in->sin_family = dst_in->sin_family;
> src_in->sin_addr.s_addr = dst_ip;
> - ret = copy_addr(addr, dev, dev->dev_addr);
> + ret = rdma_copy_addr(addr, dev, dev->dev_addr);
> } else if (LOOPBACK(src_ip)) {
> ret = rdma_translate_ip((struct sockaddr *)dst_in, addr);
> if (!ret)
> diff --git a/drivers/infiniband/core/cache.c b/drivers/infiniband/core/cache.c
> index e05ca2c..061858c 100644
> --- a/drivers/infiniband/core/cache.c
> +++ b/drivers/infiniband/core/cache.c
> @@ -32,13 +32,12 @@
> * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
> * SOFTWARE.
> *
> - * $Id: cache.c 1349 2004-12-16 21:09:43Z roland $
> + * $Id: cache.c 6885 2006-05-03 18:22:02Z sean.hefty $
> */
>
> #include <linux/module.h>
> #include <linux/errno.h>
> #include <linux/slab.h>
> -#include <linux/sched.h> /* INIT_WORK, schedule_work(), flush_scheduled_work() */
>
> #include <rdma/ib_cache.h>
>
> @@ -62,12 +61,13 @@ struct ib_update_work {
>
> static inline int start_port(struct ib_device *device)
> {
> - return device->node_type == IB_NODE_SWITCH ? 0 : 1;
> + return (device->node_type == RDMA_NODE_IB_SWITCH) ? 0 : 1;
> }
>
> static inline int end_port(struct ib_device *device)
> {
> - return device->node_type == IB_NODE_SWITCH ? 0 : device->phys_port_cnt;
> + return (device->node_type == RDMA_NODE_IB_SWITCH) ?
> + 0 : device->phys_port_cnt;
> }
>
> int ib_get_cached_gid(struct ib_device *device,
> diff --git a/drivers/infiniband/core/cm.c b/drivers/infiniband/core/cm.c
> index 1c7463b..cf43ccb 100644
> --- a/drivers/infiniband/core/cm.c
> +++ b/drivers/infiniband/core/cm.c
> @@ -3253,6 +3253,9 @@ static void cm_add_one(struct ib_device
> int ret;
> u8 i;
>
> + if (rdma_node_get_transport(device->node_type) != RDMA_TRANSPORT_IB)
> + return;
> +
> cm_dev = kmalloc(sizeof(*cm_dev) + sizeof(*port) *
> device->phys_port_cnt, GFP_KERNEL);
> if (!cm_dev)
> diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c
> index 94555d2..414600c 100644
> --- a/drivers/infiniband/core/cma.c
> +++ b/drivers/infiniband/core/cma.c
> @@ -35,6 +35,7 @@ #include <linux/in6.h>
> #include <linux/mutex.h>
> #include <linux/random.h>
> #include <linux/idr.h>
> +#include <linux/inetdevice.h>
>
> #include <net/tcp.h>
>
> @@ -43,6 +44,7 @@ #include <rdma/rdma_cm_ib.h>
> #include <rdma/ib_cache.h>
> #include <rdma/ib_cm.h>
> #include <rdma/ib_sa.h>
> +#include <rdma/iw_cm.h>
>
> MODULE_AUTHOR("Sean Hefty");
> MODULE_DESCRIPTION("Generic RDMA CM Agent");
> @@ -124,6 +126,7 @@ struct rdma_id_private {
> int query_id;
> union {
> struct ib_cm_id *ib;
> + struct iw_cm_id *iw;
> } cm_id;
>
> u32 seq_num;
> @@ -259,13 +262,23 @@ static void cma_detach_from_dev(struct r
> id_priv->cma_dev = NULL;
> }
>
> -static int cma_acquire_ib_dev(struct rdma_id_private *id_priv)
> +static int cma_acquire_dev(struct rdma_id_private *id_priv)
> {
> + enum rdma_node_type dev_type = id_priv->id.route.addr.dev_addr.dev_type;
> struct cma_device *cma_dev;
> union ib_gid *gid;
> int ret = -ENODEV;
>
> - gid = ib_addr_get_sgid(&id_priv->id.route.addr.dev_addr);
> + switch (rdma_node_get_transport(dev_type)) {
> + case RDMA_TRANSPORT_IB:
> + gid = ib_addr_get_sgid(&id_priv->id.route.addr.dev_addr);
> + break;
> + case RDMA_TRANSPORT_IWARP:
> + gid = iw_addr_get_sgid(&id_priv->id.route.addr.dev_addr);
> + break;
> + default:
> + return -ENODEV;
> + }
>
> mutex_lock(&lock);
> list_for_each_entry(cma_dev, &dev_list, list) {
> @@ -280,16 +293,6 @@ static int cma_acquire_ib_dev(struct rdm
> return ret;
> }
>
> -static int cma_acquire_dev(struct rdma_id_private *id_priv)
> -{
> - switch (id_priv->id.route.addr.dev_addr.dev_type) {
> - case IB_NODE_CA:
> - return cma_acquire_ib_dev(id_priv);
> - default:
> - return -ENODEV;
> - }
> -}
> -
> static void cma_deref_id(struct rdma_id_private *id_priv)
> {
> if (atomic_dec_and_test(&id_priv->refcount))
> @@ -347,6 +350,16 @@ static int cma_init_ib_qp(struct rdma_id
> IB_QP_PKEY_INDEX | IB_QP_PORT);
> }
>
> +static int cma_init_iw_qp(struct rdma_id_private *id_priv, struct ib_qp *qp)
> +{
> + struct ib_qp_attr qp_attr;
> +
> + qp_attr.qp_state = IB_QPS_INIT;
> + qp_attr.qp_access_flags = IB_ACCESS_LOCAL_WRITE;
> +
> + return ib_modify_qp(qp, &qp_attr, IB_QP_STATE | IB_QP_ACCESS_FLAGS);
> +}
> +
> int rdma_create_qp(struct rdma_cm_id *id, struct ib_pd *pd,
> struct ib_qp_init_attr *qp_init_attr)
> {
> @@ -362,10 +375,13 @@ int rdma_create_qp(struct rdma_cm_id *id
> if (IS_ERR(qp))
> return PTR_ERR(qp);
>
> - switch (id->device->node_type) {
> - case IB_NODE_CA:
> + switch (rdma_node_get_transport(id->device->node_type)) {
> + case RDMA_TRANSPORT_IB:
> ret = cma_init_ib_qp(id_priv, qp);
> break;
> + case RDMA_TRANSPORT_IWARP:
> + ret = cma_init_iw_qp(id_priv, qp);
> + break;
> default:
> ret = -ENOSYS;
> break;
> @@ -451,13 +467,17 @@ int rdma_init_qp_attr(struct rdma_cm_id
> int ret;
>
> id_priv = container_of(id, struct rdma_id_private, id);
> - switch (id_priv->id.device->node_type) {
> - case IB_NODE_CA:
> + switch (rdma_node_get_transport(id_priv->id.device->node_type)) {
> + case RDMA_TRANSPORT_IB:
> ret = ib_cm_init_qp_attr(id_priv->cm_id.ib, qp_attr,
> qp_attr_mask);
> if (qp_attr->qp_state == IB_QPS_RTR)
> qp_attr->rq_psn = id_priv->seq_num;
> break;
> + case RDMA_TRANSPORT_IWARP:
> + ret = iw_cm_init_qp_attr(id_priv->cm_id.iw, qp_attr,
> + qp_attr_mask);
> + break;
> default:
> ret = -ENOSYS;
> break;
> @@ -590,8 +610,8 @@ static int cma_notify_user(struct rdma_i
>
> static void cma_cancel_route(struct rdma_id_private *id_priv)
> {
> - switch (id_priv->id.device->node_type) {
> - case IB_NODE_CA:
> + switch (rdma_node_get_transport(id_priv->id.device->node_type)) {
> + case RDMA_TRANSPORT_IB:
> if (id_priv->query)
> ib_sa_cancel_query(id_priv->query_id, id_priv->query);
> break;
> @@ -611,11 +631,15 @@ static void cma_destroy_listen(struct rd
> cma_exch(id_priv, CMA_DESTROYING);
>
> if (id_priv->cma_dev) {
> - switch (id_priv->id.device->node_type) {
> - case IB_NODE_CA:
> + switch (rdma_node_get_transport(id_priv->id.device->node_type)) {
> + case RDMA_TRANSPORT_IB:
> if (id_priv->cm_id.ib && !IS_ERR(id_priv->cm_id.ib))
> ib_destroy_cm_id(id_priv->cm_id.ib);
> break;
> + case RDMA_TRANSPORT_IWARP:
> + if (id_priv->cm_id.iw && !IS_ERR(id_priv->cm_id.iw))
> + iw_destroy_cm_id(id_priv->cm_id.iw);
> + break;
> default:
> break;
> }
> @@ -690,11 +714,15 @@ void rdma_destroy_id(struct rdma_cm_id *
> cma_cancel_operation(id_priv, state);
>
> if (id_priv->cma_dev) {
> - switch (id->device->node_type) {
> - case IB_NODE_CA:
> + switch (rdma_node_get_transport(id->device->node_type)) {
> + case RDMA_TRANSPORT_IB:
> if (id_priv->cm_id.ib && !IS_ERR(id_priv->cm_id.ib))
> ib_destroy_cm_id(id_priv->cm_id.ib);
> break;
> + case RDMA_TRANSPORT_IWARP:
> + if (id_priv->cm_id.iw && !IS_ERR(id_priv->cm_id.iw))
> + iw_destroy_cm_id(id_priv->cm_id.iw);
> + break;
> default:
> break;
> }
> @@ -868,7 +896,7 @@ static struct rdma_id_private *cma_new_i
> ib_addr_set_sgid(&rt->addr.dev_addr, &rt->path_rec[0].sgid);
> ib_addr_set_dgid(&rt->addr.dev_addr, &rt->path_rec[0].dgid);
> ib_addr_set_pkey(&rt->addr.dev_addr, be16_to_cpu(rt->path_rec[0].pkey));
> - rt->addr.dev_addr.dev_type = IB_NODE_CA;
> + rt->addr.dev_addr.dev_type = RDMA_NODE_IB_CA;
>
> id_priv = container_of(id, struct rdma_id_private, id);
> id_priv->state = CMA_CONNECT;
> @@ -897,7 +925,7 @@ static int cma_req_handler(struct ib_cm_
> }
>
> atomic_inc(&conn_id->dev_remove);
> - ret = cma_acquire_ib_dev(conn_id);
> + ret = cma_acquire_dev(conn_id);
> if (ret) {
> ret = -ENODEV;
> cma_release_remove(conn_id);
> @@ -981,6 +1009,123 @@ static void cma_set_compare_data(enum rd
> }
> }
>
> +static int cma_iw_handler(struct iw_cm_id *iw_id, struct iw_cm_event *iw_event)
> +{
> + struct rdma_id_private *id_priv = iw_id->context;
> + enum rdma_cm_event_type event = 0;
> + struct sockaddr_in *sin;
> + int ret = 0;
> +
> + atomic_inc(&id_priv->dev_remove);
> +
> + switch (iw_event->event) {
> + case IW_CM_EVENT_CLOSE:
> + event = RDMA_CM_EVENT_DISCONNECTED;
> + break;
> + case IW_CM_EVENT_CONNECT_REPLY:
> + sin = (struct sockaddr_in *) &id_priv->id.route.addr.src_addr;
> + *sin = iw_event->local_addr;
> + sin = (struct sockaddr_in *) &id_priv->id.route.addr.dst_addr;
> + *sin = iw_event->remote_addr;
> + if (iw_event->status)
> + event = RDMA_CM_EVENT_REJECTED;
> + else
> + event = RDMA_CM_EVENT_ESTABLISHED;
> + break;
> + case IW_CM_EVENT_ESTABLISHED:
> + event = RDMA_CM_EVENT_ESTABLISHED;
> + break;
> + default:
> + BUG_ON(1);
> + }
> +
> + ret = cma_notify_user(id_priv, event, iw_event->status,
> + iw_event->private_data,
> + iw_event->private_data_len);
> + if (ret) {
> + /* Destroy the CM ID by returning a non-zero value. */
> + id_priv->cm_id.iw = NULL;
> + cma_exch(id_priv, CMA_DESTROYING);
> + cma_release_remove(id_priv);
> + rdma_destroy_id(&id_priv->id);
> + return ret;
> + }
> +
> + cma_release_remove(id_priv);
> + return ret;
> +}
> +
> +static int iw_conn_req_handler(struct iw_cm_id *cm_id,
> + struct iw_cm_event *iw_event)
> +{
> + struct rdma_cm_id *new_cm_id;
> + struct rdma_id_private *listen_id, *conn_id;
> + struct sockaddr_in *sin;
> + struct net_device *dev;
> + int ret;
> +
> + listen_id = cm_id->context;
> + atomic_inc(&listen_id->dev_remove);
> + if (!cma_comp(listen_id, CMA_LISTEN)) {
> + ret = -ECONNABORTED;
> + goto out;
> + }
> +
> + /* Create a new RDMA id for the new IW CM ID */
> + new_cm_id = rdma_create_id(listen_id->id.event_handler,
> + listen_id->id.context,
> + RDMA_PS_TCP);
> + if (!new_cm_id) {
> + ret = -ENOMEM;
> + goto out;
> + }
> + conn_id = container_of(new_cm_id, struct rdma_id_private, id);
> + atomic_inc(&conn_id->dev_remove);
> + conn_id->state = CMA_CONNECT;
> +
we take a reference on the iWARP device here that we never release
> + dev = ip_dev_find(iw_event->local_addr.sin_addr.s_addr);
> + if (!dev) {
> + ret = -EADDRNOTAVAIL;
> + rdma_destroy_id(new_cm_id);
> + goto out;
> + }
> + ret = rdma_copy_addr(&conn_id->id.route.addr.dev_addr, dev, NULL);
> + if (ret) {
> + rdma_destroy_id(new_cm_id);
> + goto out;
> + }
> +
> + ret = cma_acquire_dev(conn_id);
> + if (ret) {
> + rdma_destroy_id(new_cm_id);
> + goto out;
> + }
> +
> + conn_id->cm_id.iw = cm_id;
> + cm_id->context = conn_id;
> + cm_id->cm_handler = cma_iw_handler;
> +
> + sin = (struct sockaddr_in *) &new_cm_id->route.addr.src_addr;
> + *sin = iw_event->local_addr;
> + sin = (struct sockaddr_in *) &new_cm_id->route.addr.dst_addr;
> + *sin = iw_event->remote_addr;
> +
> + ret = cma_notify_user(conn_id, RDMA_CM_EVENT_CONNECT_REQUEST, 0,
> + iw_event->private_data,
> + iw_event->private_data_len);
> + if (ret) {
> + /* User wants to destroy the CM ID */
> + conn_id->cm_id.iw = NULL;
> + cma_exch(conn_id, CMA_DESTROYING);
> + cma_release_remove(conn_id);
> + rdma_destroy_id(&conn_id->id);
> + }
> +
> +out:
We need to put a dev_put here or the reference on the device will never
get released and you won't be able to remove it after you've had at
least one connection. This is my bug....
dev_put(dev);
> + cma_release_remove(listen_id);
> + return ret;
> +}
> +
> static int cma_ib_listen(struct rdma_id_private *id_priv)
> {
> struct ib_cm_compare_data compare_data;
> @@ -1010,6 +1155,30 @@ static int cma_ib_listen(struct rdma_id_
> return ret;
> }
>
> +static int cma_iw_listen(struct rdma_id_private *id_priv, int backlog)
> +{
> + int ret;
> + struct sockaddr_in *sin;
> +
> + id_priv->cm_id.iw = iw_create_cm_id(id_priv->id.device,
> + iw_conn_req_handler,
> + id_priv);
> + if (IS_ERR(id_priv->cm_id.iw))
> + return PTR_ERR(id_priv->cm_id.iw);
> +
> + sin = (struct sockaddr_in *) &id_priv->id.route.addr.src_addr;
> + id_priv->cm_id.iw->local_addr = *sin;
> +
> + ret = iw_cm_listen(id_priv->cm_id.iw, backlog);
> +
> + if (ret) {
> + iw_destroy_cm_id(id_priv->cm_id.iw);
> + id_priv->cm_id.iw = NULL;
> + }
> +
> + return ret;
> +}
> +
> static int cma_listen_handler(struct rdma_cm_id *id,
> struct rdma_cm_event *event)
> {
> @@ -1085,12 +1254,17 @@ int rdma_listen(struct rdma_cm_id *id, i
> return -EINVAL;
>
> if (id->device) {
> - switch (id->device->node_type) {
> - case IB_NODE_CA:
> + switch (rdma_node_get_transport(id->device->node_type)) {
> + case RDMA_TRANSPORT_IB:
> ret = cma_ib_listen(id_priv);
> if (ret)
> goto err;
> break;
> + case RDMA_TRANSPORT_IWARP:
> + ret = cma_iw_listen(id_priv, backlog);
> + if (ret)
> + goto err;
> + break;
> default:
> ret = -ENOSYS;
> goto err;
> @@ -1229,6 +1403,23 @@ err:
> }
> EXPORT_SYMBOL(rdma_set_ib_paths);
>
> +static int cma_resolve_iw_route(struct rdma_id_private *id_priv, int timeout_ms)
> +{
> + struct cma_work *work;
> +
> + work = kzalloc(sizeof *work, GFP_KERNEL);
> + if (!work)
> + return -ENOMEM;
> +
> + work->id = id_priv;
> + INIT_WORK(&work->work, cma_work_handler, work);
> + work->old_state = CMA_ROUTE_QUERY;
> + work->new_state = CMA_ROUTE_RESOLVED;
> + work->event.event = RDMA_CM_EVENT_ROUTE_RESOLVED;
> + queue_work(cma_wq, &work->work);
> + return 0;
> +}
> +
> int rdma_resolve_route(struct rdma_cm_id *id, int timeout_ms)
> {
> struct rdma_id_private *id_priv;
> @@ -1239,10 +1430,13 @@ int rdma_resolve_route(struct rdma_cm_id
> return -EINVAL;
>
> atomic_inc(&id_priv->refcount);
> - switch (id->device->node_type) {
> - case IB_NODE_CA:
> + switch (rdma_node_get_transport(id->device->node_type)) {
> + case RDMA_TRANSPORT_IB:
> ret = cma_resolve_ib_route(id_priv, timeout_ms);
> break;
> + case RDMA_TRANSPORT_IWARP:
> + ret = cma_resolve_iw_route(id_priv, timeout_ms);
> + break;
> default:
> ret = -ENOSYS;
> break;
> @@ -1354,8 +1548,8 @@ static int cma_resolve_loopback(struct r
> ib_addr_get_sgid(&id_priv->id.route.addr.dev_addr));
>
> if (cma_zero_addr(&id_priv->id.route.addr.src_addr)) {
> - src_in = (struct sockaddr_in *)&id_priv->id.route.addr.src_addr;
> - dst_in = (struct sockaddr_in *)&id_priv->id.route.addr.dst_addr;
> + src_in = (struct sockaddr_in *) &id_priv->id.route.addr.src_addr;
> + dst_in = (struct sockaddr_in *) &id_priv->id.route.addr.dst_addr;
> src_in->sin_family = dst_in->sin_family;
> src_in->sin_addr.s_addr = dst_in->sin_addr.s_addr;
> }
> @@ -1646,6 +1840,47 @@ out:
> return ret;
> }
>
> +static int cma_connect_iw(struct rdma_id_private *id_priv,
> + struct rdma_conn_param *conn_param)
> +{
> + struct iw_cm_id *cm_id;
> + struct sockaddr_in* sin;
> + int ret;
> + struct iw_cm_conn_param iw_param;
> +
> + cm_id = iw_create_cm_id(id_priv->id.device, cma_iw_handler, id_priv);
> + if (IS_ERR(cm_id)) {
> + ret = PTR_ERR(cm_id);
> + goto out;
> + }
> +
> + id_priv->cm_id.iw = cm_id;
> +
> + sin = (struct sockaddr_in*) &id_priv->id.route.addr.src_addr;
> + cm_id->local_addr = *sin;
> +
> + sin = (struct sockaddr_in*) &id_priv->id.route.addr.dst_addr;
> + cm_id->remote_addr = *sin;
> +
> + ret = cma_modify_qp_rtr(&id_priv->id);
> + if (ret) {
> + iw_destroy_cm_id(cm_id);
> + return ret;
> + }
> +
> + iw_param.ord = conn_param->initiator_depth;
> + iw_param.ird = conn_param->responder_resources;
> + iw_param.private_data = conn_param->private_data;
> + iw_param.private_data_len = conn_param->private_data_len;
> + if (id_priv->id.qp)
> + iw_param.qpn = id_priv->qp_num;
> + else
> + iw_param.qpn = conn_param->qp_num;
> + ret = iw_cm_connect(cm_id, &iw_param);
> +out:
> + return ret;
> +}
> +
> int rdma_connect(struct rdma_cm_id *id, struct rdma_conn_param *conn_param)
> {
> struct rdma_id_private *id_priv;
> @@ -1661,10 +1896,13 @@ int rdma_connect(struct rdma_cm_id *id,
> id_priv->srq = conn_param->srq;
> }
>
> - switch (id->device->node_type) {
> - case IB_NODE_CA:
> + switch (rdma_node_get_transport(id->device->node_type)) {
> + case RDMA_TRANSPORT_IB:
> ret = cma_connect_ib(id_priv, conn_param);
> break;
> + case RDMA_TRANSPORT_IWARP:
> + ret = cma_connect_iw(id_priv, conn_param);
> + break;
> default:
> ret = -ENOSYS;
> break;
> @@ -1705,6 +1943,28 @@ static int cma_accept_ib(struct rdma_id_
> return ib_send_cm_rep(id_priv->cm_id.ib, &rep);
> }
>
> +static int cma_accept_iw(struct rdma_id_private *id_priv,
> + struct rdma_conn_param *conn_param)
> +{
> + struct iw_cm_conn_param iw_param;
> + int ret;
> +
> + ret = cma_modify_qp_rtr(&id_priv->id);
> + if (ret)
> + return ret;
> +
> + iw_param.ord = conn_param->initiator_depth;
> + iw_param.ird = conn_param->responder_resources;
> + iw_param.private_data = conn_param->private_data;
> + iw_param.private_data_len = conn_param->private_data_len;
> + if (id_priv->id.qp) {
> + iw_param.qpn = id_priv->qp_num;
> + } else
> + iw_param.qpn = conn_param->qp_num;
> +
> + return iw_cm_accept(id_priv->cm_id.iw, &iw_param);
> +}
> +
> int rdma_accept(struct rdma_cm_id *id, struct rdma_conn_param *conn_param)
> {
> struct rdma_id_private *id_priv;
> @@ -1720,13 +1980,16 @@ int rdma_accept(struct rdma_cm_id *id, s
> id_priv->srq = conn_param->srq;
> }
>
> - switch (id->device->node_type) {
> - case IB_NODE_CA:
> + switch (rdma_node_get_transport(id->device->node_type)) {
> + case RDMA_TRANSPORT_IB:
> if (conn_param)
> ret = cma_accept_ib(id_priv, conn_param);
> else
> ret = cma_rep_recv(id_priv);
> break;
> + case RDMA_TRANSPORT_IWARP:
> + ret = cma_accept_iw(id_priv, conn_param);
> + break;
> default:
> ret = -ENOSYS;
> break;
> @@ -1753,12 +2016,16 @@ int rdma_reject(struct rdma_cm_id *id, c
> if (!cma_comp(id_priv, CMA_CONNECT))
> return -EINVAL;
>
> - switch (id->device->node_type) {
> - case IB_NODE_CA:
> + switch (rdma_node_get_transport(id->device->node_type)) {
> + case RDMA_TRANSPORT_IB:
> ret = ib_send_cm_rej(id_priv->cm_id.ib,
> IB_CM_REJ_CONSUMER_DEFINED, NULL, 0,
> private_data, private_data_len);
> break;
> + case RDMA_TRANSPORT_IWARP:
> + ret = iw_cm_reject(id_priv->cm_id.iw,
> + private_data, private_data_len);
> + break;
> default:
> ret = -ENOSYS;
> break;
> @@ -1777,16 +2044,18 @@ int rdma_disconnect(struct rdma_cm_id *i
> !cma_comp(id_priv, CMA_DISCONNECT))
> return -EINVAL;
>
> - ret = cma_modify_qp_err(id);
> - if (ret)
> - goto out;
> -
> - switch (id->device->node_type) {
> - case IB_NODE_CA:
> + switch (rdma_node_get_transport(id->device->node_type)) {
> + case RDMA_TRANSPORT_IB:
> + ret = cma_modify_qp_err(id);
> + if (ret)
> + goto out;
> /* Initiate or respond to a disconnect. */
> if (ib_send_cm_dreq(id_priv->cm_id.ib, NULL, 0))
> ib_send_cm_drep(id_priv->cm_id.ib, NULL, 0);
> break;
> + case RDMA_TRANSPORT_IWARP:
> + ret = iw_cm_disconnect(id_priv->cm_id.iw, 0);
> + break;
> default:
> break;
> }
> diff --git a/drivers/infiniband/core/device.c b/drivers/infiniband/core/device.c
> index b2f3cb9..7318fba 100644
> --- a/drivers/infiniband/core/device.c
> +++ b/drivers/infiniband/core/device.c
> @@ -30,7 +30,7 @@
> * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
> * SOFTWARE.
> *
> - * $Id: device.c 1349 2004-12-16 21:09:43Z roland $
> + * $Id: device.c 5943 2006-03-22 00:58:04Z roland $
> */
>
> #include <linux/module.h>
> @@ -505,7 +505,7 @@ int ib_query_port(struct ib_device *devi
> u8 port_num,
> struct ib_port_attr *port_attr)
> {
> - if (device->node_type == IB_NODE_SWITCH) {
> + if (device->node_type == RDMA_NODE_IB_SWITCH) {
> if (port_num)
> return -EINVAL;
> } else if (port_num < 1 || port_num > device->phys_port_cnt)
> @@ -580,7 +580,7 @@ int ib_modify_port(struct ib_device *dev
> u8 port_num, int port_modify_mask,
> struct ib_port_modify *port_modify)
> {
> - if (device->node_type == IB_NODE_SWITCH) {
> + if (device->node_type == RDMA_NODE_IB_SWITCH) {
> if (port_num)
> return -EINVAL;
> } else if (port_num < 1 || port_num > device->phys_port_cnt)
> diff --git a/drivers/infiniband/core/mad.c b/drivers/infiniband/core/mad.c
> index b38e02a..a928ecf 100644
> --- a/drivers/infiniband/core/mad.c
> +++ b/drivers/infiniband/core/mad.c
> @@ -1,5 +1,5 @@
> /*
> - * Copyright (c) 2004, 2005 Voltaire, Inc. All rights reserved.
> + * Copyright (c) 2004-2006 Voltaire, Inc. All rights reserved.
> * Copyright (c) 2005 Intel Corporation. All rights reserved.
> * Copyright (c) 2005 Mellanox Technologies Ltd. All rights reserved.
> *
> @@ -31,7 +31,7 @@
> * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
> * SOFTWARE.
> *
> - * $Id: mad.c 5596 2006-03-03 01:00:07Z sean.hefty $
> + * $Id: mad.c 7294 2006-05-17 18:12:30Z roland $
> */
> #include <linux/dma-mapping.h>
> #include <rdma/ib_cache.h>
> @@ -2877,7 +2877,10 @@ static void ib_mad_init_device(struct ib
> {
> int start, end, i;
>
> - if (device->node_type == IB_NODE_SWITCH) {
> + if (rdma_node_get_transport(device->node_type) != RDMA_TRANSPORT_IB)
> + return;
> +
> + if (device->node_type == RDMA_NODE_IB_SWITCH) {
> start = 0;
> end = 0;
> } else {
> @@ -2924,7 +2927,7 @@ static void ib_mad_remove_device(struct
> {
> int i, num_ports, cur_port;
>
> - if (device->node_type == IB_NODE_SWITCH) {
> + if (device->node_type == RDMA_NODE_IB_SWITCH) {
> num_ports = 1;
> cur_port = 0;
> } else {
> diff --git a/drivers/infiniband/core/sa_query.c b/drivers/infiniband/core/sa_query.c
> index 501cc05..4230277 100644
> --- a/drivers/infiniband/core/sa_query.c
> +++ b/drivers/infiniband/core/sa_query.c
> @@ -887,7 +887,10 @@ static void ib_sa_add_one(struct ib_devi
> struct ib_sa_device *sa_dev;
> int s, e, i;
>
> - if (device->node_type == IB_NODE_SWITCH)
> + if (rdma_node_get_transport(device->node_type) != RDMA_TRANSPORT_IB)
> + return;
> +
> + if (device->node_type == RDMA_NODE_IB_SWITCH)
> s = e = 0;
> else {
> s = 1;
> diff --git a/drivers/infiniband/core/smi.c b/drivers/infiniband/core/smi.c
> index 35852e7..b81b2b9 100644
> --- a/drivers/infiniband/core/smi.c
> +++ b/drivers/infiniband/core/smi.c
> @@ -34,7 +34,7 @@
> * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
> * SOFTWARE.
> *
> - * $Id: smi.c 1389 2004-12-27 22:56:47Z roland $
> + * $Id: smi.c 5258 2006-02-01 20:32:40Z sean.hefty $
> */
>
> #include <rdma/ib_smi.h>
> @@ -64,7 +64,7 @@ int smi_handle_dr_smp_send(struct ib_smp
>
> /* C14-9:2 */
> if (hop_ptr && hop_ptr < hop_cnt) {
> - if (node_type != IB_NODE_SWITCH)
> + if (node_type != RDMA_NODE_IB_SWITCH)
> return 0;
>
> /* smp->return_path set when received */
> @@ -77,7 +77,7 @@ int smi_handle_dr_smp_send(struct ib_smp
> if (hop_ptr == hop_cnt) {
> /* smp->return_path set when received */
> smp->hop_ptr++;
> - return (node_type == IB_NODE_SWITCH ||
> + return (node_type == RDMA_NODE_IB_SWITCH ||
> smp->dr_dlid == IB_LID_PERMISSIVE);
> }
>
> @@ -95,7 +95,7 @@ int smi_handle_dr_smp_send(struct ib_smp
>
> /* C14-13:2 */
> if (2 <= hop_ptr && hop_ptr <= hop_cnt) {
> - if (node_type != IB_NODE_SWITCH)
> + if (node_type != RDMA_NODE_IB_SWITCH)
> return 0;
>
> smp->hop_ptr--;
> @@ -107,7 +107,7 @@ int smi_handle_dr_smp_send(struct ib_smp
> if (hop_ptr == 1) {
> smp->hop_ptr--;
> /* C14-13:3 -- SMPs destined for SM shouldn't be here */
> - return (node_type == IB_NODE_SWITCH ||
> + return (node_type == RDMA_NODE_IB_SWITCH ||
> smp->dr_slid == IB_LID_PERMISSIVE);
> }
>
> @@ -142,7 +142,7 @@ int smi_handle_dr_smp_recv(struct ib_smp
>
> /* C14-9:2 -- intermediate hop */
> if (hop_ptr && hop_ptr < hop_cnt) {
> - if (node_type != IB_NODE_SWITCH)
> + if (node_type != RDMA_NODE_IB_SWITCH)
> return 0;
>
> smp->return_path[hop_ptr] = port_num;
> @@ -156,7 +156,7 @@ int smi_handle_dr_smp_recv(struct ib_smp
> smp->return_path[hop_ptr] = port_num;
> /* smp->hop_ptr updated when sending */
>
> - return (node_type == IB_NODE_SWITCH ||
> + return (node_type == RDMA_NODE_IB_SWITCH ||
> smp->dr_dlid == IB_LID_PERMISSIVE);
> }
>
> @@ -175,7 +175,7 @@ int smi_handle_dr_smp_recv(struct ib_smp
>
> /* C14-13:2 */
> if (2 <= hop_ptr && hop_ptr <= hop_cnt) {
> - if (node_type != IB_NODE_SWITCH)
> + if (node_type != RDMA_NODE_IB_SWITCH)
> return 0;
>
> /* smp->hop_ptr updated when sending */
> @@ -190,7 +190,7 @@ int smi_handle_dr_smp_recv(struct ib_smp
> return 1;
> }
> /* smp->hop_ptr updated when sending */
> - return (node_type == IB_NODE_SWITCH);
> + return (node_type == RDMA_NODE_IB_SWITCH);
> }
>
> /* C14-13:4 -- hop_ptr = 0 -> give to SM */
> diff --git a/drivers/infiniband/core/sysfs.c b/drivers/infiniband/core/sysfs.c
> index 21f9282..cfd2c06 100644
> --- a/drivers/infiniband/core/sysfs.c
> +++ b/drivers/infiniband/core/sysfs.c
> @@ -31,7 +31,7 @@
> * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
> * SOFTWARE.
> *
> - * $Id: sysfs.c 1349 2004-12-16 21:09:43Z roland $
> + * $Id: sysfs.c 6940 2006-05-04 17:04:55Z roland $
> */
>
> #include "core_priv.h"
> @@ -589,10 +589,16 @@ static ssize_t show_node_type(struct cla
> return -ENODEV;
>
> switch (dev->node_type) {
> - case IB_NODE_CA: return sprintf(buf, "%d: CA\n", dev->node_type);
> - case IB_NODE_SWITCH: return sprintf(buf, "%d: switch\n", dev->node_type);
> - case IB_NODE_ROUTER: return sprintf(buf, "%d: router\n", dev->node_type);
> - default: return sprintf(buf, "%d: <unknown>\n", dev->node_type);
> + case RDMA_NODE_IB_CA:
> + return sprintf(buf, "%d: CA\n", dev->node_type);
> + case RDMA_NODE_RNIC:
> + return sprintf(buf, "%d: RNIC\n", dev->node_type);
> + case RDMA_NODE_IB_SWITCH:
> + return sprintf(buf, "%d: switch\n", dev->node_type);
> + case RDMA_NODE_IB_ROUTER:
> + return sprintf(buf, "%d: router\n", dev->node_type);
> + default:
> + return sprintf(buf, "%d: <unknown>\n", dev->node_type);
> }
> }
>
> @@ -708,7 +714,7 @@ int ib_device_register_sysfs(struct ib_d
> if (ret)
> goto err_put;
>
> - if (device->node_type == IB_NODE_SWITCH) {
> + if (device->node_type == RDMA_NODE_IB_SWITCH) {
> ret = add_port(device, 0);
> if (ret)
> goto err_put;
> diff --git a/drivers/infiniband/core/ucm.c b/drivers/infiniband/core/ucm.c
> index 67caf36..ad2e417 100644
> --- a/drivers/infiniband/core/ucm.c
> +++ b/drivers/infiniband/core/ucm.c
> @@ -30,7 +30,7 @@
> * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
> * SOFTWARE.
> *
> - * $Id: ucm.c 4311 2005-12-05 18:42:01Z sean.hefty $
> + * $Id: ucm.c 7119 2006-05-11 16:40:38Z sean.hefty $
> */
>
> #include <linux/completion.h>
> @@ -1248,7 +1248,8 @@ static void ib_ucm_add_one(struct ib_dev
> {
> struct ib_ucm_device *ucm_dev;
>
> - if (!device->alloc_ucontext)
> + if (!device->alloc_ucontext ||
> + rdma_node_get_transport(device->node_type) != RDMA_TRANSPORT_IB)
> return;
>
> ucm_dev = kzalloc(sizeof *ucm_dev, GFP_KERNEL);
> diff --git a/drivers/infiniband/core/user_mad.c b/drivers/infiniband/core/user_mad.c
> index afe70a5..0cbd692 100644
> --- a/drivers/infiniband/core/user_mad.c
> +++ b/drivers/infiniband/core/user_mad.c
> @@ -1,6 +1,6 @@
> /*
> * Copyright (c) 2004 Topspin Communications. All rights reserved.
> - * Copyright (c) 2005 Voltaire, Inc. All rights reserved.
> + * Copyright (c) 2005-2006 Voltaire, Inc. All rights reserved.
> * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved.
> *
> * This software is available to you under a choice of one of two
> @@ -31,7 +31,7 @@
> * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
> * SOFTWARE.
> *
> - * $Id: user_mad.c 5596 2006-03-03 01:00:07Z sean.hefty $
> + * $Id: user_mad.c 6041 2006-03-27 21:06:00Z halr $
> */
>
> #include <linux/module.h>
> @@ -967,7 +967,10 @@ static void ib_umad_add_one(struct ib_de
> struct ib_umad_device *umad_dev;
> int s, e, i;
>
> - if (device->node_type == IB_NODE_SWITCH)
> + if (rdma_node_get_transport(device->node_type) != RDMA_TRANSPORT_IB)
> + return;
> +
> + if (device->node_type == RDMA_NODE_IB_SWITCH)
> s = e = 0;
> else {
> s = 1;
> diff --git a/drivers/infiniband/hw/ipath/ipath_verbs.c b/drivers/infiniband/hw/ipath/ipath_verbs.c
> index 28fdbda..e4b45d7 100644
> --- a/drivers/infiniband/hw/ipath/ipath_verbs.c
> +++ b/drivers/infiniband/hw/ipath/ipath_verbs.c
> @@ -984,7 +984,7 @@ static void *ipath_register_ib_device(in
> (1ull << IB_USER_VERBS_CMD_QUERY_SRQ) |
> (1ull << IB_USER_VERBS_CMD_DESTROY_SRQ) |
> (1ull << IB_USER_VERBS_CMD_POST_SRQ_RECV);
> - dev->node_type = IB_NODE_CA;
> + dev->node_type = RDMA_NODE_IB_CA;
> dev->phys_port_cnt = 1;
> dev->dma_device = ipath_layer_get_device(dd);
> dev->class_dev.dev = dev->dma_device;
> diff --git a/drivers/infiniband/hw/mthca/mthca_provider.c b/drivers/infiniband/hw/mthca/mthca_provider.c
> index a2eae8a..5c31819 100644
> --- a/drivers/infiniband/hw/mthca/mthca_provider.c
> +++ b/drivers/infiniband/hw/mthca/mthca_provider.c
> @@ -1273,7 +1273,7 @@ int mthca_register_device(struct mthca_d
> (1ull << IB_USER_VERBS_CMD_MODIFY_SRQ) |
> (1ull << IB_USER_VERBS_CMD_QUERY_SRQ) |
> (1ull << IB_USER_VERBS_CMD_DESTROY_SRQ);
> - dev->ib_dev.node_type = IB_NODE_CA;
> + dev->ib_dev.node_type = RDMA_NODE_IB_CA;
> dev->ib_dev.phys_port_cnt = dev->limits.num_ports;
> dev->ib_dev.dma_device = &dev->pdev->dev;
> dev->ib_dev.class_dev.dev = &dev->pdev->dev;
> diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c
> index 1c6ea1c..262427f 100644
> --- a/drivers/infiniband/ulp/ipoib/ipoib_main.c
> +++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c
> @@ -1084,13 +1084,16 @@ static void ipoib_add_one(struct ib_devi
> struct ipoib_dev_priv *priv;
> int s, e, p;
>
> + if (rdma_node_get_transport(device->node_type) != RDMA_TRANSPORT_IB)
> + return;
> +
> dev_list = kmalloc(sizeof *dev_list, GFP_KERNEL);
> if (!dev_list)
> return;
>
> INIT_LIST_HEAD(dev_list);
>
> - if (device->node_type == IB_NODE_SWITCH) {
> + if (device->node_type == RDMA_NODE_IB_SWITCH) {
> s = 0;
> e = 0;
> } else {
> @@ -1114,6 +1117,9 @@ static void ipoib_remove_one(struct ib_d
> struct ipoib_dev_priv *priv, *tmp;
> struct list_head *dev_list;
>
> + if (rdma_node_get_transport(device->node_type) != RDMA_TRANSPORT_IB)
> + return;
> +
> dev_list = ib_get_client_data(device, &ipoib_client);
>
> list_for_each_entry_safe(priv, tmp, dev_list, list) {
> diff --git a/drivers/infiniband/ulp/srp/ib_srp.c b/drivers/infiniband/ulp/srp/ib_srp.c
> index f1401e1..bba2956 100644
> --- a/drivers/infiniband/ulp/srp/ib_srp.c
> +++ b/drivers/infiniband/ulp/srp/ib_srp.c
> @@ -1845,7 +1845,7 @@ static void srp_add_one(struct ib_device
> if (IS_ERR(srp_dev->fmr_pool))
> srp_dev->fmr_pool = NULL;
>
> - if (device->node_type == IB_NODE_SWITCH) {
> + if (device->node_type == RDMA_NODE_IB_SWITCH) {
> s = 0;
> e = 0;
> } else {
> diff --git a/include/rdma/ib_addr.h b/include/rdma/ib_addr.h
> index fcb5ba8..d95d3eb 100644
> --- a/include/rdma/ib_addr.h
> +++ b/include/rdma/ib_addr.h
> @@ -40,7 +40,7 @@ struct rdma_dev_addr {
> unsigned char src_dev_addr[MAX_ADDR_LEN];
> unsigned char dst_dev_addr[MAX_ADDR_LEN];
> unsigned char broadcast[MAX_ADDR_LEN];
> - enum ib_node_type dev_type;
> + enum rdma_node_type dev_type;
> };
>
> /**
> @@ -72,6 +72,9 @@ int rdma_resolve_ip(struct sockaddr *src
>
> void rdma_addr_cancel(struct rdma_dev_addr *addr);
>
> +int rdma_copy_addr(struct rdma_dev_addr *dev_addr, struct net_device *dev,
> + const unsigned char *dst_dev_addr);
> +
> static inline int ip_addr_size(struct sockaddr *addr)
> {
> return addr->sa_family == AF_INET6 ?
> @@ -111,4 +114,14 @@ static inline void ib_addr_set_dgid(stru
> memcpy(dev_addr->dst_dev_addr + 4, gid, sizeof *gid);
> }
>
> +static inline union ib_gid* iw_addr_get_sgid(struct rdma_dev_addr* rda)
> +{
> + return (union ib_gid *) rda->src_dev_addr;
> +}
> +
> +static inline union ib_gid* iw_addr_get_dgid(struct rdma_dev_addr* rda)
> +{
> + return (union ib_gid *) rda->dst_dev_addr;
> +}
> +
> #endif /* IB_ADDR_H */
> diff --git a/include/rdma/ib_verbs.h b/include/rdma/ib_verbs.h
> index aeb4fcd..eac2d8f 100644
> --- a/include/rdma/ib_verbs.h
> +++ b/include/rdma/ib_verbs.h
> @@ -35,7 +35,7 @@
> * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
> * SOFTWARE.
> *
> - * $Id: ib_verbs.h 1349 2004-12-16 21:09:43Z roland $
> + * $Id: ib_verbs.h 6885 2006-05-03 18:22:02Z sean.hefty $
> */
>
> #if !defined(IB_VERBS_H)
> @@ -56,12 +56,35 @@ union ib_gid {
> } global;
> };
>
> -enum ib_node_type {
> - IB_NODE_CA = 1,
> - IB_NODE_SWITCH,
> - IB_NODE_ROUTER
> +enum rdma_node_type {
> + /* IB values map to NodeInfo:NodeType. */
> + RDMA_NODE_IB_CA = 1,
> + RDMA_NODE_IB_SWITCH,
> + RDMA_NODE_IB_ROUTER,
> + RDMA_NODE_RNIC
> };
>
> +enum rdma_transport_type {
> + RDMA_TRANSPORT_IB,
> + RDMA_TRANSPORT_IWARP
> +};
> +
> +static inline enum rdma_transport_type
> +rdma_node_get_transport(enum rdma_node_type node_type)
> +{
> + switch (node_type) {
> + case RDMA_NODE_IB_CA:
> + case RDMA_NODE_IB_SWITCH:
> + case RDMA_NODE_IB_ROUTER:
> + return RDMA_TRANSPORT_IB;
> + case RDMA_NODE_RNIC:
> + return RDMA_TRANSPORT_IWARP;
> + default:
> + BUG();
> + return 0;
> + }
> +}
> +
> enum ib_device_cap_flags {
> IB_DEVICE_RESIZE_MAX_WR = 1,
> IB_DEVICE_BAD_PKEY_CNTR = (1<<1),
> @@ -78,6 +101,9 @@ enum ib_device_cap_flags {
> IB_DEVICE_RC_RNR_NAK_GEN = (1<<12),
> IB_DEVICE_SRQ_RESIZE = (1<<13),
> IB_DEVICE_N_NOTIFY_CQ = (1<<14),
> + IB_DEVICE_ZERO_STAG = (1<<15),
> + IB_DEVICE_SEND_W_INV = (1<<16),
> + IB_DEVICE_MEM_WINDOW = (1<<17)
> };
>
> enum ib_atomic_cap {
> @@ -830,6 +856,7 @@ struct ib_cache {
> u8 *lmc_cache;
> };
>
> +struct iw_cm_verbs;
> struct ib_device {
> struct device *dma_device;
>
> @@ -846,6 +873,8 @@ struct ib_device {
>
> u32 flags;
>
> + struct iw_cm_verbs *iwcm;
> +
> int (*query_device)(struct ib_device *device,
> struct ib_device_attr *device_attr);
> int (*query_port)(struct ib_device *device,
> -
> To unsubscribe from this list: send the line "unsubscribe netdev" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: Updated sysctl documentation take #2
From: Diego Calleja @ 2006-06-07 22:18 UTC (permalink / raw)
To: Randy.Dunlap; +Cc: linux-kernel, akpm, netdev, linux-xfs, ecki, lkml
In-Reply-To: <20060607130653.9a4d572c.rdunlap@xenotime.net>
El Wed, 7 Jun 2006 13:06:53 -0700,
"Randy.Dunlap" <rdunlap@xenotime.net> escribió:
> I don't know how long it takes to review such a large patch, but
> I'll continue to do so. For now:
Yeah, my english is poor ;)
Most of the sysctl documentation cames from other files anyway,
README was (re)written by me, so the rest is not so bad...
> OK, that's all for the README file. I'll look at the rest of it
> sometime this week. I don't think that it's quite ready to be merged.
Thank's for your review, altought I didn't though someone was to review
so deeply a documentation patch ;) I've gone through all the files and
fixed the 72-col limit and everything I could. I've updated the patch
http://terra.es/personal/diegocg/sysctl-docs
^ permalink raw reply
* Re: [PATCH] pcnet32 driver NAPI support
From: Don Fry @ 2006-06-07 22:32 UTC (permalink / raw)
To: Lennart Sorensen; +Cc: netdev
In-Reply-To: <20060607215236.GA13380@us.ibm.com>
One other problem I ran into. I applied the patch but it will not
compile because rl_active is never defined. I have worked around it but
...
--
Don Fry
brazilnut@us.ibm.com
^ permalink raw reply
* [PATCH 9/10] Add Vitesse 8244 PHY for MPC8641 HPCN platform.
From: Jon Loeliger @ 2006-06-07 22:45 UTC (permalink / raw)
To: linuxppc-dev@ozlabs.org, netdev, jeff
Signed-off-by: Kriston Carson <KristonCarson@freescale.com>
Signed-off-by: Xianghua Xiao <x.xiao@freescale.com>
Signed-off-by: Jon Loeliger <jdl@freescale.com>
---
drivers/net/Kconfig | 6 +-
drivers/net/phy/Kconfig | 5 ++
drivers/net/phy/Makefile | 1
drivers/net/phy/vitesse.c | 136 +++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 145 insertions(+), 3 deletions(-)
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index bdaaad8..c1c2758 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -2179,11 +2179,11 @@ config SPIDER_NET
config GIANFAR
tristate "Gianfar Ethernet"
- depends on 85xx || 83xx
+ depends on 85xx || 83xx || PPC_86xx
select PHYLIB
help
- This driver supports the Gigabit TSEC on the MPC85xx
- family of chips, and the FEC on the 8540
+ This driver supports the Gigabit TSEC on the MPC83xx, MPC85xx,
+ and MPC86xx family of chips, and the FEC on the 8540.
config GFAR_NAPI
bool "NAPI Support"
diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig
index fa39b94..76e51b1 100644
--- a/drivers/net/phy/Kconfig
+++ b/drivers/net/phy/Kconfig
@@ -44,6 +44,11 @@ config CICADA_PHY
depends on PHYLIB
---help---
Currently supports the cis8204
+config VITESSE_PHY
+ tristate "Drivers for the Vitesse PHYs"
+ depends on PHYLIB
+ ---help---
+ Currently supports the vsc8244
endmenu
diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile
index e4116a5..a8d066e 100644
--- a/drivers/net/phy/Makefile
+++ b/drivers/net/phy/Makefile
@@ -8,3 +8,4 @@ obj-$(CONFIG_DAVICOM_PHY) += davicom.o
obj-$(CONFIG_CICADA_PHY) += cicada.o
obj-$(CONFIG_LXT_PHY) += lxt.o
obj-$(CONFIG_QSEMI_PHY) += qsemi.o
+obj-$(CONFIG_VITESSE_PHY) += vitesse.o
diff --git a/drivers/net/phy/vitesse.c b/drivers/net/phy/vitesse.c
new file mode 100644
index 0000000..45a605f
--- /dev/null
+++ b/drivers/net/phy/vitesse.c
@@ -0,0 +1,136 @@
+/*
+ * Driver for Vitesse PHYs
+ *
+ * Author: Kriston Carson
+ *
+ * Copyright (c) 2005 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/string.h>
+#include <linux/errno.h>
+#include <linux/unistd.h>
+#include <linux/slab.h>
+#include <linux/interrupt.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+#include <linux/spinlock.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/version.h>
+#include <linux/mii.h>
+#include <linux/ethtool.h>
+#include <linux/phy.h>
+
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/uaccess.h>
+
+/* Vitesse Extended Control Register 1 */
+#define MII_VSC8244_EXT_CON1 0x17
+#define MII_VSC8244_EXTCON1_INIT 0x0000
+
+/* Vitesse Interrupt Mask Register */
+#define MII_VSC8244_IMASK 0x19
+#define MII_VSC8244_IMASK_IEN 0x8000
+#define MII_VSC8244_IMASK_SPEED 0x4000
+#define MII_VSC8244_IMASK_LINK 0x2000
+#define MII_VSC8244_IMASK_DUPLEX 0x1000
+#define MII_VSC8244_IMASK_MASK 0xf000
+
+/* Vitesse Interrupt Status Register */
+#define MII_VSC8244_ISTAT 0x1a
+#define MII_VSC8244_ISTAT_STATUS 0x8000
+#define MII_VSC8244_ISTAT_SPEED 0x4000
+#define MII_VSC8244_ISTAT_LINK 0x2000
+#define MII_VSC8244_ISTAT_DUPLEX 0x1000
+
+/* Vitesse Auxiliary Control/Status Register */
+#define MII_VSC8244_AUX_CONSTAT 0x1c
+#define MII_VSC8244_AUXCONSTAT_INIT 0x0004
+#define MII_VSC8244_AUXCONSTAT_DUPLEX 0x0020
+#define MII_VSC8244_AUXCONSTAT_SPEED 0x0018
+#define MII_VSC8244_AUXCONSTAT_GBIT 0x0010
+#define MII_VSC8244_AUXCONSTAT_100 0x0008
+
+MODULE_DESCRIPTION("Vitesse PHY driver");
+MODULE_AUTHOR("Kriston Carson");
+MODULE_LICENSE("GPL");
+
+static int vsc824x_config_init(struct phy_device *phydev)
+{
+ int err;
+
+ err = phy_write(phydev, MII_VSC8244_AUX_CONSTAT,
+ MII_VSC8244_AUXCONSTAT_INIT);
+
+ if (err < 0)
+ return err;
+
+ err = phy_write(phydev, MII_VSC8244_EXT_CON1,
+ MII_VSC8244_EXTCON1_INIT);
+
+ return err;
+
+}
+
+static int vsc824x_ack_interrupt(struct phy_device *phydev)
+{
+ int err = phy_read(phydev, MII_VSC8244_ISTAT);
+
+ return (err < 0) ? err : 0;
+
+}
+
+static int vsc824x_config_intr(struct phy_device *phydev)
+{
+ int err;
+
+ if (phydev->interrupts == PHY_INTERRUPT_ENABLED)
+ err = phy_write(phydev, MII_VSC8244_IMASK,
+ MII_VSC8244_IMASK_MASK);
+ else
+ err = phy_write(phydev, MII_VSC8244_IMASK, 0);
+
+ return err;
+
+}
+
+/* Vitesse 824x */
+static struct phy_driver vsc8244_driver = {
+ .phy_id = 0x000fc6c2,
+ .name = "Vitesse VSC8244",
+ .phy_id_mask = 0x000fffc0,
+ .features = PHY_GBIT_FEATURES,
+ .flags = PHY_HAS_INTERRUPT,
+ .config_init = &vsc824x_config_init,
+ .config_aneg = &genphy_config_aneg,
+ .read_status = &genphy_read_status,
+ .ack_interrupt = &vsc824x_ack_interrupt,
+ .config_intr = &vsc824x_config_intr,
+ .driver = { .owner = THIS_MODULE,},
+};
+
+static int __init vsc8244_init(void)
+{
+ return phy_driver_register(&vsc8244_driver);
+}
+
+static void __exit vsc8244_exit(void)
+{
+ phy_driver_unregister(&vsc8244_driver);
+}
+
+module_init(vsc8244_init);
+module_exit(vsc8244_exit);
^ permalink raw reply related
* Re: Updated sysctl documentation take #2
From: Johannes Stezenbach @ 2006-06-07 23:56 UTC (permalink / raw)
To: Diego Calleja; +Cc: linux-kernel, akpm, netdev, linux-xfs, ecki, lkml
In-Reply-To: <20060607205316.bbb3c379.diegocg@gmail.com>
On Wed, Jun 07, 2006, Diego Calleja wrote:
> Since people didn't like the "many small files" approach, I've moved
> it to directories containing index.txt files:
>
> Documentation/sysctl/vm/index.txt
> Documentation/sysctl/net/core/index.txt
Why not just
Documentation/sysctl/vm.txt
Documentation/sysctl/net/core.txt
etc.?
Johannes
^ permalink raw reply
* Re: Updated sysctl documentation take #2
From: David Lang @ 2006-06-07 22:52 UTC (permalink / raw)
To: Johannes Stezenbach
Cc: Diego Calleja, linux-kernel, akpm, netdev, linux-xfs, ecki, lkml
In-Reply-To: <20060607235631.GA10688@linuxtv.org>
On Thu, 8 Jun 2006, Johannes Stezenbach wrote:
> On Wed, Jun 07, 2006, Diego Calleja wrote:
>> Since people didn't like the "many small files" approach, I've moved
>> it to directories containing index.txt files:
>>
>> Documentation/sysctl/vm/index.txt
>> Documentation/sysctl/net/core/index.txt
>
> Why not just
>
> Documentation/sysctl/vm.txt
> Documentation/sysctl/net/core.txt
>
> etc.?
better matching of the proc layout would be my guess.
^ permalink raw reply
* Re: [PATCH 3/4] ehea: queue managment
From: Muli Ben-Yehuda @ 2006-06-08 6:35 UTC (permalink / raw)
To: Stephen Hemminger
Cc: ossthema, netdev, Marcus Eder, Christoph Raisch,
Jan-Bernd Themann, Thomas Q Klein
In-Reply-To: <20060607102950.54dd83c1@localhost.localdomain>
On Wed, Jun 07, 2006 at 10:29:50AM -0700, Stephen Hemminger wrote:
> Be careful about global namespace issues. Stick to one prefix like ehea_
> for all non static function names. Consider putting all in one file, or
> use #include to cause it to be one compilation unit.
I thought including .c files was discouraged (if not, it should be...)
Cheers,
Muli
^ permalink raw reply
* Re: [patch] workaround zd1201 interference problem
From: Pavel Machek @ 2006-06-08 7:05 UTC (permalink / raw)
To: Daniel Drake; +Cc: Jiri Benc, linville, kernel list, netdev
In-Reply-To: <4486FD2F.8040205@gentoo.org>
Hi!
> >Well, I'll try _enable() alone, but it seems to me that _enable()
> >command is needed to initialize radio properly. I do not think we can
> >get much further without firmware sources...
>
> If you can formulate a proper and technical description of the issue
> (and exactly what is needed to workaround it), I can contact ZyDAS for
> you. They have been very helpful with ZD1211.
Okay, the issue is:
if you plug zd1201 into USB, it starts jamming radio,
immediately. Enable/disable, or iwlist wlan0 scan, or basically any
operation unjams the radio. This patch works it around:
diff --git a/drivers/net/wireless/zd1201.c b/drivers/net/wireless/zd1201.c
index 335eaf3..dcc7bc7 100644
--- a/drivers/net/wireless/zd1201.c
+++ b/drivers/net/wireless/zd1201.c
@@ -1835,8 +1835,8 @@ static int zd1201_probe(struct usb_inter
zd->dev->name);
usb_set_intfdata(interface, zd);
- zd1201_enable(zd);
- zd1201_disable(zd);
+ zd1201_enable(zd); /* zd1201 likes to startup enabled, interfering */
+ zd1201_disable(zd); /* with all the wifis in range */
return 0;
err_net:
....question is "is that right solution, or is something different
needed to solve that problem properly"?
Pavel
--
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html
^ permalink raw reply related
* Re: [patch] workaround zd1201 interference problem
From: Pavel Machek @ 2006-06-08 7:13 UTC (permalink / raw)
To: Daniel Drake; +Cc: Jiri Benc, linville, kernel list, netdev
In-Reply-To: <20060608070525.GE3688@elf.ucw.cz>
Hi!
> > >Well, I'll try _enable() alone, but it seems to me that _enable()
> > >command is needed to initialize radio properly. I do not think we can
> > >get much further without firmware sources...
> >
> > If you can formulate a proper and technical description of the issue
> > (and exactly what is needed to workaround it), I can contact ZyDAS for
> > you. They have been very helpful with ZD1211.
>
> Okay, the issue is:
>
> if you plug zd1201 into USB, it starts jamming radio,
> immediately. Enable/disable, or iwlist wlan0 scan, or basically any
> operation unjams the radio. This patch works it around:
Of course, the patch should have been:
diff --git a/drivers/net/wireless/zd1201.c b/drivers/net/wireless/zd1201.c
index 335eaf3..dcc7bc7 100644
--- a/drivers/net/wireless/zd1201.c
+++ b/drivers/net/wireless/zd1201.c
@@ -1835,6 +1835,8 @@ static int zd1201_probe(struct usb_inter
zd->dev->name);
usb_set_intfdata(interface, zd);
+ zd1201_enable(zd); /* zd1201 likes to startup enabled, interfering */
+ zd1201_disable(zd); /* with all the wifis in range */
return 0;
err_net:
....question is "is that right solution, or is something different
needed to solve that problem properly"?
Pavel
--
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html
^ permalink raw reply
* [PATCH 0/12] d80211: use sysfs instead of procfs
From: Jiri Benc @ 2006-06-08 7:49 UTC (permalink / raw)
To: netdev; +Cc: John W. Linville
The following series of patches makes d80211 to use sysfs instead of procfs.
This means that custom reference counting in most structures is replaced by
kobjects and nearly all informations from procfs files are converted to
sysfs attributes.
The only information missing in sysfs (compared to procfs) is channels and
rates info. Implementing this in a sysfs way (i. e. one information per
attribute rule) requires a lot of code and (more important) adding kobjects
to channel and rate structures. I doubt these informations are really so
useful to be worth such complications. If there are good arguments why these
informations should be exported via sysfs I will add them.
If you find a better name for some object (directory) or attribute (file) or
just consider some name wrong or ugly, let me know please.
The third patch ("separate allocation of ieee80211_local") touches the code
outside of net/d80211 - it adds ieee80211_ptr to net_device structure.
All of patches can be also obtained from 'master' branch of
git://git.kernel.org/pub/scm/linux/kernel/git/jbenc/dscape.git
---
Jiri Benc:
d80211: deinit sysfs in case of an error
d80211: better sysfs registration of symlinks to wiphy
d80211: separate allocation of ieee80211_local
d80211: fix Oops when writing to add_ and remove_iface
d80211: wiphy sysfs attributes
d80211: network interface sysfs attributes
d80211: rename sta_info_relase to sta_info_put
d80211: sysfs attributes for associated stations
d80211: remove useless parameters
d80211: rate_control sysfs attributes
d80211: encryption keys sysfs attributes
d80211: remove procfs files
include/linux/netdevice.h | 1
net/d80211/Makefile | 2
net/d80211/ieee80211.c | 206 +++++++---
net/d80211/ieee80211_dev.c | 17 +
net/d80211/ieee80211_i.h | 45 ++
net/d80211/ieee80211_iface.c | 43 +-
net/d80211/ieee80211_ioctl.c | 213 ++++++----
net/d80211/ieee80211_key.h | 2
net/d80211/ieee80211_proc.c | 771 --------------------------------------
net/d80211/ieee80211_proc.h | 45 --
net/d80211/ieee80211_scan.c | 10
net/d80211/ieee80211_sta.c | 68 ++-
net/d80211/ieee80211_sysfs.c | 706 +++++++++++++++++++++++++++++++++--
net/d80211/ieee80211_sysfs_sta.c | 434 +++++++++++++++++++++
net/d80211/rate_control.c | 55 ++-
net/d80211/rate_control.h | 57 ++-
net/d80211/sta_info.c | 132 ++++---
net/d80211/sta_info.h | 16 -
net/d80211/wme.c | 26 +
19 files changed, 1663 insertions(+), 1186 deletions(-)
--
Jiri Benc
SUSE Labs
^ permalink raw reply
* [PATCH 1/12] d80211: deinit sysfs in case of an error
From: Jiri Benc @ 2006-06-08 7:49 UTC (permalink / raw)
To: netdev; +Cc: John W. Linville
In-Reply-To: <20060608094822.014829000.midnight@suse.cz>
When ieee80211_wme_register fails in ieee80211_init, ieee80211 class was not
unregistered.
Signed-off-by: Jiri Benc <jbenc@suse.cz>
---
net/d80211/ieee80211.c | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
3aed246a5117bd4d1a4f2d5f5074c583d9b4941e
diff --git a/net/d80211/ieee80211.c b/net/d80211/ieee80211.c
index b850fb7..f549098 100644
--- a/net/d80211/ieee80211.c
+++ b/net/d80211/ieee80211.c
@@ -4462,6 +4462,7 @@ static int __init ieee80211_init(void)
if (ret) {
printk(KERN_DEBUG "ieee80211_init: failed to "
"initialize WME (err=%d)\n", ret);
+ ieee80211_sysfs_deinit();
ieee80211_proc_deinit();
return ret;
}
--
1.3.0
^ permalink raw reply related
* [PATCH 2/12] d80211: better sysfs registration of symlinks to wiphy
From: Jiri Benc @ 2006-06-08 7:49 UTC (permalink / raw)
To: netdev; +Cc: John W. Linville
In-Reply-To: <20060608094822.014829000.midnight@suse.cz>
Lately, delayed sysfs registration of net_device (in netdev_run_todo) was
removed. This allows us to remove hack that used class interface for sysfs
registration.
Signed-off-by: Jiri Benc <jbenc@suse.cz>
---
net/d80211/ieee80211.c | 18 +++++++++++++++--
net/d80211/ieee80211_i.h | 2 ++
net/d80211/ieee80211_iface.c | 15 ++++++++++++++
net/d80211/ieee80211_sysfs.c | 45 ++++++------------------------------------
4 files changed, 39 insertions(+), 41 deletions(-)
beb1533d9181d1c6d195de5743517b3559bfd9f9
diff --git a/net/d80211/ieee80211.c b/net/d80211/ieee80211.c
index f549098..9724a49 100644
--- a/net/d80211/ieee80211.c
+++ b/net/d80211/ieee80211.c
@@ -4197,9 +4197,21 @@ int ieee80211_register_hw(struct net_dev
if (hw->fraglist)
dev->features |= NETIF_F_FRAGLIST;
- result = register_netdev(dev);
- if (result < 0)
+ rtnl_lock();
+ result = dev_alloc_name(dev, dev->name);
+ if (result < 0) {
+ rtnl_unlock();
+ goto fail_dev;
+ }
+ result = register_netdevice(dev);
+ if (result < 0) {
+ rtnl_unlock();
goto fail_dev;
+ }
+ result = ieee80211_sysfs_add_netdevice(dev);
+ rtnl_unlock();
+ if (result < 0)
+ goto fail_if_sysfs;
if (rate_control_initialize(local) < 0) {
printk(KERN_DEBUG "%s: Failed to initialize rate control "
@@ -4223,6 +4235,8 @@ int ieee80211_register_hw(struct net_dev
return 0;
fail_rate:
+ ieee80211_sysfs_remove_netdevice(dev);
+fail_if_sysfs:
unregister_netdev(dev);
fail_dev:
sta_info_stop(local);
diff --git a/net/d80211/ieee80211_i.h b/net/d80211/ieee80211_i.h
index 94e151d..19d9d98 100644
--- a/net/d80211/ieee80211_i.h
+++ b/net/d80211/ieee80211_i.h
@@ -599,6 +599,8 @@ int ieee80211_if_add_mgmt(struct net_dev
void ieee80211_if_del_mgmt(struct net_device *dev);
/* ieee80211_sysfs.c */
+int ieee80211_sysfs_add_netdevice(struct net_device *dev);
+void ieee80211_sysfs_remove_netdevice(struct net_device *dev);
int ieee80211_register_sysfs(struct ieee80211_local *local);
void ieee80211_unregister_sysfs(struct ieee80211_local *local);
int ieee80211_sysfs_init(void);
diff --git a/net/d80211/ieee80211_iface.c b/net/d80211/ieee80211_iface.c
index 6631738..d534fe4 100644
--- a/net/d80211/ieee80211_iface.c
+++ b/net/d80211/ieee80211_iface.c
@@ -76,6 +76,13 @@ int ieee80211_if_add(struct net_device *
ret = register_netdevice(ndev);
if (ret)
goto fail;
+ ret = ieee80211_sysfs_add_netdevice(ndev);
+ if (ret) {
+ /* ndev will be freed by ndev->destructor */
+ unregister_netdevice(ndev);
+ *new_dev = NULL;
+ return ret;
+ }
list_add(&sdata->list, &local->sub_if_list);
ieee80211_proc_init_virtual(ndev);
@@ -123,10 +130,16 @@ int ieee80211_if_add_mgmt(struct net_dev
ret = register_netdevice(ndev);
if (ret)
goto fail;
+ ret = ieee80211_sysfs_add_netdevice(ndev);
+ if (ret)
+ goto fail_sysfs;
if (local->open_count > 0)
dev_open(ndev);
local->apdev = ndev;
return 0;
+
+fail_sysfs:
+ unregister_netdevice(ndev);
fail:
free_netdev(ndev);
return ret;
@@ -139,6 +152,7 @@ void ieee80211_if_del_mgmt(struct net_de
ASSERT_RTNL();
apdev = local->apdev;
+ ieee80211_sysfs_remove_netdevice(apdev);
local->apdev = NULL;
unregister_netdevice(apdev);
}
@@ -293,6 +307,7 @@ void __ieee80211_if_del(struct ieee80211
ieee80211_if_reinit(dev);
list_del(&sdata->list);
ieee80211_proc_deinit_virtual(dev);
+ ieee80211_sysfs_remove_netdevice(dev);
unregister_netdevice(dev);
/* Except master interface, the net_device will be freed by
* net_device->destructor (i. e. ieee80211_if_free). */
diff --git a/net/d80211/ieee80211_sysfs.c b/net/d80211/ieee80211_sysfs.c
index 463f9aa..5c7af9f 100644
--- a/net/d80211/ieee80211_sysfs.c
+++ b/net/d80211/ieee80211_sysfs.c
@@ -98,60 +98,27 @@ void ieee80211_unregister_sysfs(struct i
class_device_del(&local->class_dev);
}
-static int ieee80211_add_netdevice(struct class_device *cd,
- struct class_interface *cintf)
+int ieee80211_sysfs_add_netdevice(struct net_device *dev)
{
- struct net_device *dev = container_of(cd, struct net_device, class_dev);
struct ieee80211_local *local = dev->priv;
- if (ieee80211_dev_find_index(local) < 0)
- return 0;
- return sysfs_create_link(&cd->kobj, &local->class_dev.kobj, "wiphy");
+ return sysfs_create_link(&dev->class_dev.kobj, &local->class_dev.kobj,
+ "wiphy");
}
-static void ieee80211_remove_netdevice(struct class_device *cd,
- struct class_interface *cintf)
+void ieee80211_sysfs_remove_netdevice(struct net_device *dev)
{
- struct net_device *dev = container_of(cd, struct net_device, class_dev);
struct ieee80211_local *local = dev->priv;
- if (ieee80211_dev_find_index(local) >= 0)
- sysfs_remove_link(&cd->kobj, "wiphy");
-}
-
-static struct class_interface ieee80211_wiphy_cintf = {
- .add = ieee80211_add_netdevice,
- .remove = ieee80211_remove_netdevice,
-};
-
-/* Adds class interface watching for new network devices and adding "wiphy"
- * attribute (symlink) to them. */
-static int ieee80211_register_wiphy_cintf(void)
-{
- ieee80211_wiphy_cintf.class = loopback_dev.class_dev.class;
- return class_interface_register(&ieee80211_wiphy_cintf);
-}
-
-static void ieee80211_unregister_wiphy_cintf(void)
-{
- class_interface_unregister(&ieee80211_wiphy_cintf);
+ sysfs_remove_link(&dev->class_dev.kobj, "wiphy");
}
int ieee80211_sysfs_init(void)
{
- int result;
-
- result = class_register(&ieee80211_class);
- if (result)
- return result;
- result = ieee80211_register_wiphy_cintf();
- if (result)
- class_unregister(&ieee80211_class);
- return result;
+ return class_register(&ieee80211_class);
}
void ieee80211_sysfs_deinit(void)
{
- ieee80211_unregister_wiphy_cintf();
class_unregister(&ieee80211_class);
}
--
1.3.0
^ permalink raw reply related
* [PATCH 4/12] d80211: fix Oops when writing to add_ and remove_iface
From: Jiri Benc @ 2006-06-08 7:49 UTC (permalink / raw)
To: netdev; +Cc: John W. Linville
In-Reply-To: <20060608094822.014829000.midnight@suse.cz>
When add_iface or remove_iface sysfs attribute is opened just before device
is unregistered and some data is written there afterwards, their handlers
try to access master net_device which is released at that point.
A similar problem can happen when ioctl is invoked during unregistering - it
is possible that interface the ioctl was called on is still there but master
interface has been already freed.
Fix these problems by:
- checking if the device is unregistered in sysfs handlers and
- releasing all interfaces under single rtnl lock.
Signed-off-by: Jiri Benc <jbenc@suse.cz>
---
net/d80211/ieee80211.c | 9 +++++++--
net/d80211/ieee80211_i.h | 6 ++++++
net/d80211/ieee80211_sysfs.c | 17 +++++++++++++++--
3 files changed, 28 insertions(+), 4 deletions(-)
25dd82745a86401267b9954098b99ba4a60a71f6
diff --git a/net/d80211/ieee80211.c b/net/d80211/ieee80211.c
index 4fc2e7d..c983d70 100644
--- a/net/d80211/ieee80211.c
+++ b/net/d80211/ieee80211.c
@@ -4225,6 +4225,8 @@ int ieee80211_register_hw(struct net_dev
result = ieee80211_if_add(dev, "wlan%d", 1, &sta_dev);
if (result == 0)
ieee80211_if_set_type(sta_dev, IEEE80211_IF_TYPE_STA);
+
+ local->reg_state = IEEE80211_DEV_REGISTERED;
rtnl_unlock();
return 0;
@@ -4290,14 +4292,17 @@ void ieee80211_unregister_hw(struct net_
del_timer_sync(&local->scan_timer);
ieee80211_rx_bss_list_deinit(dev);
+ rtnl_lock();
+ local->reg_state = IEEE80211_DEV_UNREGISTERED;
if (local->apdev)
- ieee80211_if_del(local->apdev);
+ ieee80211_if_del_mgmt(local->apdev);
list_for_each_safe(ptr, n, &local->sub_if_list) {
struct ieee80211_sub_if_data *sdata =
list_entry(ptr, struct ieee80211_sub_if_data, list);
- ieee80211_if_del(sdata->dev);
+ __ieee80211_if_del(local, sdata);
}
+ rtnl_unlock();
sta_info_stop(local);
ieee80211_dev_sysfs_del(local);
diff --git a/net/d80211/ieee80211_i.h b/net/d80211/ieee80211_i.h
index 84cc50e..9fabf17 100644
--- a/net/d80211/ieee80211_i.h
+++ b/net/d80211/ieee80211_i.h
@@ -321,6 +321,12 @@ struct ieee80211_local {
int dev_index;
struct class_device class_dev;
+ enum {
+ IEEE80211_DEV_UNITIALIZED = 0,
+ IEEE80211_DEV_REGISTERED,
+ IEEE80211_DEV_UNREGISTERED,
+ } reg_state;
+
/* Tasklet and skb queue to process calls from IRQ mode. All frames
* added to skb_queue will be processed, but frames in
* skb_queue_unreliable may be dropped if the total length of these
diff --git a/net/d80211/ieee80211_sysfs.c b/net/d80211/ieee80211_sysfs.c
index fb95e96..e799506 100644
--- a/net/d80211/ieee80211_sysfs.c
+++ b/net/d80211/ieee80211_sysfs.c
@@ -17,6 +17,15 @@ #include "ieee80211_i.h"
#define to_ieee80211_local(class) container_of(class, struct ieee80211_local, class_dev)
+static inline int rtnl_lock_local(struct ieee80211_local *local)
+{
+ rtnl_lock();
+ if (unlikely(local->reg_state != IEEE80211_DEV_REGISTERED)) {
+ rtnl_unlock();
+ return -ENODEV;
+ }
+ return 0;
+}
static ssize_t store_add_iface(struct class_device *dev,
const char *buf, size_t len)
@@ -29,7 +38,9 @@ static ssize_t store_add_iface(struct cl
return -EPERM;
if (len > IFNAMSIZ)
return -EINVAL;
- rtnl_lock();
+ res = rtnl_lock_local(local);
+ if (res)
+ return res;
res = ieee80211_if_add(local->mdev, buf, 0, &new_dev);
if (res == 0)
ieee80211_if_set_type(new_dev, IEEE80211_IF_TYPE_STA);
@@ -47,7 +58,9 @@ static ssize_t store_remove_iface(struct
return -EPERM;
if (len > IFNAMSIZ)
return -EINVAL;
- rtnl_lock();
+ res = rtnl_lock_local(local);
+ if (res)
+ return res;
res = ieee80211_if_remove(local->mdev, buf, -1);
rtnl_unlock();
return res < 0 ? res : len;
--
1.3.0
^ permalink raw reply related
* [PATCH 3/12] d80211: separate allocation of ieee80211_local
From: Jiri Benc @ 2006-06-08 7:49 UTC (permalink / raw)
To: netdev; +Cc: John W. Linville
In-Reply-To: <20060608094822.014829000.midnight@suse.cz>
ieee80211_local has a separate class_device. That means it has reference
counting independent of master net_device and can be freed at a different
time, therefore these two structures cannot be allocated together.
Solve this by adding ieee80211_ptr pointer to net_device structure (similar
to other pointers already presented there) and using it as a pointer to
independently allocated ieee80211_local.
This also allows is_ieee80211_device function to be nice finally.
Signed-off-by: Jiri Benc <jbenc@suse.cz>
---
include/linux/netdevice.h | 1
net/d80211/ieee80211.c | 100 +++++++++++++++++++++---------------------
net/d80211/ieee80211_dev.c | 17 +++++++
net/d80211/ieee80211_i.h | 9 +++-
net/d80211/ieee80211_iface.c | 20 ++++----
net/d80211/ieee80211_ioctl.c | 92 +++++++++++++++++++--------------------
net/d80211/ieee80211_proc.c | 6 +--
net/d80211/ieee80211_scan.c | 10 ++--
net/d80211/ieee80211_sta.c | 58 ++++++++++++------------
net/d80211/ieee80211_sysfs.c | 26 ++++++++---
net/d80211/rate_control.c | 4 +-
net/d80211/rate_control.h | 4 +-
net/d80211/wme.c | 26 +++++------
13 files changed, 206 insertions(+), 167 deletions(-)
3085d33e38881f0987329c4258514f60ffe824af
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index f4169bb..037e63a 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -371,6 +371,7 @@ #define NETIF_F_UFO 8192
void *ip6_ptr; /* IPv6 specific data */
void *ec_ptr; /* Econet specific data */
void *ax25_ptr; /* AX.25 specific data */
+ void *ieee80211_ptr; /* IEEE 802.11 specific data */
/*
* Cache line mostly used on receive path (including eth_type_trans())
diff --git a/net/d80211/ieee80211.c b/net/d80211/ieee80211.c
index 9724a49..4fc2e7d 100644
--- a/net/d80211/ieee80211.c
+++ b/net/d80211/ieee80211.c
@@ -110,7 +110,7 @@ static int rate_list_match(int *rate_lis
void ieee80211_prepare_rates(struct net_device *dev)
{
- struct ieee80211_local *local = dev->priv;
+ struct ieee80211_local *local = dev->ieee80211_ptr;
int i;
for (i = 0; i < local->num_curr_rates; i++) {
@@ -1059,7 +1059,7 @@ __ieee80211_tx_prepare(struct ieee80211_
struct net_device *dev,
struct ieee80211_tx_control *control)
{
- struct ieee80211_local *local = dev->priv;
+ struct ieee80211_local *local = dev->ieee80211_ptr;
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
int hdrlen;
@@ -1095,12 +1095,9 @@ __ieee80211_tx_prepare(struct ieee80211_
}
-/* FIXME: This is not nice but currently there doesn't exist more elegant way */
static int inline is_ieee80211_device(struct net_device *dev)
{
- return (dev->wireless_handlers ==
- (struct iw_handler_def *) &ieee80211_iw_handler_def) ||
- (dev->hard_start_xmit == ieee80211_mgmt_start_xmit);
+ return (dev->ieee80211_ptr != NULL);
}
/* Device in tx->dev has a reference added; use dev_put(tx->dev) when
@@ -1131,7 +1128,7 @@ static void inline ieee80211_tx_prepare(
static int ieee80211_tx(struct net_device *dev, struct sk_buff *skb,
struct ieee80211_tx_control *control, int mgmt)
{
- struct ieee80211_local *local = dev->priv;
+ struct ieee80211_local *local = dev->ieee80211_ptr;
struct sta_info *sta;
ieee80211_tx_handler *handler;
struct ieee80211_txrx_data tx;
@@ -1307,7 +1304,7 @@ #endif
static int ieee80211_subif_start_xmit(struct sk_buff *skb,
struct net_device *dev)
{
- struct ieee80211_local *local = (struct ieee80211_local *) dev->priv;
+ struct ieee80211_local *local = dev->ieee80211_ptr;
struct ieee80211_tx_packet_data *pkt_data;
struct ieee80211_sub_if_data *sdata;
int ret = 1, head_need;
@@ -1613,7 +1610,7 @@ static void ieee80211_beacon_add_tim(str
struct sk_buff * ieee80211_beacon_get(struct net_device *dev, int if_id,
struct ieee80211_tx_control *control)
{
- struct ieee80211_local *local = dev->priv;
+ struct ieee80211_local *local = dev->ieee80211_ptr;
struct sk_buff *skb;
struct net_device *bdev;
struct ieee80211_sub_if_data *sdata = NULL;
@@ -1690,7 +1687,7 @@ struct sk_buff *
ieee80211_get_buffered_bc(struct net_device *dev, int if_id,
struct ieee80211_tx_control *control)
{
- struct ieee80211_local *local = dev->priv;
+ struct ieee80211_local *local = dev->ieee80211_ptr;
struct sk_buff *skb;
struct sta_info *sta;
ieee80211_tx_handler *handler;
@@ -1754,7 +1751,7 @@ ieee80211_get_buffered_bc(struct net_dev
int ieee80211_if_config(struct net_device *dev)
{
struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
- struct ieee80211_local *local = dev->priv;
+ struct ieee80211_local *local = dev->ieee80211_ptr;
struct ieee80211_if_conf conf;
if (!local->hw->config_interface || !netif_running(dev))
@@ -1780,7 +1777,7 @@ int ieee80211_if_config(struct net_devic
int ieee80211_hw_config(struct net_device *dev)
{
- struct ieee80211_local *local = dev->priv;
+ struct ieee80211_local *local = dev->ieee80211_ptr;
int i, ret = 0;
#ifdef CONFIG_D80211_VERBOSE_DEBUG
@@ -1811,7 +1808,7 @@ #endif /* CONFIG_D80211_VERBOSE_DEBUG */
struct ieee80211_conf *ieee80211_get_hw_conf(struct net_device *dev)
{
- struct ieee80211_local *local = dev->priv;
+ struct ieee80211_local *local = dev->ieee80211_ptr;
return &local->conf;
}
@@ -1854,7 +1851,7 @@ #endif /* CONFIG_D80211_VERBOSE_DEBUG */
static void ieee80211_tx_timeout(struct net_device *dev)
{
- struct ieee80211_local *local = dev->priv;
+ struct ieee80211_local *local = dev->ieee80211_ptr;
printk(KERN_WARNING "%s: resetting interface.\n", dev->name);
@@ -1878,7 +1875,7 @@ static int ieee80211_set_mac_address(str
static void ieee80211_set_multicast_list(struct net_device *dev)
{
- struct ieee80211_local *local = dev->priv;
+ struct ieee80211_local *local = dev->ieee80211_ptr;
struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
unsigned short flags;
@@ -1920,7 +1917,7 @@ struct dev_mc_list *ieee80211_get_mc_lis
struct dev_mc_list *prev,
void **ptr)
{
- struct ieee80211_local *local = dev->priv;
+ struct ieee80211_local *local = dev->ieee80211_ptr;
struct ieee80211_sub_if_data *sdata = *ptr;
struct dev_mc_list *mc;
@@ -1966,7 +1963,7 @@ static inline int identical_mac_addr_all
static int ieee80211_master_open(struct net_device *dev)
{
- struct ieee80211_local *local = dev->priv;
+ struct ieee80211_local *local = dev->ieee80211_ptr;
struct ieee80211_sub_if_data *sdata;
int res = -EOPNOTSUPP;
@@ -1981,7 +1978,7 @@ static int ieee80211_master_open(struct
static int ieee80211_master_stop(struct net_device *dev)
{
- struct ieee80211_local *local = dev->priv;
+ struct ieee80211_local *local = dev->ieee80211_ptr;
struct ieee80211_sub_if_data *sdata;
list_for_each_entry(sdata, &local->sub_if_list, list) {
@@ -1993,7 +1990,7 @@ static int ieee80211_master_stop(struct
static int ieee80211_mgmt_open(struct net_device *dev)
{
- struct ieee80211_local *local = dev->priv;
+ struct ieee80211_local *local = dev->ieee80211_ptr;
if (!netif_running(local->mdev))
return -EOPNOTSUPP;
@@ -2038,7 +2035,7 @@ static void ieee80211_start_hard_monitor
static int ieee80211_open(struct net_device *dev)
{
struct ieee80211_sub_if_data *sdata, *nsdata;
- struct ieee80211_local *local = dev->priv;
+ struct ieee80211_local *local = dev->ieee80211_ptr;
struct ieee80211_if_init_conf conf;
int res;
@@ -2117,7 +2114,7 @@ static int ieee80211_open(struct net_dev
static int ieee80211_stop(struct net_device *dev)
{
struct ieee80211_sub_if_data *sdata;
- struct ieee80211_local *local = dev->priv;
+ struct ieee80211_local *local = dev->ieee80211_ptr;
sdata = IEEE80211_DEV_TO_SUB_IF(dev);
@@ -2381,7 +2378,7 @@ void
ieee80211_rx_mgmt(struct net_device *dev, struct sk_buff *skb,
struct ieee80211_rx_status *status, u32 msg_type)
{
- struct ieee80211_local *local = dev->priv;
+ struct ieee80211_local *local = dev->ieee80211_ptr;
struct ieee80211_frame_info *fi;
size_t hlen;
struct ieee80211_sub_if_data *sdata;
@@ -2545,7 +2542,7 @@ #endif /* IEEE80211_VERBOSE_DEBUG_PS */
static int ap_sta_ps_end(struct net_device *dev, struct sta_info *sta)
{
- struct ieee80211_local *local = dev->priv;
+ struct ieee80211_local *local = dev->ieee80211_ptr;
struct sk_buff *skb;
int sent = 0;
struct ieee80211_sub_if_data *sdata;
@@ -3356,7 +3353,7 @@ static inline void ieee80211_invoke_rx_h
void __ieee80211_rx(struct net_device *dev, struct sk_buff *skb,
struct ieee80211_rx_status *status)
{
- struct ieee80211_local *local = dev->priv;
+ struct ieee80211_local *local = dev->ieee80211_ptr;
struct ieee80211_sub_if_data *sdata;
struct sta_info *sta;
struct ieee80211_hdr *hdr;
@@ -3629,7 +3626,7 @@ static void ieee80211_stat_refresh(unsig
void ieee80211_rx_irqsafe(struct net_device *dev, struct sk_buff *skb,
struct ieee80211_rx_status *status)
{
- struct ieee80211_local *local = dev->priv;
+ struct ieee80211_local *local = dev->ieee80211_ptr;
struct ieee80211_rx_status *saved;
skb->dev = dev;
@@ -3646,7 +3643,7 @@ void ieee80211_rx_irqsafe(struct net_dev
void ieee80211_tx_status_irqsafe(struct net_device *dev, struct sk_buff *skb,
struct ieee80211_tx_status *status)
{
- struct ieee80211_local *local = dev->priv;
+ struct ieee80211_local *local = dev->ieee80211_ptr;
struct ieee80211_tx_status *saved;
int tmp;
@@ -3786,7 +3783,7 @@ void ieee80211_tx_status(struct net_devi
{
struct sk_buff *skb2;
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
- struct ieee80211_local *local = dev->priv;
+ struct ieee80211_local *local = dev->ieee80211_ptr;
u16 frag, type;
u32 msg_type;
@@ -3974,7 +3971,7 @@ static ieee80211_tx_handler ieee80211_tx
int ieee80211_if_update_wds(struct net_device *dev, u8 *remote_addr)
{
- struct ieee80211_local *local = dev->priv;
+ struct ieee80211_local *local = dev->ieee80211_ptr;
struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
struct sta_info *sta;
@@ -3998,7 +3995,7 @@ int ieee80211_if_update_wds(struct net_d
static void ieee80211_if_init(struct net_device *dev)
{
- struct ieee80211_local *local = dev->priv;
+ struct ieee80211_local *local = dev->ieee80211_ptr;
spin_lock_init(&local->sub_if_lock);
INIT_LIST_HEAD(&local->sub_if_list);
@@ -4065,6 +4062,10 @@ struct net_device *ieee80211_alloc_hw(si
struct ieee80211_sub_if_data *sdata;
int priv_size;
+ local = ieee80211_dev_alloc(GFP_KERNEL);
+ if (!local)
+ return NULL;
+
/* Ensure 32-byte alignment of our private data and hw private data.
* Each net_device is followed by a sub_if_data which is used for
* interface specific information.
@@ -4075,30 +4076,24 @@ struct net_device *ieee80211_alloc_hw(si
* * net_dev *
* 0160 *****************
* * sub_if *
- * 0180 *****************
- * * local *
* 0b80 *****************
* * hw_priv *
* 1664 *****************
*/
priv_size = ((sizeof(struct ieee80211_sub_if_data) +
NETDEV_ALIGN_CONST) & ~NETDEV_ALIGN_CONST) +
- ((sizeof(struct ieee80211_local) +
- NETDEV_ALIGN_CONST) & ~NETDEV_ALIGN_CONST) +
priv_data_len;
mdev = alloc_netdev(priv_size, "wmaster%d", ether_setup);
- if (mdev == NULL)
+ if (mdev == NULL) {
+ ieee80211_dev_free(local);
return NULL;
+ }
- mdev->priv = (char *)netdev_priv(mdev) +
- ((sizeof(struct ieee80211_sub_if_data) +
- NETDEV_ALIGN_CONST) & ~NETDEV_ALIGN_CONST);
- local = mdev->priv;
- local->hw_priv = (char *)local +
- ((sizeof(struct ieee80211_local) +
+ mdev->ieee80211_ptr = local;
+ local->hw_priv = (char *)mdev->priv +
+ ((sizeof(struct ieee80211_sub_if_data) +
NETDEV_ALIGN_CONST) & ~NETDEV_ALIGN_CONST);
- local->dev_index = -1;
local->mdev = mdev;
local->rx_handlers = ieee80211_rx_handlers;
local->tx_handlers = ieee80211_tx_handlers;
@@ -4166,7 +4161,7 @@ struct net_device *ieee80211_alloc_hw(si
int ieee80211_register_hw(struct net_device *dev, struct ieee80211_hw *hw)
{
- struct ieee80211_local *local = dev->priv;
+ struct ieee80211_local *local = dev->ieee80211_ptr;
struct net_device *sta_dev;
int result;
@@ -4185,7 +4180,7 @@ int ieee80211_register_hw(struct net_dev
return -1;
local->class_dev.dev = dev->class_dev.dev;
- result = ieee80211_register_sysfs(local);
+ result = ieee80211_dev_sysfs_add(local);
if (result < 0)
goto fail_sysfs;
@@ -4240,7 +4235,7 @@ fail_if_sysfs:
unregister_netdev(dev);
fail_dev:
sta_info_stop(local);
- ieee80211_unregister_sysfs(local);
+ ieee80211_dev_sysfs_del(local);
fail_sysfs:
ieee80211_dev_free_index(local);
return result;
@@ -4248,7 +4243,7 @@ fail_sysfs:
int ieee80211_update_hw(struct net_device *dev, struct ieee80211_hw *hw)
{
- struct ieee80211_local *local = dev->priv;
+ struct ieee80211_local *local = dev->ieee80211_ptr;
local->hw = hw;
@@ -4280,7 +4275,7 @@ int ieee80211_update_hw(struct net_devic
void ieee80211_unregister_hw(struct net_device *dev)
{
- struct ieee80211_local *local = dev->priv;
+ struct ieee80211_local *local = dev->ieee80211_ptr;
struct list_head *ptr, *n;
int i;
@@ -4305,7 +4300,7 @@ void ieee80211_unregister_hw(struct net_
}
sta_info_stop(local);
- ieee80211_unregister_sysfs(local);
+ ieee80211_dev_sysfs_del(local);
for (i = 0; i < IEEE80211_FRAGMENT_MAX; i++)
if (local->fragments[i].skb)
@@ -4330,14 +4325,21 @@ void ieee80211_unregister_hw(struct net_
void ieee80211_free_hw(struct net_device *dev)
{
+ struct ieee80211_local *local = dev->ieee80211_ptr;
+
free_netdev(dev);
+ ieee80211_dev_free(local);
}
+void ieee80211_release_hw(struct ieee80211_local *local)
+{
+ kfree(local);
+}
/* Perform netif operations on all configured interfaces */
int ieee80211_netif_oper(struct net_device *sdev, Netif_Oper op)
{
- struct ieee80211_local *local = sdev->priv;
+ struct ieee80211_local *local = sdev->ieee80211_ptr;
struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(sdev);
struct net_device *dev = sdata->master;
@@ -4377,7 +4379,7 @@ #endif
void * ieee80211_dev_hw_data(struct net_device *dev)
{
- struct ieee80211_local *local = dev->priv;
+ struct ieee80211_local *local = dev->ieee80211_ptr;
return local->hw_priv;
}
diff --git a/net/d80211/ieee80211_dev.c b/net/d80211/ieee80211_dev.c
index 6278cfa..6c6ca91 100644
--- a/net/d80211/ieee80211_dev.c
+++ b/net/d80211/ieee80211_dev.c
@@ -99,3 +99,20 @@ int ieee80211_dev_find_index(struct ieee
spin_unlock(&dev_list_lock);
return index;
}
+
+struct ieee80211_local *ieee80211_dev_alloc(gfp_t flags)
+{
+ struct ieee80211_local *local;
+
+ local = kzalloc(sizeof(struct ieee80211_local), flags);
+ if (!local)
+ return NULL;
+ local->dev_index = -1;
+ ieee80211_dev_sysfs_init(local);
+ return local;
+}
+
+void ieee80211_dev_free(struct ieee80211_local *local)
+{
+ ieee80211_dev_sysfs_put(local);
+}
diff --git a/net/d80211/ieee80211_i.h b/net/d80211/ieee80211_i.h
index 19d9d98..84cc50e 100644
--- a/net/d80211/ieee80211_i.h
+++ b/net/d80211/ieee80211_i.h
@@ -505,6 +505,7 @@ #endif /* CONFIG_D80211_DEBUG_COUNTERS *
/* ieee80211.c */
+void ieee80211_release_hw(struct ieee80211_local *local);
int ieee80211_hw_config(struct net_device *dev);
int ieee80211_if_config(struct net_device *dev);
struct ieee80211_key_conf *
@@ -582,6 +583,8 @@ int ieee80211_dev_alloc_index(struct iee
void ieee80211_dev_free_index(struct ieee80211_local *local);
struct ieee80211_local *ieee80211_dev_find(int index);
int ieee80211_dev_find_index(struct ieee80211_local *local);
+struct ieee80211_local *ieee80211_dev_alloc(gfp_t flags);
+void ieee80211_dev_free(struct ieee80211_local *local);
/* ieee80211_iface.c */
int ieee80211_if_add(struct net_device *dev, const char *name,
@@ -601,8 +604,10 @@ void ieee80211_if_del_mgmt(struct net_de
/* ieee80211_sysfs.c */
int ieee80211_sysfs_add_netdevice(struct net_device *dev);
void ieee80211_sysfs_remove_netdevice(struct net_device *dev);
-int ieee80211_register_sysfs(struct ieee80211_local *local);
-void ieee80211_unregister_sysfs(struct ieee80211_local *local);
+void ieee80211_dev_sysfs_init(struct ieee80211_local *local);
+void ieee80211_dev_sysfs_put(struct ieee80211_local *local);
+int ieee80211_dev_sysfs_add(struct ieee80211_local *local);
+void ieee80211_dev_sysfs_del(struct ieee80211_local *local);
int ieee80211_sysfs_init(void);
void ieee80211_sysfs_deinit(void);
diff --git a/net/d80211/ieee80211_iface.c b/net/d80211/ieee80211_iface.c
index d534fe4..8ab2c07 100644
--- a/net/d80211/ieee80211_iface.c
+++ b/net/d80211/ieee80211_iface.c
@@ -29,7 +29,7 @@ int ieee80211_if_add(struct net_device *
int format, struct net_device **new_dev)
{
struct net_device *ndev, *tmp_dev;
- struct ieee80211_local *local = dev->priv;
+ struct ieee80211_local *local = dev->ieee80211_ptr;
struct ieee80211_sub_if_data *sdata = NULL, *sdata_parent;
int ret;
int i;
@@ -40,7 +40,7 @@ int ieee80211_if_add(struct net_device *
if (ndev == NULL)
return -ENOMEM;
- ndev->priv = local;
+ ndev->ieee80211_ptr = local;
if (strlen(name) == 0) {
i = 0;
do {
@@ -98,7 +98,7 @@ fail:
int ieee80211_if_add_mgmt(struct net_device *dev)
{
struct net_device *ndev;
- struct ieee80211_local *local = dev->priv;
+ struct ieee80211_local *local = dev->ieee80211_ptr;
struct ieee80211_sub_if_data *sdata, *nsdata;
int ret;
@@ -113,7 +113,7 @@ int ieee80211_if_add_mgmt(struct net_dev
if (ret)
goto fail;
- ndev->priv = local;
+ ndev->ieee80211_ptr = local;
memcpy(ndev->dev_addr, dev->dev_addr, ETH_ALEN);
ndev->base_addr = dev->base_addr;
ndev->irq = dev->irq;
@@ -147,7 +147,7 @@ fail:
void ieee80211_if_del_mgmt(struct net_device *dev)
{
- struct ieee80211_local *local = dev->priv;
+ struct ieee80211_local *local = dev->ieee80211_ptr;
struct net_device *apdev;
ASSERT_RTNL();
@@ -207,7 +207,7 @@ void ieee80211_if_set_type(struct net_de
/* Must be called with rtnl lock held. */
void ieee80211_if_reinit(struct net_device *dev)
{
- struct ieee80211_local *local = dev->priv;
+ struct ieee80211_local *local = dev->ieee80211_ptr;
struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
struct sta_info *sta;
int i;
@@ -316,7 +316,7 @@ void __ieee80211_if_del(struct ieee80211
/* Must be called with rtnl lock held. */
int ieee80211_if_remove(struct net_device *dev, const char *name, int id)
{
- struct ieee80211_local *local = dev->priv;
+ struct ieee80211_local *local = dev->ieee80211_ptr;
struct ieee80211_sub_if_data *sdata, *n;
ASSERT_RTNL();
@@ -337,7 +337,7 @@ int ieee80211_if_remove(struct net_devic
void ieee80211_if_free(struct net_device *dev)
{
- struct ieee80211_local *local = dev->priv;
+ struct ieee80211_local *local = dev->ieee80211_ptr;
BUG_ON(dev == local->mdev || dev == local->apdev);
free_netdev(dev);
@@ -346,7 +346,7 @@ void ieee80211_if_free(struct net_device
/* Must be called with rtnl lock held. */
void ieee80211_if_flush(struct net_device *dev)
{
- struct ieee80211_local *local = dev->priv;
+ struct ieee80211_local *local = dev->ieee80211_ptr;
struct ieee80211_sub_if_data *sdata, *n;
ASSERT_RTNL();
@@ -357,7 +357,7 @@ void ieee80211_if_flush(struct net_devic
void ieee80211_if_del(struct net_device *dev)
{
- struct ieee80211_local *local = dev->priv;
+ struct ieee80211_local *local = dev->ieee80211_ptr;
struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
rtnl_lock();
diff --git a/net/d80211/ieee80211_ioctl.c b/net/d80211/ieee80211_ioctl.c
index 30dfc76..8d593e8 100644
--- a/net/d80211/ieee80211_ioctl.c
+++ b/net/d80211/ieee80211_ioctl.c
@@ -118,7 +118,7 @@ static int ieee80211_ioctl_get_hw_featur
struct prism2_hostapd_param *param,
int param_len)
{
- struct ieee80211_local *local = dev->priv;
+ struct ieee80211_local *local = dev->ieee80211_ptr;
u8 *pos = param->u.hw_features.data;
int left = param_len - (pos - (u8 *) param);
int mode, i;
@@ -169,7 +169,7 @@ static int ieee80211_ioctl_get_hw_featur
static int ieee80211_ioctl_scan(struct net_device *dev,
struct prism2_hostapd_param *param)
{
- struct ieee80211_local *local = dev->priv;
+ struct ieee80211_local *local = dev->ieee80211_ptr;
if (local->hw->passive_scan == NULL)
return -EOPNOTSUPP;
@@ -209,7 +209,7 @@ static int ieee80211_ioctl_scan(struct n
static int ieee80211_ioctl_flush(struct net_device *dev,
struct prism2_hostapd_param *param)
{
- struct ieee80211_local *local = dev->priv;
+ struct ieee80211_local *local = dev->ieee80211_ptr;
sta_info_flush(local, NULL);
return 0;
}
@@ -218,7 +218,7 @@ static int ieee80211_ioctl_flush(struct
static int ieee80211_ioctl_add_sta(struct net_device *dev,
struct prism2_hostapd_param *param)
{
- struct ieee80211_local *local = dev->priv;
+ struct ieee80211_local *local = dev->ieee80211_ptr;
struct sta_info *sta;
u32 rates;
int i, j;
@@ -303,7 +303,7 @@ static int ieee80211_ioctl_add_sta(struc
static int ieee80211_ioctl_remove_sta(struct net_device *dev,
struct prism2_hostapd_param *param)
{
- struct ieee80211_local *local = dev->priv;
+ struct ieee80211_local *local = dev->ieee80211_ptr;
struct sta_info *sta;
sta = sta_info_get(local, param->sta_addr);
@@ -319,7 +319,7 @@ static int ieee80211_ioctl_remove_sta(st
static int ieee80211_ioctl_get_dot11counterstable(struct net_device *dev,
struct prism2_hostapd_param *param)
{
- struct ieee80211_local *local = dev->priv;
+ struct ieee80211_local *local = dev->ieee80211_ptr;
struct ieee80211_low_level_stats stats;
memset(&stats, 0, sizeof(stats));
@@ -351,7 +351,7 @@ static int ieee80211_ioctl_get_dot11coun
static int ieee80211_ioctl_get_info_sta(struct net_device *dev,
struct prism2_hostapd_param *param)
{
- struct ieee80211_local *local = dev->priv;
+ struct ieee80211_local *local = dev->ieee80211_ptr;
struct sta_info *sta;
if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
@@ -402,7 +402,7 @@ static int ieee80211_ioctl_get_info_sta(
static int ieee80211_ioctl_set_flags_sta(struct net_device *dev,
struct prism2_hostapd_param *param)
{
- struct ieee80211_local *local = dev->priv;
+ struct ieee80211_local *local = dev->ieee80211_ptr;
struct sta_info *sta;
sta = sta_info_get(local, param->sta_addr);
@@ -433,7 +433,7 @@ int ieee80211_set_hw_encryption(struct n
struct ieee80211_key *key)
{
struct ieee80211_key_conf *keyconf = NULL;
- struct ieee80211_local *local = dev->priv;
+ struct ieee80211_local *local = dev->ieee80211_ptr;
int rc = 0;
/* default to sw encryption; this will be cleared by low-level
@@ -467,7 +467,7 @@ static int ieee80211_set_encryption(stru
int idx, int alg, int set_tx_key, int *err,
const u8 *_key, size_t key_len)
{
- struct ieee80211_local *local = dev->priv;
+ struct ieee80211_local *local = dev->ieee80211_ptr;
int ret = 0;
struct sta_info *sta;
struct ieee80211_key **key;
@@ -706,7 +706,7 @@ static int ieee80211_ioctl_get_encryptio
struct prism2_hostapd_param *param,
int param_len)
{
- struct ieee80211_local *local = dev->priv;
+ struct ieee80211_local *local = dev->ieee80211_ptr;
int ret = 0;
struct sta_info *sta;
struct ieee80211_key **key;
@@ -823,7 +823,7 @@ #ifdef CONFIG_HOSTAPD_WPA_TESTING
static int ieee80211_ioctl_wpa_trigger(struct net_device *dev,
struct prism2_hostapd_param *param)
{
- struct ieee80211_local *local = dev->priv;
+ struct ieee80211_local *local = dev->ieee80211_ptr;
struct sta_info *sta;
if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
@@ -852,7 +852,7 @@ static int ieee80211_ioctl_set_rate_sets
struct prism2_hostapd_param *param,
int param_len)
{
- struct ieee80211_local *local = dev->priv;
+ struct ieee80211_local *local = dev->ieee80211_ptr;
u16 *pos = (u16 *) param->u.set_rate_sets.data;
int left = param_len - ((u8 *) pos - (u8 *) param);
int i, mode, num_supp, num_basic, *supp, *basic, *prev;
@@ -937,7 +937,7 @@ static int ieee80211_ioctl_add_if(struct
ieee80211_if_set_type(new_dev, IEEE80211_IF_TYPE_WDS);
res = ieee80211_if_update_wds(new_dev, wds->remote_addr);
if (res)
- __ieee80211_if_del(dev->priv,
+ __ieee80211_if_del(dev->ieee80211_ptr,
IEEE80211_DEV_TO_SUB_IF(new_dev));
return res;
} else if (param->u.if_info.type == HOSTAP_IF_VLAN) {
@@ -951,7 +951,7 @@ static int ieee80211_ioctl_add_if(struct
#if 0
res = ieee80211_if_update_vlan(new_dev, vlan->id);
if (res)
- __ieee80211_if_del(dev->priv,
+ __ieee80211_if_del(dev->ieee80211_ptr,
IEEE80211_DEV_TO_SUB_IF(new_dev));
#endif
return res;
@@ -1013,7 +1013,7 @@ static int ieee80211_ioctl_update_if(str
if (param->u.if_info.type == HOSTAP_IF_WDS) {
struct hostapd_if_wds *wds =
(struct hostapd_if_wds *) param->u.if_info.data;
- struct ieee80211_local *local = dev->priv;
+ struct ieee80211_local *local = dev->ieee80211_ptr;
struct net_device *wds_dev = NULL;
struct ieee80211_sub_if_data *sdata;
@@ -1050,7 +1050,7 @@ static int ieee80211_ioctl_scan_req(stru
struct prism2_hostapd_param *param,
int param_len)
{
- struct ieee80211_local *local = dev->priv;
+ struct ieee80211_local *local = dev->ieee80211_ptr;
u8 *pos = param->u.scan_req.ssid;
int left = param_len - ((u8 *) pos - (u8 *) param);
int len = param->u.scan_req.ssid_len;
@@ -1082,7 +1082,7 @@ static int ieee80211_ioctl_sta_get_state
static int ieee80211_ioctl_mlme(struct net_device *dev,
struct prism2_hostapd_param *param)
{
- struct ieee80211_local *local = dev->priv;
+ struct ieee80211_local *local = dev->ieee80211_ptr;
struct ieee80211_sub_if_data *sdata;
if (local->user_space_mlme)
@@ -1105,7 +1105,7 @@ static int ieee80211_ioctl_mlme(struct n
static int ieee80211_ioctl_get_load_stats(struct net_device *dev,
struct prism2_hostapd_param *param)
{
- struct ieee80211_local *local = dev->priv;
+ struct ieee80211_local *local = dev->ieee80211_ptr;
param->u.get_load_stats.channel_use = local->channel_use;
/* if (param->u.get_load_stats.flags & LOAD_STATS_CLEAR)
@@ -1118,7 +1118,7 @@ static int ieee80211_ioctl_get_load_stat
static int ieee80211_ioctl_set_sta_vlan(struct net_device *dev,
struct prism2_hostapd_param *param)
{
- struct ieee80211_local *local = dev->priv;
+ struct ieee80211_local *local = dev->ieee80211_ptr;
struct sta_info *sta;
sta = sta_info_get(local, param->sta_addr);
@@ -1146,7 +1146,7 @@ #endif
static int ieee80211_set_gen_ie(struct net_device *dev, u8 *ie, size_t len)
{
struct ieee80211_sub_if_data *sdata;
- struct ieee80211_local *local = dev->priv;
+ struct ieee80211_local *local = dev->ieee80211_ptr;
if (local->user_space_mlme)
return -EOPNOTSUPP;
@@ -1206,7 +1206,7 @@ static int
ieee80211_ioctl_set_tx_queue_params(struct net_device *dev,
struct prism2_hostapd_param *param)
{
- struct ieee80211_local *local = dev->priv;
+ struct ieee80211_local *local = dev->ieee80211_ptr;
struct ieee80211_tx_queue_params qparam;
if (!local->hw->conf_tx) {
@@ -1229,7 +1229,7 @@ ieee80211_ioctl_set_tx_queue_params(stru
static int ieee80211_ioctl_get_tx_stats(struct net_device *dev,
struct prism2_hostapd_param *param)
{
- struct ieee80211_local *local = dev->priv;
+ struct ieee80211_local *local = dev->ieee80211_ptr;
struct ieee80211_tx_queue_stats stats;
int ret, i;
@@ -1254,7 +1254,7 @@ static int ieee80211_ioctl_get_tx_stats(
static int ieee80211_ioctl_set_channel_flag(struct net_device *dev,
struct prism2_hostapd_param *param)
{
- struct ieee80211_local *local = dev->priv;
+ struct ieee80211_local *local = dev->ieee80211_ptr;
struct ieee80211_hw_modes *mode = NULL;
struct ieee80211_channel *chan = NULL;
int i;
@@ -1445,7 +1445,7 @@ static int ieee80211_ioctl_giwname(struc
struct iw_request_info *info,
char *name, char *extra)
{
- struct ieee80211_local *local = dev->priv;
+ struct ieee80211_local *local = dev->ieee80211_ptr;
switch (local->conf.phymode) {
case MODE_IEEE80211A:
@@ -1589,7 +1589,7 @@ static void ieee80211_unmask_channel(str
static int ieee80211_unmask_channels(struct net_device *dev)
{
- struct ieee80211_local *local = dev->priv;
+ struct ieee80211_local *local = dev->ieee80211_ptr;
int m, c;
for (m = 0; m < local->hw->num_modes; m++) {
@@ -1690,7 +1690,7 @@ int ieee80211_ioctl_siwfreq(struct net_d
struct iw_request_info *info,
struct iw_freq *freq, char *extra)
{
- struct ieee80211_local *local = dev->priv;
+ struct ieee80211_local *local = dev->ieee80211_ptr;
int m, c, nfreq, set = 0;
/* freq->e == 0: freq->m = channel; otherwise freq = m * 10^e */
@@ -1743,7 +1743,7 @@ static int ieee80211_ioctl_giwfreq(struc
struct iw_request_info *info,
struct iw_freq *freq, char *extra)
{
- struct ieee80211_local *local = dev->priv;
+ struct ieee80211_local *local = dev->ieee80211_ptr;
/* TODO: in station mode (Managed/Ad-hoc) might need to poll low-level
* driver for the current channel with firmware-based management */
@@ -1759,7 +1759,7 @@ static int ieee80211_ioctl_siwessid(stru
struct iw_request_info *info,
struct iw_point *data, char *ssid)
{
- struct ieee80211_local *local = dev->priv;
+ struct ieee80211_local *local = dev->ieee80211_ptr;
struct ieee80211_sub_if_data *sdata;
size_t len = data->length;
@@ -1827,7 +1827,7 @@ static int ieee80211_ioctl_siwap(struct
struct iw_request_info *info,
struct sockaddr *ap_addr, char *extra)
{
- struct ieee80211_local *local = dev->priv;
+ struct ieee80211_local *local = dev->ieee80211_ptr;
struct ieee80211_sub_if_data *sdata;
sdata = IEEE80211_DEV_TO_SUB_IF(dev);
@@ -1876,7 +1876,7 @@ static int ieee80211_ioctl_siwscan(struc
struct iw_request_info *info,
struct iw_point *data, char *extra)
{
- struct ieee80211_local *local = dev->priv;
+ struct ieee80211_local *local = dev->ieee80211_ptr;
struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
u8 *ssid = NULL;
size_t ssid_len = 0;
@@ -1901,7 +1901,7 @@ static int ieee80211_ioctl_giwscan(struc
struct iw_point *data, char *extra)
{
int res;
- struct ieee80211_local *local = dev->priv;
+ struct ieee80211_local *local = dev->ieee80211_ptr;
if (local->sta_scanning)
return -EAGAIN;
res = ieee80211_sta_scan_results(dev, extra, IW_SCAN_MAX_DATA);
@@ -1918,7 +1918,7 @@ static int ieee80211_ioctl_siwrts(struct
struct iw_request_info *info,
struct iw_param *rts, char *extra)
{
- struct ieee80211_local *local = dev->priv;
+ struct ieee80211_local *local = dev->ieee80211_ptr;
if (rts->disabled)
local->rts_threshold = IEEE80211_MAX_RTS_THRESHOLD;
@@ -1941,7 +1941,7 @@ static int ieee80211_ioctl_giwrts(struct
struct iw_request_info *info,
struct iw_param *rts, char *extra)
{
- struct ieee80211_local *local = dev->priv;
+ struct ieee80211_local *local = dev->ieee80211_ptr;
rts->value = local->rts_threshold;
rts->disabled = (rts->value >= IEEE80211_MAX_RTS_THRESHOLD);
@@ -1955,7 +1955,7 @@ static int ieee80211_ioctl_siwfrag(struc
struct iw_request_info *info,
struct iw_param *frag, char *extra)
{
- struct ieee80211_local *local = dev->priv;
+ struct ieee80211_local *local = dev->ieee80211_ptr;
if (frag->disabled)
local->fragmentation_threshold = IEEE80211_MAX_FRAG_THRESHOLD;
@@ -1982,7 +1982,7 @@ static int ieee80211_ioctl_giwfrag(struc
struct iw_request_info *info,
struct iw_param *frag, char *extra)
{
- struct ieee80211_local *local = dev->priv;
+ struct ieee80211_local *local = dev->ieee80211_ptr;
frag->value = local->fragmentation_threshold;
frag->disabled = (frag->value >= IEEE80211_MAX_RTS_THRESHOLD);
@@ -1996,7 +1996,7 @@ static int ieee80211_ioctl_siwretry(stru
struct iw_request_info *info,
struct iw_param *retry, char *extra)
{
- struct ieee80211_local *local = dev->priv;
+ struct ieee80211_local *local = dev->ieee80211_ptr;
if (retry->disabled ||
(retry->flags & IW_RETRY_TYPE) != IW_RETRY_LIMIT)
@@ -2025,7 +2025,7 @@ static int ieee80211_ioctl_giwretry(stru
struct iw_request_info *info,
struct iw_param *retry, char *extra)
{
- struct ieee80211_local *local = dev->priv;
+ struct ieee80211_local *local = dev->ieee80211_ptr;
retry->disabled = 0;
if ((retry->flags & IW_RETRY_TYPE) != IW_RETRY_LIMIT)
@@ -2060,7 +2060,7 @@ static void ieee80211_ioctl_unmask_chann
static int ieee80211_ioctl_test_mode(struct net_device *dev, int mode)
{
- struct ieee80211_local *local = dev->priv;
+ struct ieee80211_local *local = dev->ieee80211_ptr;
int ret = -EOPNOTSUPP;
if (mode == IEEE80211_TEST_UNMASK_CHANNELS) {
@@ -2077,7 +2077,7 @@ static int ieee80211_ioctl_test_mode(str
static int ieee80211_ioctl_clear_keys(struct net_device *dev)
{
- struct ieee80211_local *local = dev->priv;
+ struct ieee80211_local *local = dev->ieee80211_ptr;
struct ieee80211_key_conf key;
struct list_head *ptr;
int i;
@@ -2138,7 +2138,7 @@ ieee80211_ioctl_force_unicast_rate(struc
struct ieee80211_sub_if_data *sdata,
int rate)
{
- struct ieee80211_local *local = dev->priv;
+ struct ieee80211_local *local = dev->ieee80211_ptr;
int i;
if (sdata->type != IEEE80211_IF_TYPE_AP)
@@ -2164,7 +2164,7 @@ ieee80211_ioctl_max_ratectrl_rate(struct
struct ieee80211_sub_if_data *sdata,
int rate)
{
- struct ieee80211_local *local = dev->priv;
+ struct ieee80211_local *local = dev->ieee80211_ptr;
int i;
if (sdata->type != IEEE80211_IF_TYPE_AP)
@@ -2254,7 +2254,7 @@ static int ieee80211_ioctl_prism2_param(
struct iw_request_info *info,
void *wrqu, char *extra)
{
- struct ieee80211_local *local = dev->priv;
+ struct ieee80211_local *local = dev->ieee80211_ptr;
struct ieee80211_sub_if_data *sdata;
int *i = (int *) extra;
int param = *i;
@@ -2524,7 +2524,7 @@ static int ieee80211_ioctl_get_prism2_pa
struct iw_request_info *info,
void *wrqu, char *extra)
{
- struct ieee80211_local *local = dev->priv;
+ struct ieee80211_local *local = dev->ieee80211_ptr;
struct ieee80211_sub_if_data *sdata;
int *param = (int *) extra;
int ret = 0;
@@ -2716,7 +2716,7 @@ static int ieee80211_ioctl_test_param(st
struct iw_request_info *info,
void *wrqu, char *extra)
{
- struct ieee80211_local *local = dev->priv;
+ struct ieee80211_local *local = dev->ieee80211_ptr;
int *i = (int *) extra;
int param = *i;
int value = *(i + 1);
@@ -2849,7 +2849,7 @@ static int ieee80211_ioctl_siwauth(struc
struct iw_request_info *info,
struct iw_param *data, char *extra)
{
- struct ieee80211_local *local = dev->priv;
+ struct ieee80211_local *local = dev->ieee80211_ptr;
struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
int ret = 0;
diff --git a/net/d80211/ieee80211_proc.c b/net/d80211/ieee80211_proc.c
index c9f5567..4f3a6b9 100644
--- a/net/d80211/ieee80211_proc.c
+++ b/net/d80211/ieee80211_proc.c
@@ -269,7 +269,7 @@ static int ieee80211_proc_sta_read(char
sta->tx_fragments, sta->tx_filtered_count);
p = ieee80211_proc_key(p, sta->key, 0, 1);
- local = (struct ieee80211_local *) sta->dev->priv;
+ local = (struct ieee80211_local *) sta->dev->ieee80211_ptr;
if (sta->txrate >= 0 && sta->txrate < local->num_curr_rates) {
p += sprintf(p, "txrate=%d\n",
local->curr_rates[sta->txrate].rate);
@@ -676,7 +676,7 @@ void ieee80211_proc_deinit_sta(struct ie
void ieee80211_proc_init_virtual(struct net_device *dev)
{
struct proc_dir_entry *entry;
- struct ieee80211_local *local = (struct ieee80211_local *) dev->priv;
+ struct ieee80211_local *local = dev->ieee80211_ptr;
if (!local->proc_iface)
return;
@@ -690,7 +690,7 @@ void ieee80211_proc_init_virtual(struct
void ieee80211_proc_deinit_virtual(struct net_device *dev)
{
- struct ieee80211_local *local = (struct ieee80211_local *) dev->priv;
+ struct ieee80211_local *local = dev->ieee80211_ptr;
if (local->proc_iface)
remove_proc_entry(dev->name, local->proc_iface);
diff --git a/net/d80211/ieee80211_scan.c b/net/d80211/ieee80211_scan.c
index 9984fd6..4184abf 100644
--- a/net/d80211/ieee80211_scan.c
+++ b/net/d80211/ieee80211_scan.c
@@ -110,7 +110,7 @@ static void next_chan_all_modes(struct i
static void ieee80211_scan_start(struct net_device *dev,
struct ieee80211_scan_conf *conf)
{
- struct ieee80211_local *local = dev->priv;
+ struct ieee80211_local *local = dev->ieee80211_ptr;
int old_mode_idx = local->scan.mode_idx;
int old_chan_idx = local->scan.chan_idx;
struct ieee80211_hw_modes *mode = NULL;
@@ -209,7 +209,7 @@ #endif
static void ieee80211_scan_stop(struct net_device *dev,
struct ieee80211_scan_conf *conf)
{
- struct ieee80211_local *local = dev->priv;
+ struct ieee80211_local *local = dev->ieee80211_ptr;
struct ieee80211_hw_modes *mode;
struct ieee80211_channel *chan;
int wait;
@@ -258,7 +258,7 @@ #endif /* CONFIG_D80211_VERBOSE_DEBUG */
static void ieee80211_scan_handler(unsigned long uldev)
{
struct net_device *dev = (struct net_device *) uldev;
- struct ieee80211_local *local = dev->priv;
+ struct ieee80211_local *local = dev->ieee80211_ptr;
struct ieee80211_scan_conf conf;
if (local->scan.interval == 0 && !local->scan.in_scan) {
@@ -286,7 +286,7 @@ static void ieee80211_scan_handler(unsig
void ieee80211_init_scan(struct net_device *dev)
{
- struct ieee80211_local *local = dev->priv;
+ struct ieee80211_local *local = dev->ieee80211_ptr;
struct ieee80211_hdr hdr;
u16 fc;
int len = 10;
@@ -342,7 +342,7 @@ void ieee80211_init_scan(struct net_devi
void ieee80211_stop_scan(struct net_device *dev)
{
- struct ieee80211_local *local = dev->priv;
+ struct ieee80211_local *local = dev->ieee80211_ptr;
if (local->hw->passive_scan != 0) {
del_timer_sync(&local->scan.timer);
diff --git a/net/d80211/ieee80211_sta.c b/net/d80211/ieee80211_sta.c
index af58013..66a4575 100644
--- a/net/d80211/ieee80211_sta.c
+++ b/net/d80211/ieee80211_sta.c
@@ -234,7 +234,7 @@ static void ieee80211_sta_wmm_params(str
struct ieee80211_if_sta *ifsta,
u8 *wmm_param, size_t wmm_param_len)
{
- struct ieee80211_local *local = dev->priv;
+ struct ieee80211_local *local = dev->ieee80211_ptr;
struct ieee80211_tx_queue_params params;
size_t left;
int count;
@@ -468,7 +468,7 @@ static void ieee80211_authenticate(struc
static void ieee80211_send_assoc(struct net_device *dev,
struct ieee80211_if_sta *ifsta)
{
- struct ieee80211_local *local = dev->priv;
+ struct ieee80211_local *local = dev->ieee80211_ptr;
struct sk_buff *skb;
struct ieee80211_mgmt *mgmt;
u8 *pos, *ies;
@@ -688,7 +688,7 @@ static void ieee80211_associate(struct n
static void ieee80211_associated(struct net_device *dev,
struct ieee80211_if_sta *ifsta)
{
- struct ieee80211_local *local = dev->priv;
+ struct ieee80211_local *local = dev->ieee80211_ptr;
struct sta_info *sta;
int disassoc;
@@ -749,7 +749,7 @@ static void ieee80211_associated(struct
static void ieee80211_send_probe_req(struct net_device *dev, u8 *dst,
u8 *ssid, size_t ssid_len)
{
- struct ieee80211_local *local = dev->priv;
+ struct ieee80211_local *local = dev->ieee80211_ptr;
struct sk_buff *skb;
struct ieee80211_mgmt *mgmt;
u8 *pos, *supp_rates, *esupp_rates = NULL;
@@ -1079,7 +1079,7 @@ static void ieee80211_rx_mgmt_assoc_resp
struct ieee80211_rx_status *rx_status,
int reassoc)
{
- struct ieee80211_local *local = dev->priv;
+ struct ieee80211_local *local = dev->ieee80211_ptr;
struct sta_info *sta;
u32 rates;
u16 capab_info, status_code, aid;
@@ -1210,7 +1210,7 @@ static void ieee80211_rx_mgmt_assoc_resp
static void __ieee80211_rx_bss_hash_add(struct net_device *dev,
struct ieee80211_sta_bss *bss)
{
- struct ieee80211_local *local = dev->priv;
+ struct ieee80211_local *local = dev->ieee80211_ptr;
bss->hnext = local->sta_bss_hash[STA_HASH(bss->bssid)];
local->sta_bss_hash[STA_HASH(bss->bssid)] = bss;
}
@@ -1220,7 +1220,7 @@ static void __ieee80211_rx_bss_hash_add(
static void __ieee80211_rx_bss_hash_del(struct net_device *dev,
struct ieee80211_sta_bss *bss)
{
- struct ieee80211_local *local = dev->priv;
+ struct ieee80211_local *local = dev->ieee80211_ptr;
struct ieee80211_sta_bss *b, *prev = NULL;
b = local->sta_bss_hash[STA_HASH(bss->bssid)];
while (b) {
@@ -1242,7 +1242,7 @@ static void __ieee80211_rx_bss_hash_del(
static struct ieee80211_sta_bss *
ieee80211_rx_bss_add(struct net_device *dev, u8 *bssid)
{
- struct ieee80211_local *local = dev->priv;
+ struct ieee80211_local *local = dev->ieee80211_ptr;
struct ieee80211_sta_bss *bss;
bss = kmalloc(sizeof(*bss), GFP_ATOMIC);
@@ -1265,7 +1265,7 @@ ieee80211_rx_bss_add(struct net_device *
static struct ieee80211_sta_bss *
ieee80211_rx_bss_get(struct net_device *dev, u8 *bssid)
{
- struct ieee80211_local *local = dev->priv;
+ struct ieee80211_local *local = dev->ieee80211_ptr;
struct ieee80211_sta_bss *bss;
spin_lock_bh(&local->sta_bss_lock);
@@ -1294,7 +1294,7 @@ static void ieee80211_rx_bss_free(struct
static void ieee80211_rx_bss_put(struct net_device *dev,
struct ieee80211_sta_bss *bss)
{
- struct ieee80211_local *local = dev->priv;
+ struct ieee80211_local *local = dev->ieee80211_ptr;
if (!atomic_dec_and_test(&bss->users))
return;
@@ -1308,7 +1308,7 @@ static void ieee80211_rx_bss_put(struct
void ieee80211_rx_bss_list_init(struct net_device *dev)
{
- struct ieee80211_local *local = dev->priv;
+ struct ieee80211_local *local = dev->ieee80211_ptr;
spin_lock_init(&local->sta_bss_lock);
INIT_LIST_HEAD(&local->sta_bss_list);
}
@@ -1316,7 +1316,7 @@ void ieee80211_rx_bss_list_init(struct n
void ieee80211_rx_bss_list_deinit(struct net_device *dev)
{
- struct ieee80211_local *local = dev->priv;
+ struct ieee80211_local *local = dev->ieee80211_ptr;
struct ieee80211_sta_bss *bss;
struct list_head *ptr;
@@ -1336,7 +1336,7 @@ static void ieee80211_rx_bss_info(struct
struct ieee80211_rx_status *rx_status,
int beacon)
{
- struct ieee80211_local *local = dev->priv;
+ struct ieee80211_local *local = dev->ieee80211_ptr;
struct ieee802_11_elems elems;
size_t baselen;
int channel, invalid = 0, clen;
@@ -1587,7 +1587,7 @@ static void ieee80211_rx_mgmt_beacon(str
size_t len,
struct ieee80211_rx_status *rx_status)
{
- struct ieee80211_local *local = dev->priv;
+ struct ieee80211_local *local = dev->ieee80211_ptr;
struct ieee80211_sub_if_data *sdata;
struct ieee80211_if_sta *ifsta;
int use_protection;
@@ -1645,7 +1645,7 @@ static void ieee80211_rx_mgmt_probe_req(
size_t len,
struct ieee80211_rx_status *rx_status)
{
- struct ieee80211_local *local = dev->priv;
+ struct ieee80211_local *local = dev->ieee80211_ptr;
struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
int tx_last_beacon;
struct sk_buff *skb;
@@ -1802,7 +1802,7 @@ void ieee80211_sta_rx_scan(struct net_de
static int ieee80211_sta_active_ibss(struct net_device *dev)
{
- struct ieee80211_local *local = dev->priv;
+ struct ieee80211_local *local = dev->ieee80211_ptr;
struct list_head *ptr;
int active = 0;
struct sta_info *sta;
@@ -1825,7 +1825,7 @@ static int ieee80211_sta_active_ibss(str
static void ieee80211_sta_expire(struct net_device *dev)
{
- struct ieee80211_local *local = dev->priv;
+ struct ieee80211_local *local = dev->ieee80211_ptr;
struct list_head *ptr, *n;
struct sta_info *sta;
@@ -1911,7 +1911,7 @@ void ieee80211_sta_timer(unsigned long p
static void ieee80211_sta_new_auth(struct net_device *dev,
struct ieee80211_if_sta *ifsta)
{
- struct ieee80211_local *local = dev->priv;
+ struct ieee80211_local *local = dev->ieee80211_ptr;
struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
if (sdata->type != IEEE80211_IF_TYPE_STA)
@@ -1972,7 +1972,7 @@ static int ieee80211_sta_join_ibss(struc
struct ieee80211_if_sta *ifsta,
struct ieee80211_sta_bss *bss)
{
- struct ieee80211_local *local = dev->priv;
+ struct ieee80211_local *local = dev->ieee80211_ptr;
struct iw_freq rq;
int res, rates, i, j;
struct sk_buff *skb;
@@ -2132,7 +2132,7 @@ static int ieee80211_sta_join_ibss(struc
static int ieee80211_sta_create_ibss(struct net_device *dev,
struct ieee80211_if_sta *ifsta)
{
- struct ieee80211_local *local = dev->priv;
+ struct ieee80211_local *local = dev->ieee80211_ptr;
struct ieee80211_sta_bss *bss;
struct ieee80211_sub_if_data *sdata;
u8 bssid[ETH_ALEN], *pos;
@@ -2189,7 +2189,7 @@ #endif
static int ieee80211_sta_find_ibss(struct net_device *dev,
struct ieee80211_if_sta *ifsta)
{
- struct ieee80211_local *local = dev->priv;
+ struct ieee80211_local *local = dev->ieee80211_ptr;
struct ieee80211_sta_bss *bss;
int found = 0;
u8 bssid[ETH_ALEN];
@@ -2281,7 +2281,7 @@ int ieee80211_sta_set_ssid(struct net_de
{
struct ieee80211_sub_if_data *sdata;
struct ieee80211_if_sta *ifsta;
- struct ieee80211_local *local = dev->priv;
+ struct ieee80211_local *local = dev->ieee80211_ptr;
if (len > IEEE80211_MAX_SSID_LEN)
return -EINVAL;
@@ -2376,7 +2376,7 @@ int ieee80211_sta_set_bssid(struct net_d
static void ieee80211_sta_save_oper_chan(struct net_device *dev)
{
- struct ieee80211_local *local = dev->priv;
+ struct ieee80211_local *local = dev->ieee80211_ptr;
local->scan_oper_channel = local->conf.channel;
local->scan_oper_channel_val = local->conf.channel_val;
local->scan_oper_power_level = local->conf.power_level;
@@ -2388,7 +2388,7 @@ static void ieee80211_sta_save_oper_chan
static int ieee80211_sta_restore_oper_chan(struct net_device *dev)
{
- struct ieee80211_local *local = dev->priv;
+ struct ieee80211_local *local = dev->ieee80211_ptr;
local->conf.channel = local->scan_oper_channel;
local->conf.channel_val = local->scan_oper_channel_val;
local->conf.power_level = local->scan_oper_power_level;
@@ -2425,7 +2425,7 @@ static int ieee80211_active_scan(struct
static void ieee80211_sta_scan_timer(unsigned long ptr)
{
struct net_device *dev = (struct net_device *) ptr;
- struct ieee80211_local *local = dev->priv;
+ struct ieee80211_local *local = dev->ieee80211_ptr;
struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
struct ieee80211_hw_modes *mode;
struct ieee80211_channel *chan;
@@ -2526,7 +2526,7 @@ #endif
int ieee80211_sta_req_scan(struct net_device *dev, u8 *ssid, size_t ssid_len)
{
- struct ieee80211_local *local = dev->priv;
+ struct ieee80211_local *local = dev->ieee80211_ptr;
if (ssid_len > IEEE80211_MAX_SSID_LEN)
return -EINVAL;
@@ -2584,7 +2584,7 @@ ieee80211_sta_scan_result(struct net_dev
struct ieee80211_sta_bss *bss,
char *current_ev, char *end_buf)
{
- struct ieee80211_local *local = dev->priv;
+ struct ieee80211_local *local = dev->ieee80211_ptr;
struct iw_event iwe;
if (time_after(jiffies,
@@ -2746,7 +2746,7 @@ ieee80211_sta_scan_result(struct net_dev
int ieee80211_sta_scan_results(struct net_device *dev, char *buf, size_t len)
{
- struct ieee80211_local *local = dev->priv;
+ struct ieee80211_local *local = dev->ieee80211_ptr;
struct list_head *ptr;
char *current_ev = buf;
char *end_buf = buf + len;
@@ -2791,7 +2791,7 @@ struct sta_info * ieee80211_ibss_add_sta
struct sk_buff *skb, u8 *bssid,
u8 *addr)
{
- struct ieee80211_local *local = dev->priv;
+ struct ieee80211_local *local = dev->ieee80211_ptr;
struct list_head *ptr;
struct sta_info *sta;
struct ieee80211_sub_if_data *sdata = NULL;
diff --git a/net/d80211/ieee80211_sysfs.c b/net/d80211/ieee80211_sysfs.c
index 5c7af9f..fb95e96 100644
--- a/net/d80211/ieee80211_sysfs.c
+++ b/net/d80211/ieee80211_sysfs.c
@@ -53,6 +53,11 @@ static ssize_t store_remove_iface(struct
return res < 0 ? res : len;
}
+static void ieee80211_class_dev_release(struct class_device *dev)
+{
+ ieee80211_release_hw(to_ieee80211_local(dev));
+}
+
#ifdef CONFIG_HOTPLUG
static int ieee80211_uevent(struct class_device *cd, char **envp,
int num_envp, char *buf, int size)
@@ -79,28 +84,39 @@ static struct class_device_attribute iee
static struct class ieee80211_class = {
.name = "ieee80211",
.class_dev_attrs = ieee80211_class_dev_attrs,
+ .release = ieee80211_class_dev_release,
#ifdef CONFIG_HOTPLUG
.uevent = ieee80211_uevent,
#endif
};
-int ieee80211_register_sysfs(struct ieee80211_local *local)
+void ieee80211_dev_sysfs_init(struct ieee80211_local *local)
{
local->class_dev.class = &ieee80211_class;
local->class_dev.class_data = local;
+ class_device_initialize(&local->class_dev);
+}
+
+void ieee80211_dev_sysfs_put(struct ieee80211_local *local)
+{
+ class_device_put(&local->class_dev);
+}
+
+int ieee80211_dev_sysfs_add(struct ieee80211_local *local)
+{
snprintf(local->class_dev.class_id, BUS_ID_SIZE,
"phy%d", local->dev_index);
- return class_device_register(&local->class_dev);
+ return class_device_add(&local->class_dev);
}
-void ieee80211_unregister_sysfs(struct ieee80211_local *local)
+void ieee80211_dev_sysfs_del(struct ieee80211_local *local)
{
class_device_del(&local->class_dev);
}
int ieee80211_sysfs_add_netdevice(struct net_device *dev)
{
- struct ieee80211_local *local = dev->priv;
+ struct ieee80211_local *local = dev->ieee80211_ptr;
return sysfs_create_link(&dev->class_dev.kobj, &local->class_dev.kobj,
"wiphy");
@@ -108,8 +124,6 @@ int ieee80211_sysfs_add_netdevice(struct
void ieee80211_sysfs_remove_netdevice(struct net_device *dev)
{
- struct ieee80211_local *local = dev->priv;
-
sysfs_remove_link(&dev->class_dev.kobj, "wiphy");
}
diff --git a/net/d80211/rate_control.c b/net/d80211/rate_control.c
index 429ef2b..3485302 100644
--- a/net/d80211/rate_control.c
+++ b/net/d80211/rate_control.c
@@ -126,7 +126,7 @@ static void rate_control_simple_tx_statu
struct sk_buff *skb,
struct ieee80211_tx_status *status)
{
- struct ieee80211_local *local = dev->priv;
+ struct ieee80211_local *local = dev->ieee80211_ptr;
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
struct sta_info *sta;
struct sta_rate_control *srctrl;
@@ -217,7 +217,7 @@ static struct ieee80211_rate *
rate_control_simple_get_rate(struct net_device *dev, struct sk_buff *skb,
struct rate_control_extra *extra)
{
- struct ieee80211_local *local = dev->priv;
+ struct ieee80211_local *local = dev->ieee80211_ptr;
struct ieee80211_sub_if_data *sdata;
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
struct sta_info *sta;
diff --git a/net/d80211/rate_control.h b/net/d80211/rate_control.h
index 26d3c0f..b509539 100644
--- a/net/d80211/rate_control.h
+++ b/net/d80211/rate_control.h
@@ -64,7 +64,7 @@ static inline void rate_control_tx_statu
struct sk_buff *skb,
struct ieee80211_tx_status *status)
{
- struct ieee80211_local *local = dev->priv;
+ struct ieee80211_local *local = dev->ieee80211_ptr;
local->rate_ctrl->tx_status(dev, skb, status);
}
@@ -73,7 +73,7 @@ static inline struct ieee80211_rate *
rate_control_get_rate(struct net_device *dev, struct sk_buff *skb,
struct rate_control_extra *extra)
{
- struct ieee80211_local *local = dev->priv;
+ struct ieee80211_local *local = dev->ieee80211_ptr;
return local->rate_ctrl->get_rate(dev, skb, extra);
}
diff --git a/net/d80211/wme.c b/net/d80211/wme.c
index f20d3e0..138f892 100644
--- a/net/d80211/wme.c
+++ b/net/d80211/wme.c
@@ -175,7 +175,7 @@ static inline int wme_downgrade_ac(struc
* negative return value indicates to drop the frame */
static inline int classify80211(struct sk_buff *skb, struct Qdisc *qd)
{
- struct ieee80211_local *local = qd->dev->priv;
+ struct ieee80211_local *local = qd->dev->ieee80211_ptr;
struct ieee80211_tx_packet_data *pkt_data =
(struct ieee80211_tx_packet_data *) skb->cb;
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
@@ -227,7 +227,7 @@ static inline int classify80211(struct s
static int wme_qdiscop_enqueue(struct sk_buff *skb, struct Qdisc* qd)
{
- struct ieee80211_local *local = qd->dev->priv;
+ struct ieee80211_local *local = qd->dev->ieee80211_ptr;
struct ieee80211_sched_data *q = qdisc_priv(qd);
struct ieee80211_tx_packet_data *pkt_data =
(struct ieee80211_tx_packet_data *) skb->cb;
@@ -314,7 +314,7 @@ static struct sk_buff *wme_qdiscop_deque
{
struct ieee80211_sched_data *q = qdisc_priv(qd);
struct net_device *dev = qd->dev;
- struct ieee80211_local *local = dev->priv;
+ struct ieee80211_local *local = dev->ieee80211_ptr;
struct ieee80211_hw *hw = local->hw;
struct ieee80211_tx_queue_stats stats;
struct sk_buff *skb;
@@ -351,7 +351,7 @@ static struct sk_buff *wme_qdiscop_deque
static void wme_qdiscop_reset(struct Qdisc* qd)
{
struct ieee80211_sched_data *q = qdisc_priv(qd);
- struct ieee80211_local *local = qd->dev->priv;
+ struct ieee80211_local *local = qd->dev->ieee80211_ptr;
struct ieee80211_hw *hw = local->hw;
int queue;
@@ -368,7 +368,7 @@ static void wme_qdiscop_reset(struct Qdi
static void wme_qdiscop_destroy(struct Qdisc* qd)
{
struct ieee80211_sched_data *q = qdisc_priv(qd);
- struct ieee80211_local *local = qd->dev->priv;
+ struct ieee80211_local *local = qd->dev->ieee80211_ptr;
struct ieee80211_hw *hw = local->hw;
struct tcf_proto *tp;
int queue;
@@ -409,7 +409,7 @@ static int wme_qdiscop_init(struct Qdisc
{
struct ieee80211_sched_data *q = qdisc_priv(qd);
struct net_device *dev = qd->dev;
- struct ieee80211_local *local = dev->priv;
+ struct ieee80211_local *local = dev->ieee80211_ptr;
int queues = local->hw->queues;
int err = 0, i;
@@ -464,7 +464,7 @@ static int wme_classop_graft(struct Qdis
struct Qdisc *new, struct Qdisc **old)
{
struct ieee80211_sched_data *q = qdisc_priv(qd);
- struct ieee80211_local *local = qd->dev->priv;
+ struct ieee80211_local *local = qd->dev->ieee80211_ptr;
struct ieee80211_hw *hw = local->hw;
unsigned long queue = arg - 1;
@@ -488,7 +488,7 @@ static struct Qdisc *
wme_classop_leaf(struct Qdisc *qd, unsigned long arg)
{
struct ieee80211_sched_data *q = qdisc_priv(qd);
- struct ieee80211_local *local = qd->dev->priv;
+ struct ieee80211_local *local = qd->dev->ieee80211_ptr;
struct ieee80211_hw *hw = local->hw;
unsigned long queue = arg - 1;
@@ -501,7 +501,7 @@ wme_classop_leaf(struct Qdisc *qd, unsig
static unsigned long wme_classop_get(struct Qdisc *qd, u32 classid)
{
- struct ieee80211_local *local = qd->dev->priv;
+ struct ieee80211_local *local = qd->dev->ieee80211_ptr;
struct ieee80211_hw *hw = local->hw;
unsigned long queue = TC_H_MIN(classid);
@@ -529,7 +529,7 @@ static int wme_classop_change(struct Qdi
struct rtattr **tca, unsigned long *arg)
{
unsigned long cl = *arg;
- struct ieee80211_local *local = qd->dev->priv;
+ struct ieee80211_local *local = qd->dev->ieee80211_ptr;
struct ieee80211_hw *hw = local->hw;
/* printk(KERN_DEBUG "entering %s\n", __func__); */
@@ -547,7 +547,7 @@ static int wme_classop_change(struct Qdi
* when we add WMM-SA support - TSPECs may be deleted here */
static int wme_classop_delete(struct Qdisc *qd, unsigned long cl)
{
- struct ieee80211_local *local = qd->dev->priv;
+ struct ieee80211_local *local = qd->dev->ieee80211_ptr;
struct ieee80211_hw *hw = local->hw;
/* printk(KERN_DEBUG "entering %s\n", __func__); */
@@ -561,7 +561,7 @@ static int wme_classop_dump_class(struct
struct sk_buff *skb, struct tcmsg *tcm)
{
struct ieee80211_sched_data *q = qdisc_priv(qd);
- struct ieee80211_local *local = qd->dev->priv;
+ struct ieee80211_local *local = qd->dev->ieee80211_ptr;
struct ieee80211_hw *hw = local->hw;
/* printk(KERN_DEBUG "entering %s\n", __func__); */
@@ -576,7 +576,7 @@ static int wme_classop_dump_class(struct
static void wme_classop_walk(struct Qdisc *qd, struct qdisc_walker *arg)
{
- struct ieee80211_local *local = qd->dev->priv;
+ struct ieee80211_local *local = qd->dev->ieee80211_ptr;
struct ieee80211_hw *hw = local->hw;
int queue;
/* printk(KERN_DEBUG "entering %s\n", __func__); */
--
1.3.0
^ permalink raw reply related
* [PATCH 5/12] d80211: wiphy sysfs attributes
From: Jiri Benc @ 2006-06-08 7:49 UTC (permalink / raw)
To: netdev; +Cc: John W. Linville
In-Reply-To: <20060608094822.014829000.midnight@suse.cz>
Add /sys/class/ieee80211/phyX/* attributes.
Signed-off-by: Jiri Benc <jbenc@suse.cz>
---
net/d80211/ieee80211_proc.c | 4 -
net/d80211/ieee80211_proc.h | 3
net/d80211/ieee80211_sysfs.c | 304 +++++++++++++++++++++++++++++++++++++++++-
3 files changed, 302 insertions(+), 9 deletions(-)
b049b3afd8db895dd1f6985c1d1051eb733b887b
diff --git a/net/d80211/ieee80211_proc.c b/net/d80211/ieee80211_proc.c
index 4f3a6b9..581b583 100644
--- a/net/d80211/ieee80211_proc.c
+++ b/net/d80211/ieee80211_proc.c
@@ -442,7 +442,7 @@ #endif /* CONFIG_D80211_DEBUG_COUNTERS *
}
-static const char * ieee80211_mode_str_short(int mode)
+const char *ieee80211_mode_str_short(int mode)
{
switch (mode) {
case MODE_IEEE80211A:
@@ -459,7 +459,7 @@ static const char * ieee80211_mode_str_s
}
-static const char * ieee80211_mode_str(int mode)
+const char *ieee80211_mode_str(int mode)
{
switch (mode) {
case MODE_IEEE80211A:
diff --git a/net/d80211/ieee80211_proc.h b/net/d80211/ieee80211_proc.h
index 8c76560..4519d26 100644
--- a/net/d80211/ieee80211_proc.h
+++ b/net/d80211/ieee80211_proc.h
@@ -42,4 +42,7 @@ static inline void ieee80211_proc_init(v
static inline void ieee80211_proc_deinit(void) {}
#endif /* CONFIG_PROC_FS */
+const char *ieee80211_mode_str(int mode);
+const char *ieee80211_mode_str_short(int mode);
+
#endif /* IEEE80211_PROC_H */
diff --git a/net/d80211/ieee80211_sysfs.c b/net/d80211/ieee80211_sysfs.c
index e799506..07a7036 100644
--- a/net/d80211/ieee80211_sysfs.c
+++ b/net/d80211/ieee80211_sysfs.c
@@ -14,6 +14,8 @@ #include <linux/netdevice.h>
#include <linux/rtnetlink.h>
#include <net/d80211.h>
#include "ieee80211_i.h"
+#include "ieee80211_proc.h"
+#include "rate_control.h"
#define to_ieee80211_local(class) container_of(class, struct ieee80211_local, class_dev)
@@ -27,6 +29,8 @@ static inline int rtnl_lock_local(struct
return 0;
}
+/* attributes in /sys/class/ieee80211/phyX/ */
+
static ssize_t store_add_iface(struct class_device *dev,
const char *buf, size_t len)
{
@@ -66,6 +70,284 @@ static ssize_t store_remove_iface(struct
return res < 0 ? res : len;
}
+static ssize_t ieee80211_local_show(struct class_device *dev, char *buf,
+ ssize_t (*format)(struct ieee80211_local *, char *))
+{
+ struct ieee80211_local *local = to_ieee80211_local(dev);
+ ssize_t ret = -EINVAL;
+
+ if (local->reg_state == IEEE80211_DEV_REGISTERED)
+ ret = (*format)(local, buf);
+ return ret;
+}
+
+#define IEEE80211_LOCAL_FMT(name, field, format_string) \
+static ssize_t ieee80211_local_fmt_##name(struct ieee80211_local *local,\
+ char *buf) \
+{ \
+ return sprintf(buf, format_string, local->field); \
+}
+
+#define __IEEE80211_LOCAL_SHOW(name) \
+static ssize_t ieee80211_local_show_##name(struct class_device *cd, \
+ char *buf) \
+{ \
+ return ieee80211_local_show(cd, buf, \
+ ieee80211_local_fmt_##name); \
+}
+
+#define IEEE80211_LOCAL_SHOW(name, field, format) \
+ IEEE80211_LOCAL_FMT(name, field, format "\n") \
+ __IEEE80211_LOCAL_SHOW(name)
+
+IEEE80211_LOCAL_SHOW(channel, conf.channel, "%d");
+IEEE80211_LOCAL_SHOW(frequency, conf.freq, "%d");
+IEEE80211_LOCAL_SHOW(radar_detect, conf.radar_detect, "%d");
+IEEE80211_LOCAL_SHOW(antenna_sel, conf.antenna_sel, "%d");
+IEEE80211_LOCAL_SHOW(calib_int, conf.calib_int, "%d");
+IEEE80211_LOCAL_SHOW(bridge_packets, bridge_packets, "%d");
+IEEE80211_LOCAL_SHOW(key_tx_rx_threshold, key_tx_rx_threshold, "%d");
+IEEE80211_LOCAL_SHOW(rts_threshold, rts_threshold, "%d");
+IEEE80211_LOCAL_SHOW(fragmentation_threshold, fragmentation_threshold, "%d");
+IEEE80211_LOCAL_SHOW(short_retry_limit, short_retry_limit, "%d");
+IEEE80211_LOCAL_SHOW(long_retry_limit, long_retry_limit, "%d");
+IEEE80211_LOCAL_SHOW(total_ps_buffered, total_ps_buffered, "%d");
+
+static ssize_t ieee80211_local_fmt_mode(struct ieee80211_local *local,
+ char *buf)
+{
+ return sprintf(buf, "%s\n", ieee80211_mode_str(local->conf.phymode));
+}
+__IEEE80211_LOCAL_SHOW(mode);
+
+static ssize_t ieee80211_local_fmt_wep_iv(struct ieee80211_local *local,
+ char *buf)
+{
+ return sprintf(buf, "%#06x\n", local->wep_iv & 0xffffff);
+}
+__IEEE80211_LOCAL_SHOW(wep_iv);
+
+static ssize_t ieee80211_local_fmt_tx_power_reduction(struct ieee80211_local
+ *local, char *buf)
+{
+ short tx_power_reduction = local->conf.tx_power_reduction;
+
+ return sprintf(buf, "%d.%d dBm\n", tx_power_reduction / 10,
+ tx_power_reduction % 10);
+}
+__IEEE80211_LOCAL_SHOW(tx_power_reduction);
+
+static ssize_t ieee80211_local_fmt_modes(struct ieee80211_local *local,
+ char *buf)
+{
+ int i;
+ struct ieee80211_hw_modes *mode;
+ char *p = buf;
+
+ /* FIXME: locking against ieee80211_update_hw? */
+ for (i = 0; i < local->hw->num_modes; i++) {
+ mode = &local->hw->modes[i];
+ p += sprintf(p, "%s\n", ieee80211_mode_str_short(mode->mode));
+ }
+ return (p - buf);
+}
+__IEEE80211_LOCAL_SHOW(modes);
+
+static ssize_t ieee80211_local_fmt_rate_ctrl_alg(struct ieee80211_local *local,
+ char *buf)
+{
+ if (local->rate_ctrl && local->rate_ctrl_priv)
+ return sprintf(buf, "%s\n", local->rate_ctrl->name);
+ return 0;
+}
+__IEEE80211_LOCAL_SHOW(rate_ctrl_alg);
+
+static struct class_device_attribute ieee80211_class_dev_attrs[] = {
+ __ATTR(add_iface, S_IWUSR, NULL, store_add_iface),
+ __ATTR(remove_iface, S_IWUSR, NULL, store_remove_iface),
+ __ATTR(channel, S_IRUGO, ieee80211_local_show_channel, NULL),
+ __ATTR(frequency, S_IRUGO, ieee80211_local_show_frequency, NULL),
+ __ATTR(radar_detect, S_IRUGO, ieee80211_local_show_radar_detect, NULL),
+ __ATTR(antenna_sel, S_IRUGO, ieee80211_local_show_antenna_sel, NULL),
+ __ATTR(calib_int, S_IRUGO, ieee80211_local_show_calib_int, NULL),
+ __ATTR(bridge_packets, S_IRUGO, ieee80211_local_show_bridge_packets, NULL),
+ __ATTR(key_tx_rx_threshold, S_IRUGO, ieee80211_local_show_key_tx_rx_threshold, NULL),
+ __ATTR(rts_threshold, S_IRUGO, ieee80211_local_show_rts_threshold, NULL),
+ __ATTR(fragmentation_threshold, S_IRUGO, ieee80211_local_show_fragmentation_threshold, NULL),
+ __ATTR(short_retry_limit, S_IRUGO, ieee80211_local_show_short_retry_limit, NULL),
+ __ATTR(long_retry_limit, S_IRUGO, ieee80211_local_show_long_retry_limit, NULL),
+ __ATTR(total_ps_buffered, S_IRUGO, ieee80211_local_show_total_ps_buffered, NULL),
+ __ATTR(mode, S_IRUGO, ieee80211_local_show_mode, NULL),
+ __ATTR(wep_iv, S_IRUGO, ieee80211_local_show_wep_iv, NULL),
+ __ATTR(tx_power_reduction, S_IRUGO, ieee80211_local_show_tx_power_reduction, NULL),
+ __ATTR(modes, S_IRUGO, ieee80211_local_show_modes, NULL),
+ __ATTR(rate_ctrl_alg, S_IRUGO, ieee80211_local_show_rate_ctrl_alg, NULL),
+ {}
+};
+
+/* attributes in /sys/class/ieee80211/phyX/statistics/ */
+
+#define IEEE80211_LOCAL_ATTR(name, field, format) \
+IEEE80211_LOCAL_SHOW(name, field, format) \
+static CLASS_DEVICE_ATTR(name, S_IRUGO, ieee80211_local_show_##name, NULL);
+
+IEEE80211_LOCAL_ATTR(transmitted_fragment_count, dot11TransmittedFragmentCount, "%u");
+IEEE80211_LOCAL_ATTR(multicast_transmitted_frame_count, dot11MulticastTransmittedFrameCount, "%u");
+IEEE80211_LOCAL_ATTR(failed_count, dot11FailedCount, "%u");
+IEEE80211_LOCAL_ATTR(retry_count, dot11RetryCount, "%u");
+IEEE80211_LOCAL_ATTR(multiple_retry_count, dot11MultipleRetryCount, "%u");
+IEEE80211_LOCAL_ATTR(frame_duplicate_count, dot11FrameDuplicateCount, "%u");
+IEEE80211_LOCAL_ATTR(received_fragment_count, dot11ReceivedFragmentCount, "%u");
+IEEE80211_LOCAL_ATTR(multicast_received_frame_count, dot11MulticastReceivedFrameCount, "%u");
+IEEE80211_LOCAL_ATTR(transmitted_frame_count, dot11TransmittedFrameCount, "%u");
+IEEE80211_LOCAL_ATTR(wep_undecryptable_count, dot11WEPUndecryptableCount, "%u");
+IEEE80211_LOCAL_ATTR(num_scans, scan.num_scans, "%u");
+
+#ifdef CONFIG_D80211_DEBUG_COUNTERS
+IEEE80211_LOCAL_ATTR(tx_handlers_drop, tx_handlers_drop, "%u");
+IEEE80211_LOCAL_ATTR(tx_handlers_queued, tx_handlers_queued, "%u");
+IEEE80211_LOCAL_ATTR(tx_handlers_drop_unencrypted, tx_handlers_drop_unencrypted, "%u");
+IEEE80211_LOCAL_ATTR(tx_handlers_drop_fragment, tx_handlers_drop_fragment, "%u");
+IEEE80211_LOCAL_ATTR(tx_handlers_drop_wep, tx_handlers_drop_wep, "%u");
+IEEE80211_LOCAL_ATTR(tx_handlers_drop_rate_limit, tx_handlers_drop_rate_limit, "%u");
+IEEE80211_LOCAL_ATTR(tx_handlers_drop_not_assoc, tx_handlers_drop_not_assoc, "%u");
+IEEE80211_LOCAL_ATTR(tx_handlers_drop_unauth_port, tx_handlers_drop_unauth_port, "%u");
+IEEE80211_LOCAL_ATTR(rx_handlers_drop, rx_handlers_drop, "%u");
+IEEE80211_LOCAL_ATTR(rx_handlers_queued, rx_handlers_queued, "%u");
+IEEE80211_LOCAL_ATTR(rx_handlers_drop_nullfunc, rx_handlers_drop_nullfunc, "%u");
+IEEE80211_LOCAL_ATTR(rx_handlers_drop_defrag, rx_handlers_drop_defrag, "%u");
+IEEE80211_LOCAL_ATTR(rx_handlers_drop_short, rx_handlers_drop_short, "%u");
+IEEE80211_LOCAL_ATTR(rx_handlers_drop_passive_scan, rx_handlers_drop_passive_scan, "%u");
+IEEE80211_LOCAL_ATTR(tx_expand_skb_head, tx_expand_skb_head, "%u");
+IEEE80211_LOCAL_ATTR(tx_expand_skb_head_cloned, tx_expand_skb_head_cloned, "%u");
+IEEE80211_LOCAL_ATTR(rx_expand_skb_head, rx_expand_skb_head, "%u");
+IEEE80211_LOCAL_ATTR(rx_expand_skb_head2, rx_expand_skb_head2, "%u");
+IEEE80211_LOCAL_ATTR(rx_handlers_fragments, rx_handlers_fragments, "%u");
+IEEE80211_LOCAL_ATTR(tx_status_drop, tx_status_drop, "%u");
+
+static ssize_t ieee80211_local_fmt_wme_rx_queue(struct ieee80211_local *local,
+ char *buf)
+{
+ int i;
+ char *p = buf;
+
+ for (i = 0; i < NUM_RX_DATA_QUEUES; i++)
+ p += sprintf(p, "%u\n", local->wme_rx_queue[i]);
+ return (p - buf);
+}
+__IEEE80211_LOCAL_SHOW(wme_rx_queue);
+static CLASS_DEVICE_ATTR(wme_rx_queue, S_IRUGO,
+ ieee80211_local_show_wme_rx_queue, NULL);
+
+static ssize_t ieee80211_local_fmt_wme_tx_queue(struct ieee80211_local *local,
+ char *buf)
+{
+ int i;
+ char *p = buf;
+
+ for (i = 0; i < NUM_RX_DATA_QUEUES; i++)
+ p += sprintf(p, "%u\n", local->wme_tx_queue[i]);
+ return (p - buf);
+}
+__IEEE80211_LOCAL_SHOW(wme_tx_queue);
+static CLASS_DEVICE_ATTR(wme_tx_queue, S_IRUGO,
+ ieee80211_local_show_wme_tx_queue, NULL);
+#endif
+
+static ssize_t ieee80211_stats_show(struct class_device *dev, char *buf,
+ ssize_t (*format)(struct ieee80211_low_level_stats *, char *))
+{
+ struct ieee80211_local *local = to_ieee80211_local(dev);
+ struct ieee80211_low_level_stats stats;
+ ssize_t ret = -EINVAL;
+
+ if (!local->hw->get_stats)
+ return -EOPNOTSUPP;
+ ret = rtnl_lock_local(local);
+ if (ret)
+ return ret;
+ ret = local->hw->get_stats(local->mdev, &stats);
+ rtnl_unlock();
+ if (!ret)
+ ret = (*format)(&stats, buf);
+ return ret;
+}
+
+#define IEEE80211_STATS_FMT(name, field, format_string) \
+static ssize_t ieee80211_stats_fmt_##name(struct ieee80211_low_level_stats \
+ *stats, char *buf) \
+{ \
+ return sprintf(buf, format_string, stats->field); \
+}
+
+#define __IEEE80211_STATS_SHOW(name) \
+static ssize_t ieee80211_stats_show_##name(struct class_device *cd, \
+ char *buf) \
+{ \
+ return ieee80211_stats_show(cd, buf, \
+ ieee80211_stats_fmt_##name); \
+}
+
+#define IEEE80211_STATS_ATTR(name, field, format) \
+IEEE80211_STATS_FMT(name, field, format "\n") \
+__IEEE80211_STATS_SHOW(name) \
+static CLASS_DEVICE_ATTR(name, S_IRUGO, ieee80211_stats_show_##name, NULL);
+
+IEEE80211_STATS_ATTR(ack_failure_count, dot11ACKFailureCount, "%u");
+IEEE80211_STATS_ATTR(rts_failure_count, dot11RTSFailureCount, "%u");
+IEEE80211_STATS_ATTR(fcs_error_count, dot11FCSErrorCount, "%u");
+IEEE80211_STATS_ATTR(rts_success_count, dot11RTSSuccessCount, "%u");
+
+static struct attribute *ieee80211_stats_attrs[] = {
+ &class_device_attr_transmitted_fragment_count.attr,
+ &class_device_attr_multicast_transmitted_frame_count.attr,
+ &class_device_attr_failed_count.attr,
+ &class_device_attr_retry_count.attr,
+ &class_device_attr_multiple_retry_count.attr,
+ &class_device_attr_frame_duplicate_count.attr,
+ &class_device_attr_received_fragment_count.attr,
+ &class_device_attr_multicast_received_frame_count.attr,
+ &class_device_attr_transmitted_frame_count.attr,
+ &class_device_attr_wep_undecryptable_count.attr,
+ &class_device_attr_ack_failure_count.attr,
+ &class_device_attr_rts_failure_count.attr,
+ &class_device_attr_fcs_error_count.attr,
+ &class_device_attr_rts_success_count.attr,
+ &class_device_attr_num_scans.attr,
+#ifdef CONFIG_D80211_DEBUG_COUNTERS
+ &class_device_attr_tx_handlers_drop.attr,
+ &class_device_attr_tx_handlers_queued.attr,
+ &class_device_attr_tx_handlers_drop_unencrypted.attr,
+ &class_device_attr_tx_handlers_drop_fragment.attr,
+ &class_device_attr_tx_handlers_drop_wep.attr,
+ &class_device_attr_tx_handlers_drop_rate_limit.attr,
+ &class_device_attr_tx_handlers_drop_not_assoc.attr,
+ &class_device_attr_tx_handlers_drop_unauth_port.attr,
+ &class_device_attr_rx_handlers_drop.attr,
+ &class_device_attr_rx_handlers_queued.attr,
+ &class_device_attr_rx_handlers_drop_nullfunc.attr,
+ &class_device_attr_rx_handlers_drop_defrag.attr,
+ &class_device_attr_rx_handlers_drop_short.attr,
+ &class_device_attr_rx_handlers_drop_passive_scan.attr,
+ &class_device_attr_tx_expand_skb_head.attr,
+ &class_device_attr_tx_expand_skb_head_cloned.attr,
+ &class_device_attr_rx_expand_skb_head.attr,
+ &class_device_attr_rx_expand_skb_head2.attr,
+ &class_device_attr_rx_handlers_fragments.attr,
+ &class_device_attr_tx_status_drop.attr,
+ &class_device_attr_wme_rx_queue.attr,
+ &class_device_attr_wme_tx_queue.attr,
+#endif
+ NULL,
+};
+
+static struct attribute_group ieee80211_stats_group = {
+ .name = "statistics",
+ .attrs = ieee80211_stats_attrs,
+};
+
+/* /sys/class/ieee80211/phyX functions */
+
static void ieee80211_class_dev_release(struct class_device *dev)
{
ieee80211_release_hw(to_ieee80211_local(dev));
@@ -88,12 +370,6 @@ static int ieee80211_uevent(struct class
}
#endif
-static struct class_device_attribute ieee80211_class_dev_attrs[] = {
- __ATTR(add_iface, S_IWUSR, NULL, store_add_iface),
- __ATTR(remove_iface, S_IWUSR, NULL, store_remove_iface),
- {}
-};
-
static struct class ieee80211_class = {
.name = "ieee80211",
.class_dev_attrs = ieee80211_class_dev_attrs,
@@ -117,16 +393,28 @@ void ieee80211_dev_sysfs_put(struct ieee
int ieee80211_dev_sysfs_add(struct ieee80211_local *local)
{
+ int res;
+
snprintf(local->class_dev.class_id, BUS_ID_SIZE,
"phy%d", local->dev_index);
- return class_device_add(&local->class_dev);
+ res = class_device_add(&local->class_dev);
+ if (res)
+ return res;
+ res = sysfs_create_group(&local->class_dev.kobj,
+ &ieee80211_stats_group);
+ if (res)
+ class_device_del(&local->class_dev);
+ return res;
}
void ieee80211_dev_sysfs_del(struct ieee80211_local *local)
{
+ sysfs_remove_group(&local->class_dev.kobj, &ieee80211_stats_group);
class_device_del(&local->class_dev);
}
+/* /sys/class/net/X functions */
+
int ieee80211_sysfs_add_netdevice(struct net_device *dev)
{
struct ieee80211_local *local = dev->ieee80211_ptr;
@@ -140,6 +428,8 @@ void ieee80211_sysfs_remove_netdevice(st
sysfs_remove_link(&dev->class_dev.kobj, "wiphy");
}
+/* general module functions */
+
int ieee80211_sysfs_init(void)
{
return class_register(&ieee80211_class);
--
1.3.0
^ permalink raw reply related
* [PATCH 6/12] d80211: network interface sysfs attributes
From: Jiri Benc @ 2006-06-08 7:49 UTC (permalink / raw)
To: netdev; +Cc: John W. Linville
In-Reply-To: <20060608094822.014829000.midnight@suse.cz>
Add /sys/class/net/X/* attributes for 802.11 interfaces.
Signed-off-by: Jiri Benc <jbenc@suse.cz>
---
net/d80211/ieee80211_i.h | 3
net/d80211/ieee80211_iface.c | 1
net/d80211/ieee80211_sysfs.c | 299 ++++++++++++++++++++++++++++++++++++++++++
3 files changed, 301 insertions(+), 2 deletions(-)
ad13a53621edc97c9bfb41a513a674415186c392
diff --git a/net/d80211/ieee80211_i.h b/net/d80211/ieee80211_i.h
index 9fabf17..7c1b621 100644
--- a/net/d80211/ieee80211_i.h
+++ b/net/d80211/ieee80211_i.h
@@ -305,6 +305,8 @@ #define NUM_DEFAULT_KEYS 4
} u;
int channel_use;
int channel_use_raw;
+
+ struct attribute_group *sysfs_group;
};
#define IEEE80211_DEV_TO_SUB_IF(dev) netdev_priv(dev)
@@ -616,5 +618,6 @@ int ieee80211_dev_sysfs_add(struct ieee8
void ieee80211_dev_sysfs_del(struct ieee80211_local *local);
int ieee80211_sysfs_init(void);
void ieee80211_sysfs_deinit(void);
+int ieee80211_sysfs_change_if_type(struct net_device *dev);
#endif /* IEEE80211_I_H */
diff --git a/net/d80211/ieee80211_iface.c b/net/d80211/ieee80211_iface.c
index 8ab2c07..727b5e3 100644
--- a/net/d80211/ieee80211_iface.c
+++ b/net/d80211/ieee80211_iface.c
@@ -202,6 +202,7 @@ void ieee80211_if_set_type(struct net_de
printk(KERN_WARNING "%s: %s: Unknown interface type 0x%x",
dev->name, __FUNCTION__, type);
}
+ ieee80211_sysfs_change_if_type(dev);
}
/* Must be called with rtnl lock held. */
diff --git a/net/d80211/ieee80211_sysfs.c b/net/d80211/ieee80211_sysfs.c
index 07a7036..12d16fd 100644
--- a/net/d80211/ieee80211_sysfs.c
+++ b/net/d80211/ieee80211_sysfs.c
@@ -18,6 +18,7 @@ #include "ieee80211_proc.h"
#include "rate_control.h"
#define to_ieee80211_local(class) container_of(class, struct ieee80211_local, class_dev)
+#define to_net_dev(class) container_of(class, struct net_device, class_dev)
static inline int rtnl_lock_local(struct ieee80211_local *local)
{
@@ -346,6 +347,238 @@ static struct attribute_group ieee80211_
.attrs = ieee80211_stats_attrs,
};
+/* attributes in /sys/class/net/X/ */
+
+static ssize_t ieee80211_if_show(struct class_device *cd, char *buf,
+ ssize_t (*format)(const struct ieee80211_sub_if_data *,
+ char *))
+{
+ struct net_device *dev = to_net_dev(cd);
+ struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+ ssize_t ret = -EINVAL;
+
+ read_lock(&dev_base_lock);
+ if (dev->reg_state == NETREG_REGISTERED) {
+ ret = (*format)(sdata, buf);
+ }
+ read_unlock(&dev_base_lock);
+ return ret;
+}
+
+#define IEEE80211_IF_FMT(name, field, format_string) \
+static ssize_t ieee80211_if_fmt_##name(const struct \
+ ieee80211_sub_if_data *sdata, char *buf) \
+{ \
+ return sprintf(buf, format_string, sdata->field); \
+}
+#define IEEE80211_IF_FMT_DEC(name, field) \
+ IEEE80211_IF_FMT(name, field, "%d\n")
+#define IEEE80211_IF_FMT_HEX(name, field) \
+ IEEE80211_IF_FMT(name, field, "%#x\n")
+#define IEEE80211_IF_FMT_SIZE(name, field) \
+ IEEE80211_IF_FMT(name, field, "%zd\n")
+
+#define IEEE80211_IF_FMT_ATOMIC(name, field) \
+static ssize_t ieee80211_if_fmt_##name(const struct \
+ ieee80211_sub_if_data *sdata, char *buf) \
+{ \
+ return sprintf(buf, "%d\n", atomic_read(&sdata->field)); \
+}
+
+#define IEEE80211_IF_FMT_MAC(name, field) \
+static ssize_t ieee80211_if_fmt_##name(const struct \
+ ieee80211_sub_if_data *sdata, char *buf) \
+{ \
+ return sprintf(buf, MACSTR "\n", MAC2STR(sdata->field)); \
+}
+
+#define __IEEE80211_IF_SHOW(name) \
+static ssize_t ieee80211_if_show_##name(struct class_device *cd, \
+ char *buf) \
+{ \
+ return ieee80211_if_show(cd, buf, ieee80211_if_fmt_##name); \
+} \
+static CLASS_DEVICE_ATTR(name, S_IRUGO, ieee80211_if_show_##name, NULL);
+
+#define IEEE80211_IF_SHOW(name, field, format) \
+ IEEE80211_IF_FMT_##format(name, field) \
+ __IEEE80211_IF_SHOW(name)
+
+/* common attributes */
+IEEE80211_IF_SHOW(channel_use, channel_use, DEC);
+IEEE80211_IF_SHOW(drop_unencrypted, drop_unencrypted, DEC);
+IEEE80211_IF_SHOW(eapol, eapol, DEC);
+IEEE80211_IF_SHOW(ieee8021_x, ieee802_1x, DEC);
+
+/* STA/IBSS attributes */
+IEEE80211_IF_SHOW(state, u.sta.state, DEC);
+IEEE80211_IF_SHOW(bssid, u.sta.bssid, MAC);
+IEEE80211_IF_SHOW(prev_bssid, u.sta.prev_bssid, MAC);
+IEEE80211_IF_SHOW(ssid_len, u.sta.ssid_len, SIZE);
+IEEE80211_IF_SHOW(aid, u.sta.aid, DEC);
+IEEE80211_IF_SHOW(ap_capab, u.sta.ap_capab, HEX);
+IEEE80211_IF_SHOW(capab, u.sta.capab, HEX);
+IEEE80211_IF_SHOW(extra_ie_len, u.sta.extra_ie_len, SIZE);
+IEEE80211_IF_SHOW(auth_tries, u.sta.auth_tries, DEC);
+IEEE80211_IF_SHOW(assoc_tries, u.sta.assoc_tries, DEC);
+IEEE80211_IF_SHOW(auth_algs, u.sta.auth_algs, HEX);
+IEEE80211_IF_SHOW(auth_alg, u.sta.auth_alg, DEC);
+IEEE80211_IF_SHOW(auth_transaction, u.sta.auth_transaction, DEC);
+
+static ssize_t ieee80211_if_fmt_flags(const struct
+ ieee80211_sub_if_data *sdata, char *buf)
+{
+ return sprintf(buf, "%s%s%s%s%s%s%s\n",
+ sdata->u.sta.ssid_set ? "SSID\n" : "",
+ sdata->u.sta.bssid_set ? "BSSID\n" : "",
+ sdata->u.sta.prev_bssid_set ? "prev BSSID\n" : "",
+ sdata->u.sta.authenticated ? "AUTH\n" : "",
+ sdata->u.sta.associated ? "ASSOC\n" : "",
+ sdata->u.sta.probereq_poll ? "PROBEREQ POLL\n" : "",
+ sdata->u.sta.use_protection ? "CTS prot\n" : "");
+}
+__IEEE80211_IF_SHOW(flags);
+
+/* AP attributes */
+IEEE80211_IF_SHOW(max_aid, u.ap.max_aid, DEC);
+IEEE80211_IF_SHOW(num_sta_ps, u.ap.num_sta_ps, ATOMIC);
+IEEE80211_IF_SHOW(dtim_period, u.ap.dtim_period, DEC);
+IEEE80211_IF_SHOW(dtim_count, u.ap.dtim_count, DEC);
+IEEE80211_IF_SHOW(num_beacons, u.ap.num_beacons, DEC);
+IEEE80211_IF_SHOW(force_unicast_rateidx, u.ap.force_unicast_rateidx, DEC);
+IEEE80211_IF_SHOW(max_ratectrl_rateidx, u.ap.max_ratectrl_rateidx, DEC);
+
+static ssize_t ieee80211_if_fmt_num_buffered_multicast(const struct
+ ieee80211_sub_if_data *sdata, char *buf)
+{
+ return sprintf(buf, "%u\n", skb_queue_len(&sdata->u.ap.ps_bc_buf));
+}
+__IEEE80211_IF_SHOW(num_buffered_multicast);
+
+static ssize_t ieee80211_if_fmt_beacon_head_len(const struct
+ ieee80211_sub_if_data *sdata, char *buf)
+{
+ if (sdata->u.ap.beacon_head)
+ return sprintf(buf, "%d\n", sdata->u.ap.beacon_head_len);
+ return sprintf(buf, "\n");
+}
+__IEEE80211_IF_SHOW(beacon_head_len);
+
+static ssize_t ieee80211_if_fmt_beacon_tail_len(const struct
+ ieee80211_sub_if_data *sdata, char *buf)
+{
+ if (sdata->u.ap.beacon_tail)
+ return sprintf(buf, "%d\n", sdata->u.ap.beacon_tail_len);
+ return sprintf(buf, "\n");
+}
+__IEEE80211_IF_SHOW(beacon_tail_len);
+
+/* WDS attributes */
+IEEE80211_IF_SHOW(peer, u.wds.remote_addr, MAC);
+
+/* VLAN attributes */
+IEEE80211_IF_SHOW(vlan_id, u.vlan.id, DEC);
+
+/* MONITOR attributes */
+static ssize_t ieee80211_if_fmt_mode(const struct
+ ieee80211_sub_if_data *sdata, char *buf)
+{
+ struct ieee80211_local *local = sdata->local;
+
+ return sprintf(buf, "%s\n", (local->hw->monitor_during_oper ||
+ local->open_count == local->monitors) ?
+ "hard" : "soft");
+}
+__IEEE80211_IF_SHOW(mode);
+
+static struct attribute *ieee80211_sta_attrs[] = {
+ &class_device_attr_channel_use.attr,
+ &class_device_attr_drop_unencrypted.attr,
+ &class_device_attr_eapol.attr,
+ &class_device_attr_ieee8021_x.attr,
+ &class_device_attr_state.attr,
+ &class_device_attr_bssid.attr,
+ &class_device_attr_prev_bssid.attr,
+ &class_device_attr_ssid_len.attr,
+ &class_device_attr_aid.attr,
+ &class_device_attr_ap_capab.attr,
+ &class_device_attr_capab.attr,
+ &class_device_attr_extra_ie_len.attr,
+ &class_device_attr_auth_tries.attr,
+ &class_device_attr_assoc_tries.attr,
+ &class_device_attr_auth_algs.attr,
+ &class_device_attr_auth_alg.attr,
+ &class_device_attr_auth_transaction.attr,
+ &class_device_attr_flags.attr,
+ NULL
+};
+
+static struct attribute *ieee80211_ap_attrs[] = {
+ &class_device_attr_channel_use.attr,
+ &class_device_attr_drop_unencrypted.attr,
+ &class_device_attr_eapol.attr,
+ &class_device_attr_ieee8021_x.attr,
+ &class_device_attr_max_aid.attr,
+ &class_device_attr_num_sta_ps.attr,
+ &class_device_attr_dtim_period.attr,
+ &class_device_attr_dtim_count.attr,
+ &class_device_attr_num_beacons.attr,
+ &class_device_attr_force_unicast_rateidx.attr,
+ &class_device_attr_max_ratectrl_rateidx.attr,
+ &class_device_attr_num_buffered_multicast.attr,
+ &class_device_attr_beacon_head_len.attr,
+ &class_device_attr_beacon_tail_len.attr,
+ NULL
+};
+
+static struct attribute *ieee80211_wds_attrs[] = {
+ &class_device_attr_channel_use.attr,
+ &class_device_attr_drop_unencrypted.attr,
+ &class_device_attr_eapol.attr,
+ &class_device_attr_ieee8021_x.attr,
+ &class_device_attr_peer.attr,
+ NULL
+};
+
+static struct attribute *ieee80211_vlan_attrs[] = {
+ &class_device_attr_channel_use.attr,
+ &class_device_attr_drop_unencrypted.attr,
+ &class_device_attr_eapol.attr,
+ &class_device_attr_ieee8021_x.attr,
+ &class_device_attr_vlan_id.attr,
+ NULL
+};
+
+static struct attribute *ieee80211_monitor_attrs[] = {
+ &class_device_attr_mode.attr,
+ NULL
+};
+
+static struct attribute_group ieee80211_sta_group = {
+ .name = "sta",
+ .attrs = ieee80211_sta_attrs,
+};
+
+static struct attribute_group ieee80211_ap_group = {
+ .name = "ap",
+ .attrs = ieee80211_ap_attrs,
+};
+
+static struct attribute_group ieee80211_wds_group = {
+ .name = "wds",
+ .attrs = ieee80211_wds_attrs,
+};
+
+static struct attribute_group ieee80211_vlan_group = {
+ .name = "vlan",
+ .attrs = ieee80211_vlan_attrs,
+};
+
+static struct attribute_group ieee80211_monitor_group = {
+ .name = "monitor",
+ .attrs = ieee80211_monitor_attrs,
+};
+
/* /sys/class/ieee80211/phyX functions */
static void ieee80211_class_dev_release(struct class_device *dev)
@@ -415,16 +648,78 @@ void ieee80211_dev_sysfs_del(struct ieee
/* /sys/class/net/X functions */
+static void __ieee80211_remove_if_group(struct kobject *kobj,
+ struct ieee80211_sub_if_data *sdata)
+{
+ if (sdata->sysfs_group) {
+ sysfs_remove_group(kobj, sdata->sysfs_group);
+ sdata->sysfs_group = NULL;
+ }
+}
+
+static inline void ieee80211_remove_if_group(struct kobject *kobj,
+ struct net_device *dev)
+{
+ __ieee80211_remove_if_group(kobj, IEEE80211_DEV_TO_SUB_IF(dev));
+}
+
+static int ieee80211_add_if_group(struct kobject *kobj,
+ struct net_device *dev)
+{
+ struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+ int res = 0;
+
+ __ieee80211_remove_if_group(kobj, sdata);
+ switch (sdata->type) {
+ case IEEE80211_IF_TYPE_STA:
+ sdata->sysfs_group = &ieee80211_sta_group;
+ break;
+ case IEEE80211_IF_TYPE_AP:
+ sdata->sysfs_group = &ieee80211_ap_group;
+ break;
+ case IEEE80211_IF_TYPE_WDS:
+ sdata->sysfs_group = &ieee80211_wds_group;
+ break;
+ case IEEE80211_IF_TYPE_VLAN:
+ sdata->sysfs_group = &ieee80211_vlan_group;
+ break;
+ case IEEE80211_IF_TYPE_MNTR:
+ sdata->sysfs_group = &ieee80211_monitor_group;
+ break;
+ default:
+ goto out;
+ }
+ res = sysfs_create_group(kobj, sdata->sysfs_group);
+ if (res)
+ sdata->sysfs_group = NULL;
+out:
+ return res;
+}
+
+int ieee80211_sysfs_change_if_type(struct net_device *dev)
+{
+ return ieee80211_add_if_group(&dev->class_dev.kobj, dev);
+}
+
int ieee80211_sysfs_add_netdevice(struct net_device *dev)
{
struct ieee80211_local *local = dev->ieee80211_ptr;
+ int res;
- return sysfs_create_link(&dev->class_dev.kobj, &local->class_dev.kobj,
- "wiphy");
+ res = sysfs_create_link(&dev->class_dev.kobj, &local->class_dev.kobj,
+ "wiphy");
+ if (res)
+ goto out;
+ res = ieee80211_add_if_group(&dev->class_dev.kobj, dev);
+ if (res)
+ sysfs_remove_link(&dev->class_dev.kobj, "wiphy");
+out:
+ return res;
}
void ieee80211_sysfs_remove_netdevice(struct net_device *dev)
{
+ ieee80211_remove_if_group(&dev->class_dev.kobj, dev);
sysfs_remove_link(&dev->class_dev.kobj, "wiphy");
}
--
1.3.0
^ permalink raw reply related
* [PATCH 7/12] d80211: rename sta_info_relase to sta_info_put
From: Jiri Benc @ 2006-06-08 7:49 UTC (permalink / raw)
To: netdev; +Cc: John W. Linville
In-Reply-To: <20060608094822.014829000.midnight@suse.cz>
sta_info structure has reference counting (will be converted to kobject in
next patch). Therefore, sta_info_release should be divided into two
functions - one for decrementing reference count and one for freeing the
structure when the count drops to zero. sta_info_release is the name
suitable for the second function.
This patch renames sta_info_release to sta_info_put to let next patch
introduce a new sta_info_release function.
Signed-off-by: Jiri Benc <jbenc@suse.cz>
---
net/d80211/ieee80211.c | 18 +++++++++---------
net/d80211/ieee80211_iface.c | 2 +-
net/d80211/ieee80211_ioctl.c | 18 +++++++++---------
net/d80211/ieee80211_sta.c | 8 ++++----
net/d80211/rate_control.c | 4 ++--
net/d80211/sta_info.c | 10 +++++-----
net/d80211/sta_info.h | 2 +-
7 files changed, 31 insertions(+), 31 deletions(-)
4ddde98ebbdede0d0b16a85156e1b9c192c0e764
diff --git a/net/d80211/ieee80211.c b/net/d80211/ieee80211.c
index c983d70..0c23607 100644
--- a/net/d80211/ieee80211.c
+++ b/net/d80211/ieee80211.c
@@ -1153,7 +1153,7 @@ static int ieee80211_tx(struct net_devic
skb = tx.skb; /* handlers are allowed to change skb */
if (sta)
- sta_info_release(local, sta);
+ sta_info_put(local, sta);
if (unlikely(res == TXRX_DROP)) {
I802_DEBUG_INC(local->tx_handlers_drop);
@@ -1373,7 +1373,7 @@ static int ieee80211_subif_start_xmit(st
fc |= WLAN_FC_STYPE_QOS_DATA << 4;
hdrlen += 2;
}
- sta_info_release(local, sta);
+ sta_info_put(local, sta);
}
hdr.frame_control = cpu_to_le16(fc);
@@ -1743,7 +1743,7 @@ ieee80211_get_buffered_bc(struct net_dev
}
if (sta)
- sta_info_release(local, sta);
+ sta_info_put(local, sta);
return skb;
}
@@ -2330,7 +2330,7 @@ ieee80211_rx_h_data(struct ieee80211_txr
skb = NULL;
}
if (dsta)
- sta_info_release(local, dsta);
+ sta_info_put(local, dsta);
}
}
@@ -3469,7 +3469,7 @@ void __ieee80211_rx(struct net_device *d
end:
if (sta)
- sta_info_release(local, sta);
+ sta_info_put(local, sta);
}
@@ -3806,7 +3806,7 @@ void ieee80211_tx_status(struct net_devi
status->excessive_retries = 0;
status->tx_filtered = 1;
}
- sta_info_release(local, sta);
+ sta_info_put(local, sta);
}
}
@@ -3855,7 +3855,7 @@ void ieee80211_tx_status(struct net_devi
}
dev_kfree_skb(skb);
}
- sta_info_release(local, sta);
+ sta_info_put(local, sta);
return;
}
} else {
@@ -3978,7 +3978,7 @@ int ieee80211_if_update_wds(struct net_d
/* Remove STA entry for the old peer */
sta = sta_info_get(local, sdata->u.wds.remote_addr);
if (sta) {
- sta_info_release(local, sta);
+ sta_info_put(local, sta);
sta_info_free(local, sta, 0);
} else {
printk(KERN_DEBUG "%s: could not find STA entry for WDS link "
@@ -4522,7 +4522,7 @@ EXPORT_SYMBOL(ieee80211_get_hdrlen_from_
EXPORT_SYMBOL(ieee80211_rate_control_register);
EXPORT_SYMBOL(ieee80211_rate_control_unregister);
EXPORT_SYMBOL(sta_info_get);
-EXPORT_SYMBOL(sta_info_release);
+EXPORT_SYMBOL(sta_info_put);
EXPORT_SYMBOL(ieee80211_radar_status);
EXPORT_SYMBOL(ieee80211_get_mc_list_item);
diff --git a/net/d80211/ieee80211_iface.c b/net/d80211/ieee80211_iface.c
index 727b5e3..467dcba 100644
--- a/net/d80211/ieee80211_iface.c
+++ b/net/d80211/ieee80211_iface.c
@@ -261,7 +261,7 @@ #endif
case IEEE80211_IF_TYPE_WDS:
sta = sta_info_get(local, sdata->u.wds.remote_addr);
if (sta) {
- sta_info_release(local, sta);
+ sta_info_put(local, sta);
sta_info_free(local, sta, 0);
} else {
#ifdef CONFIG_D80211_VERBOSE_DEBUG
diff --git a/net/d80211/ieee80211_ioctl.c b/net/d80211/ieee80211_ioctl.c
index 8d593e8..e1bdc03 100644
--- a/net/d80211/ieee80211_ioctl.c
+++ b/net/d80211/ieee80211_ioctl.c
@@ -294,7 +294,7 @@ static int ieee80211_ioctl_add_sta(struc
}
}
- sta_info_release(local, sta);
+ sta_info_put(local, sta);
return 0;
}
@@ -308,7 +308,7 @@ static int ieee80211_ioctl_remove_sta(st
sta = sta_info_get(local, param->sta_addr);
if (sta) {
- sta_info_release(local, sta);
+ sta_info_put(local, sta);
sta_info_free(local, sta, 1);
}
@@ -393,7 +393,7 @@ static int ieee80211_ioctl_get_info_sta(
param->u.get_info_sta.last_rssi = sta->last_rssi;
param->u.get_info_sta.last_ack_rssi = sta->last_ack_rssi[2];
- sta_info_release(local, sta);
+ sta_info_put(local, sta);
return 0;
}
@@ -421,7 +421,7 @@ static int ieee80211_ioctl_set_flags_sta
printk(KERN_DEBUG "%s: failed to set low-level driver "
"PAE state (unauthorized) for " MACSTR "\n",
dev->name, MAC2STR(sta->addr));
- sta_info_release(local, sta);
+ sta_info_put(local, sta);
}
return sta ? 0 : -ENOENT;
@@ -563,7 +563,7 @@ #endif /* CONFIG_D80211_VERBOSE_DEBUG */
if (sta->flags & WLAN_STA_WME) {
try_hwaccel = 0;
}
- sta_info_release(local, sta);
+ sta_info_put(local, sta);
sta = NULL;
}
}
@@ -643,7 +643,7 @@ #endif /* CONFIG_D80211_VERBOSE_DEBUG */
done:
if (sta)
- sta_info_release(local, sta);
+ sta_info_put(local, sta);
return ret;
}
@@ -813,7 +813,7 @@ static int ieee80211_ioctl_get_encryptio
}
if (sta)
- sta_info_release(local, sta);
+ sta_info_put(local, sta);
return ret;
}
@@ -842,7 +842,7 @@ static int ieee80211_ioctl_wpa_trigger(s
sta->wpa_trigger = param->u.wpa_trigger.trigger;
- sta_info_release(local, sta);
+ sta_info_put(local, sta);
return 0;
}
#endif /* CONFIG_HOSTAPD_WPA_TESTING */
@@ -1136,7 +1136,7 @@ #endif
sta->vlan_id = param->u.set_sta_vlan.vlan_id;
dev_put(new_vlan_dev);
}
- sta_info_release(local, sta);
+ sta_info_put(local, sta);
}
return sta ? 0 : -ENOENT;
diff --git a/net/d80211/ieee80211_sta.c b/net/d80211/ieee80211_sta.c
index 66a4575..a42c387 100644
--- a/net/d80211/ieee80211_sta.c
+++ b/net/d80211/ieee80211_sta.c
@@ -730,7 +730,7 @@ static void ieee80211_associated(struct
ifsta->ssid_len);
}
}
- sta_info_release(local, sta);
+ sta_info_put(local, sta);
}
if (disassoc) {
union iwreq_data wrqu;
@@ -1200,7 +1200,7 @@ static void ieee80211_rx_mgmt_assoc_resp
}
- sta_info_release(local, sta);
+ sta_info_put(local, sta);
ieee80211_associated(dev, ifsta);
}
@@ -1443,7 +1443,7 @@ #endif /* IEEE80211_IBSS_DEBUG */
dev->name, MAC2STR(sta->addr), prev_rates,
supp_rates, sta->supp_rates);
}
- sta_info_release(local, sta);
+ sta_info_put(local, sta);
}
if (elems.ssid == NULL)
@@ -2834,7 +2834,7 @@ struct sta_info * ieee80211_ibss_add_sta
rate_control_rate_init(local, sta);
- return sta; /* caller will call sta_info_release() */
+ return sta; /* caller will call sta_info_put() */
}
diff --git a/net/d80211/rate_control.c b/net/d80211/rate_control.c
index 3485302..9bcb8fc 100644
--- a/net/d80211/rate_control.c
+++ b/net/d80211/rate_control.c
@@ -209,7 +209,7 @@ #endif /* CONFIG_D80211_VERBOSE_DEBUG */
}
}
- sta_info_release(local, sta);
+ sta_info_put(local, sta);
}
@@ -260,7 +260,7 @@ rate_control_simple_get_rate(struct net_
extra->nonerp_idx = nonerp_idx;
extra->nonerp = &local->curr_rates[extra->nonerp_idx];
- sta_info_release(local, sta);
+ sta_info_put(local, sta);
return &local->curr_rates[rateidx];
}
diff --git a/net/d80211/sta_info.c b/net/d80211/sta_info.c
index de14821..9565c29 100644
--- a/net/d80211/sta_info.c
+++ b/net/d80211/sta_info.c
@@ -98,7 +98,7 @@ int sta_info_min_txrate_get(struct ieee8
}
-void sta_info_release(struct ieee80211_local *local, struct sta_info *sta)
+void sta_info_put(struct ieee80211_local *local, struct sta_info *sta)
{
struct sk_buff *skb;
@@ -145,7 +145,7 @@ struct sta_info * sta_info_add(struct ie
atomic_inc(&sta->users); /* sta in hashlist etc, decremented by
* sta_info_free() */
atomic_inc(&sta->users); /* sta used by caller, decremented by
- * sta_info_release() */
+ * sta_info_put() */
spin_lock_bh(&local->sta_lock);
list_add(&sta->list, &local->sta_list);
local->num_sta++;
@@ -237,13 +237,13 @@ #endif /* CONFIG_D80211_VERBOSE_DEBUG */
if (atomic_read(&sta->users) != 1) {
/* This is OK, but printed for debugging. The station structure
* will be removed when the other user of the data calls
- * sta_info_release(). */
+ * sta_info_put(). */
printk(KERN_DEBUG "%s: STA " MACSTR " users count %d when "
"removing it\n", local->mdev->name, MAC2STR(sta->addr),
atomic_read(&sta->users));
}
- sta_info_release(local, sta);
+ sta_info_put(local, sta);
}
@@ -302,7 +302,7 @@ static void sta_info_cleanup(unsigned lo
struct sta_info *sta = (struct sta_info *) ptr;
atomic_inc(&sta->users);
sta_info_cleanup_expire_buffered(local, sta);
- sta_info_release(local, sta);
+ sta_info_put(local, sta);
ptr = ptr->next;
}
spin_unlock_bh(&local->sta_lock);
diff --git a/net/d80211/sta_info.h b/net/d80211/sta_info.h
index 294cb0a..fddc80e 100644
--- a/net/d80211/sta_info.h
+++ b/net/d80211/sta_info.h
@@ -134,7 +134,7 @@ struct ieee80211_local;
struct sta_info * sta_info_get(struct ieee80211_local *local, u8 *addr);
int sta_info_min_txrate_get(struct ieee80211_local *local);
-void sta_info_release(struct ieee80211_local *local, struct sta_info *sta);
+void sta_info_put(struct ieee80211_local *local, struct sta_info *sta);
struct sta_info * sta_info_add(struct ieee80211_local *local,
struct net_device *dev, u8 *addr);
void sta_info_free(struct ieee80211_local *local, struct sta_info *sta,
--
1.3.0
^ permalink raw reply related
* [PATCH 8/12] d80211: sysfs attributes for associated stations
From: Jiri Benc @ 2006-06-08 7:49 UTC (permalink / raw)
To: netdev; +Cc: John W. Linville
In-Reply-To: <20060608094822.014829000.midnight@suse.cz>
Add /sys/class/ieee80211/phyX/sta/* attributes.
Signed-off-by: Jiri Benc <jbenc@suse.cz>
---
net/d80211/Makefile | 1
net/d80211/ieee80211.c | 5 +
net/d80211/ieee80211_i.h | 14 ++
net/d80211/ieee80211_proc.c | 3 -
net/d80211/ieee80211_sysfs_sta.c | 228 ++++++++++++++++++++++++++++++++++++++
net/d80211/sta_info.c | 114 +++++++++++++------
net/d80211/sta_info.h | 11 +-
7 files changed, 331 insertions(+), 45 deletions(-)
create mode 100644 net/d80211/ieee80211_sysfs_sta.c
ed88547db8f143b83cf336c93221400edc2b3d81
diff --git a/net/d80211/Makefile b/net/d80211/Makefile
index 66bfcff..7d1ec29 100644
--- a/net/d80211/Makefile
+++ b/net/d80211/Makefile
@@ -12,6 +12,7 @@ obj-$(CONFIG_D80211) += 80211.o rate_con
ieee80211_dev.o \
ieee80211_iface.o \
ieee80211_sysfs.o \
+ ieee80211_sysfs_sta.o \
michael.o \
tkip.o \
aes_ccm.o \
diff --git a/net/d80211/ieee80211.c b/net/d80211/ieee80211.c
index 0c23607..15d43f8 100644
--- a/net/d80211/ieee80211.c
+++ b/net/d80211/ieee80211.c
@@ -4188,7 +4188,9 @@ int ieee80211_register_hw(struct net_dev
ieee80211_update_hw(dev, hw); /* Don't care about the result. */
- sta_info_start(local);
+ result = sta_info_start(local);
+ if (result < 0)
+ goto fail_sta_info;
if (hw->fraglist)
dev->features |= NETIF_F_FRAGLIST;
@@ -4237,6 +4239,7 @@ fail_if_sysfs:
unregister_netdev(dev);
fail_dev:
sta_info_stop(local);
+fail_sta_info:
ieee80211_dev_sysfs_del(local);
fail_sysfs:
ieee80211_dev_free_index(local);
diff --git a/net/d80211/ieee80211_i.h b/net/d80211/ieee80211_i.h
index 7c1b621..212d12f 100644
--- a/net/d80211/ieee80211_i.h
+++ b/net/d80211/ieee80211_i.h
@@ -344,9 +344,11 @@ #define IEEE80211_IRQSAFE_QUEUE_LIMIT 12
spinlock_t generic_lock;
/* Station data structures */
+ struct kset sta_kset;
spinlock_t sta_lock; /* mutex for STA data structures */
int num_sta; /* number of stations in sta_list */
struct list_head sta_list;
+ struct list_head deleted_sta_list;
struct sta_info *sta_hash[STA_HASH_SIZE];
struct timer_list sta_cleanup;
@@ -511,6 +513,12 @@ #endif /* CONFIG_D80211_DEBUG_COUNTERS *
int user_space_mlme;
};
+struct sta_attribute {
+ struct attribute attr;
+ ssize_t (*show)(const struct sta_info *, char *buf);
+ ssize_t (*store)(struct sta_info *, const char *buf, size_t count);
+};
+
/* ieee80211.c */
void ieee80211_release_hw(struct ieee80211_local *local);
@@ -620,4 +628,10 @@ int ieee80211_sysfs_init(void);
void ieee80211_sysfs_deinit(void);
int ieee80211_sysfs_change_if_type(struct net_device *dev);
+/* ieee80211_sysfs_sta.c */
+int ieee80211_sta_kset_sysfs_register(struct ieee80211_local *local);
+void ieee80211_sta_kset_sysfs_unregister(struct ieee80211_local *local);
+int ieee80211_sta_sysfs_add(struct sta_info *sta);
+void ieee80211_sta_sysfs_remove(struct sta_info *sta);
+
#endif /* IEEE80211_I_H */
diff --git a/net/d80211/ieee80211_proc.c b/net/d80211/ieee80211_proc.c
index 581b583..4bb3179 100644
--- a/net/d80211/ieee80211_proc.c
+++ b/net/d80211/ieee80211_proc.c
@@ -241,7 +241,6 @@ static int ieee80211_proc_sta_read(char
if (!sta || !sta->dev)
return -1;
- p += sprintf(p, "users=%d\n", atomic_read(&sta->users));
p += sprintf(p, "aid=%d\n", sta->aid);
p += sprintf(p, "flags=0x%x %s%s%s%s%s%s%s%s%s%s\n", sta->flags,
sta->flags & WLAN_STA_AUTH ? "[AUTH]" : "",
@@ -656,7 +655,6 @@ void ieee80211_proc_init_sta(struct ieee
ieee80211_proc_sta_read, sta);
if (entry) {
entry->mode &= ~(S_IRWXG | S_IRWXO);
- sta->proc_entry_added = 1;
}
}
@@ -668,7 +666,6 @@ void ieee80211_proc_deinit_sta(struct ie
sprintf(buf, MACSTR, MAC2STR(sta->addr));
if (local->proc_sta) {
remove_proc_entry(buf, local->proc_sta);
- sta->proc_entry_added = 0;
}
}
diff --git a/net/d80211/ieee80211_sysfs_sta.c b/net/d80211/ieee80211_sysfs_sta.c
new file mode 100644
index 0000000..07de564
--- /dev/null
+++ b/net/d80211/ieee80211_sysfs_sta.c
@@ -0,0 +1,228 @@
+/*
+ * Copyright 2003-2005, Devicescape Software, Inc.
+ * Copyright (c) 2006 Jiri Benc <jbenc@suse.cz>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kobject.h>
+#include <linux/sysfs.h>
+#include "ieee80211_i.h"
+#include "sta_info.h"
+
+static ssize_t sta_sysfs_show(struct kobject *, struct attribute *, char *);
+
+static struct sysfs_ops sta_ktype_ops = {
+ .show = sta_sysfs_show,
+};
+
+#define STA_SHOW(name, field, format_string) \
+static ssize_t show_sta_##name(const struct sta_info *sta, char *buf) \
+{ \
+ return sprintf(buf, format_string, sta->field); \
+}
+#define STA_SHOW_D(name, field) STA_SHOW(name, field, "%d\n")
+#define STA_SHOW_U(name, field) STA_SHOW(name, field, "%u\n")
+#define STA_SHOW_LU(name, field) STA_SHOW(name, field, "%lu\n")
+#define STA_SHOW_S(name, field) STA_SHOW(name, field, "%s\n")
+
+#define STA_SHOW_RATE(name, field) \
+static ssize_t show_sta_##name(const struct sta_info *sta, char *buf) \
+{ \
+ struct ieee80211_local *local = sta->dev->ieee80211_ptr; \
+ return sprintf(buf, "%d\n", \
+ (sta->field >= 0 && \
+ sta->field < local->num_curr_rates) ? \
+ local->curr_rates[sta->field].rate : -1); \
+}
+
+#define __STA_ATTR(name) \
+static struct sta_attribute sta_attr_##name = \
+ __ATTR(name, S_IRUSR, show_sta_##name, NULL)
+
+#define STA_ATTR(name, field, format) \
+ STA_SHOW_##format(name, field) \
+ __STA_ATTR(name)
+
+STA_ATTR(aid, aid, D);
+STA_ATTR(key_idx_compression, key_idx_compression, D);
+STA_ATTR(dev, dev->name, S);
+STA_ATTR(vlan_id, vlan_id, D);
+STA_ATTR(rx_packets, rx_packets, LU);
+STA_ATTR(tx_packets, tx_packets, LU);
+STA_ATTR(rx_bytes, rx_bytes, LU);
+STA_ATTR(tx_bytes, tx_bytes, LU);
+STA_ATTR(rx_duplicates, num_duplicates, LU);
+STA_ATTR(rx_fragments, rx_fragments, LU);
+STA_ATTR(rx_dropped, rx_dropped, LU);
+STA_ATTR(tx_fragments, tx_fragments, LU);
+STA_ATTR(tx_filtered, tx_filtered_count, LU);
+STA_ATTR(txrate, txrate, RATE);
+STA_ATTR(last_txrate, last_txrate, RATE);
+STA_ATTR(tx_retry_failed, tx_retry_failed, LU);
+STA_ATTR(tx_retry_count, tx_retry_count, LU);
+STA_ATTR(last_rssi, last_rssi, D);
+STA_ATTR(channel_use, channel_use, D);
+STA_ATTR(wep_weak_iv_count, wep_weak_iv_count, D);
+
+static ssize_t show_sta_flags(const struct sta_info *sta, char *buf)
+{
+ return sprintf(buf, "%s%s%s%s%s%s%s%s%s%s",
+ sta->flags & WLAN_STA_AUTH ? "AUTH\n" : "",
+ sta->flags & WLAN_STA_ASSOC ? "ASSOC\n" : "",
+ sta->flags & WLAN_STA_PS ? "PS\n" : "",
+ sta->flags & WLAN_STA_TIM ? "TIM\n" : "",
+ sta->flags & WLAN_STA_PERM ? "PERM\n" : "",
+ sta->flags & WLAN_STA_AUTHORIZED ? "AUTHORIZED\n" : "",
+ sta->flags & WLAN_STA_SHORT_PREAMBLE ?
+ "SHORT PREAMBLE\n" : "",
+ sta->flags & WLAN_STA_WME ? "WME\n" : "",
+ sta->flags & WLAN_STA_WDS ? "WDS\n" : "",
+ sta->flags & WLAN_STA_XR ? "XR\n" : "");
+}
+__STA_ATTR(flags);
+
+static ssize_t show_sta_num_ps_buf_frames(const struct sta_info *sta, char *buf)
+{
+ return sprintf(buf, "%u\n", skb_queue_len(&sta->ps_tx_buf));
+}
+__STA_ATTR(num_ps_buf_frames);
+
+static ssize_t show_sta_last_ack_rssi(const struct sta_info *sta, char *buf)
+{
+ return sprintf(buf, "%d %d %d\n", sta->last_ack_rssi[0],
+ sta->last_ack_rssi[1], sta->last_ack_rssi[2]);
+}
+__STA_ATTR(last_ack_rssi);
+
+static ssize_t show_sta_last_ack_ms(const struct sta_info *sta, char *buf)
+{
+ return sprintf(buf, "%d\n", sta->last_ack ?
+ jiffies_to_msecs(jiffies - sta->last_ack) : -1);
+}
+__STA_ATTR(last_ack_ms);
+
+static ssize_t show_sta_inactive_ms(const struct sta_info *sta, char *buf)
+{
+ return sprintf(buf, "%d\n", jiffies_to_msecs(jiffies - sta->last_rx));
+}
+__STA_ATTR(inactive_ms);
+
+static ssize_t show_sta_last_seq_ctrl(const struct sta_info *sta, char *buf)
+{
+ int i;
+ char *p = buf;
+
+ for (i = 0; i < NUM_RX_DATA_QUEUES; i++)
+ p += sprintf(p, "%x ", sta->last_seq_ctrl[i]);
+ p += sprintf(p, "\n");
+ return (p - buf);
+}
+__STA_ATTR(last_seq_ctrl);
+
+#ifdef CONFIG_D80211_DEBUG_COUNTERS
+static ssize_t show_sta_wme_rx_queue(const struct sta_info *sta, char *buf)
+{
+ int i;
+ char *p = buf;
+
+ for (i = 0; i < NUM_RX_DATA_QUEUES; i++)
+ p += sprintf(p, "%u ", sta->wme_rx_queue[i]);
+ p += sprintf(p, "\n");
+ return (p - buf);
+}
+__STA_ATTR(wme_rx_queue);
+
+static ssize_t show_sta_wme_tx_queue(const struct sta_info *sta, char *buf)
+{
+ int i;
+ char *p = buf;
+
+ for (i = 0; i < NUM_RX_DATA_QUEUES; i++)
+ p += sprintf(p, "%u ", sta->wme_tx_queue[i]);
+ p += sprintf(p, "\n");
+ return (p - buf);
+}
+__STA_ATTR(wme_tx_queue);
+#endif
+
+static struct attribute *sta_ktype_attrs[] = {
+ &sta_attr_aid.attr,
+ &sta_attr_key_idx_compression.attr,
+ &sta_attr_dev.attr,
+ &sta_attr_vlan_id.attr,
+ &sta_attr_rx_packets.attr,
+ &sta_attr_tx_packets.attr,
+ &sta_attr_rx_bytes.attr,
+ &sta_attr_tx_bytes.attr,
+ &sta_attr_rx_duplicates.attr,
+ &sta_attr_rx_fragments.attr,
+ &sta_attr_rx_dropped.attr,
+ &sta_attr_tx_fragments.attr,
+ &sta_attr_tx_filtered.attr,
+ &sta_attr_txrate.attr,
+ &sta_attr_last_txrate.attr,
+ &sta_attr_tx_retry_failed.attr,
+ &sta_attr_tx_retry_count.attr,
+ &sta_attr_last_rssi.attr,
+ &sta_attr_channel_use.attr,
+ &sta_attr_wep_weak_iv_count.attr,
+
+ &sta_attr_flags.attr,
+ &sta_attr_num_ps_buf_frames.attr,
+ &sta_attr_last_ack_rssi.attr,
+ &sta_attr_last_ack_ms.attr,
+ &sta_attr_inactive_ms.attr,
+ &sta_attr_last_seq_ctrl.attr,
+#ifdef CONFIG_D80211_DEBUG_COUNTERS
+ &sta_attr_wme_rx_queue.attr,
+ &sta_attr_wme_tx_queue.attr,
+#endif
+ NULL
+};
+
+static struct kobj_type sta_ktype = {
+ .release = sta_info_release,
+ .sysfs_ops = &sta_ktype_ops,
+ .default_attrs = sta_ktype_attrs,
+};
+
+static ssize_t sta_sysfs_show(struct kobject *kobj, struct attribute *attr,
+ char *buf)
+{
+ struct sta_attribute *sta_attr;
+ struct sta_info *sta;
+
+ sta_attr = container_of(attr, struct sta_attribute, attr);
+ sta = container_of(kobj, struct sta_info, kobj);
+ return sta_attr->show(sta, buf);
+}
+
+int ieee80211_sta_kset_sysfs_register(struct ieee80211_local *local)
+{
+ int res;
+
+ res = kobject_set_name(&local->sta_kset.kobj, "sta");
+ if (res)
+ return res;
+ local->sta_kset.kobj.parent = &local->class_dev.kobj;
+ local->sta_kset.ktype = &sta_ktype;
+ return kset_register(&local->sta_kset);
+}
+
+void ieee80211_sta_kset_sysfs_unregister(struct ieee80211_local *local)
+{
+ kset_unregister(&local->sta_kset);
+}
+
+int ieee80211_sta_sysfs_add(struct sta_info *sta)
+{
+ return kobject_add(&sta->kobj);
+}
+
+void ieee80211_sta_sysfs_remove(struct sta_info *sta)
+{
+ kobject_del(&sta->kobj);
+}
diff --git a/net/d80211/sta_info.c b/net/d80211/sta_info.c
index 9565c29..bba4771 100644
--- a/net/d80211/sta_info.c
+++ b/net/d80211/sta_info.c
@@ -10,6 +10,7 @@ #include <linux/config.h>
#include <linux/version.h>
#include <linux/module.h>
#include <linux/init.h>
+#include <linux/kobject.h>
#include <linux/netdevice.h>
#include <linux/types.h>
#include <linux/slab.h>
@@ -55,6 +56,10 @@ static void sta_info_hash_del(struct iee
"hash table\n", local->mdev->name, MAC2STR(sta->addr));
}
+static inline struct sta_info *__sta_info_get(struct sta_info *sta)
+{
+ return kobject_get(&sta->kobj) ? sta : NULL;
+}
struct sta_info * sta_info_get(struct ieee80211_local *local, u8 *addr)
{
@@ -64,7 +69,7 @@ struct sta_info * sta_info_get(struct ie
sta = local->sta_hash[STA_HASH(addr)];
while (sta) {
if (memcmp(sta->addr, addr, ETH_ALEN) == 0) {
- atomic_inc(&sta->users);
+ __sta_info_get(sta);
break;
}
sta = sta->hnext;
@@ -74,7 +79,6 @@ struct sta_info * sta_info_get(struct ie
return sta;
}
-
int sta_info_min_txrate_get(struct ieee80211_local *local)
{
struct sta_info *sta;
@@ -100,10 +104,14 @@ int sta_info_min_txrate_get(struct ieee8
void sta_info_put(struct ieee80211_local *local, struct sta_info *sta)
{
- struct sk_buff *skb;
+ kobject_put(&sta->kobj);
+}
- if (!atomic_dec_and_test(&sta->users))
- return;
+void sta_info_release(struct kobject *kobj)
+{
+ struct sta_info *sta = container_of(kobj, struct sta_info, kobj);
+ struct ieee80211_local *local = sta->local;
+ struct sk_buff *skb;
/* free sta structure; it has already been removed from
* hash table etc. external structures. Make sure that all
@@ -132,20 +140,27 @@ struct sta_info * sta_info_add(struct ie
memset(sta, 0, sizeof(*sta));
+ if (kobject_set_name(&sta->kobj, MACSTR, MAC2STR(addr))) {
+ kfree(sta);
+ return NULL;
+ }
+ sta->kobj.kset = &local->sta_kset;
+ kobject_init(&sta->kobj);
+
sta->rate_ctrl_priv = rate_control_alloc_sta(local);
if (sta->rate_ctrl_priv == NULL) {
+ kobject_put(&sta->kobj);
kfree(sta);
return NULL;
}
memcpy(sta->addr, addr, ETH_ALEN);
+ sta->local = local;
sta->dev = dev;
skb_queue_head_init(&sta->ps_tx_buf);
skb_queue_head_init(&sta->tx_filtered);
- atomic_inc(&sta->users); /* sta in hashlist etc, decremented by
- * sta_info_free() */
- atomic_inc(&sta->users); /* sta used by caller, decremented by
- * sta_info_put() */
+ __sta_info_get(sta); /* sta used by caller, decremented by
+ * sta_info_put() */
spin_lock_bh(&local->sta_lock);
list_add(&sta->list, &local->sta_list);
local->num_sta++;
@@ -161,6 +176,8 @@ #ifdef CONFIG_D80211_VERBOSE_DEBUG
#endif /* CONFIG_D80211_VERBOSE_DEBUG */
if (!in_interrupt()) {
+ sta->sysfs_registered = 1;
+ ieee80211_sta_sysfs_add(sta);
ieee80211_proc_init_sta(local, sta);
} else {
/* procfs entry adding might sleep, so schedule process context
@@ -172,6 +189,19 @@ #endif /* CONFIG_D80211_VERBOSE_DEBUG */
return sta;
}
+static void finish_sta_info_free(struct ieee80211_local *local,
+ struct sta_info *sta)
+{
+#ifdef CONFIG_D80211_VERBOSE_DEBUG
+ printk(KERN_DEBUG "%s: Removed STA " MACSTR "\n",
+ local->mdev->name, MAC2STR(sta->addr));
+#endif /* CONFIG_D80211_VERBOSE_DEBUG */
+
+ ieee80211_proc_deinit_sta(local, sta);
+ ieee80211_sta_sysfs_remove(sta);
+
+ sta_info_put(local, sta);
+}
void sta_info_free(struct ieee80211_local *local, struct sta_info *sta,
int locked)
@@ -227,23 +257,11 @@ void sta_info_free(struct ieee80211_loca
sta->key_idx_compression = HW_KEY_IDX_INVALID;
}
-#ifdef CONFIG_D80211_VERBOSE_DEBUG
- printk(KERN_DEBUG "%s: Removed STA " MACSTR "\n",
- local->mdev->name, MAC2STR(sta->addr));
-#endif /* CONFIG_D80211_VERBOSE_DEBUG */
-
- ieee80211_proc_deinit_sta(local, sta);
-
- if (atomic_read(&sta->users) != 1) {
- /* This is OK, but printed for debugging. The station structure
- * will be removed when the other user of the data calls
- * sta_info_put(). */
- printk(KERN_DEBUG "%s: STA " MACSTR " users count %d when "
- "removing it\n", local->mdev->name, MAC2STR(sta->addr),
- atomic_read(&sta->users));
- }
-
- sta_info_put(local, sta);
+ if (in_atomic()) {
+ list_add(&sta->list, &local->deleted_sta_list);
+ schedule_work(&local->sta_proc_add);
+ } else
+ finish_sta_info_free(local, sta);
}
@@ -300,7 +318,7 @@ static void sta_info_cleanup(unsigned lo
ptr = local->sta_list.next;
while (ptr && ptr != &local->sta_list) {
struct sta_info *sta = (struct sta_info *) ptr;
- atomic_inc(&sta->users);
+ __sta_info_get(sta);
sta_info_cleanup_expire_buffered(local, sta);
sta_info_put(local, sta);
ptr = ptr->next;
@@ -317,15 +335,27 @@ static void sta_info_proc_add_task(void
struct ieee80211_local *local = data;
struct list_head *ptr;
struct sta_info *sta;
- int max_adds = 100;
- while (max_adds > 0) {
- sta = NULL;
+ while (1) {
+ spin_lock_bh(&local->sta_lock);
+ if (!list_empty(&local->deleted_sta_list)) {
+ sta = list_entry(local->deleted_sta_list.next,
+ struct sta_info, list);
+ list_del(local->deleted_sta_list.next);
+ } else
+ sta = NULL;
+ spin_unlock_bh(&local->sta_lock);
+ if (!sta)
+ break;
+ finish_sta_info_free(local, sta);
+ }
+
+ while (1) {
spin_lock_bh(&local->sta_lock);
list_for_each(ptr, &local->sta_list) {
sta = list_entry(ptr, struct sta_info, list);
- if (!sta->proc_entry_added) {
- atomic_inc(&sta->users);
+ if (!sta->sysfs_registered) {
+ __sta_info_get(sta);
break;
}
sta = NULL;
@@ -335,10 +365,10 @@ static void sta_info_proc_add_task(void
if (!sta)
break;
+ sta->sysfs_registered = 1;
+ ieee80211_sta_sysfs_add(sta);
ieee80211_proc_init_sta(local, sta);
- atomic_dec(&sta->users);
-
- max_adds--;
+ sta_info_put(local, sta);
}
}
@@ -347,6 +377,7 @@ void sta_info_init(struct ieee80211_loca
{
spin_lock_init(&local->sta_lock);
INIT_LIST_HEAD(&local->sta_list);
+ INIT_LIST_HEAD(&local->deleted_sta_list);
init_timer(&local->sta_cleanup);
local->sta_cleanup.expires = jiffies + STA_INFO_CLEANUP_INTERVAL;
@@ -356,9 +387,15 @@ void sta_info_init(struct ieee80211_loca
INIT_WORK(&local->sta_proc_add, sta_info_proc_add_task, local);
}
-void sta_info_start(struct ieee80211_local *local)
+int sta_info_start(struct ieee80211_local *local)
{
+ int res;
+
+ res = ieee80211_sta_kset_sysfs_register(local);
+ if (res)
+ return res;
add_timer(&local->sta_cleanup);
+ return 0;
}
void sta_info_stop(struct ieee80211_local *local)
@@ -371,8 +408,13 @@ void sta_info_stop(struct ieee80211_loca
while (ptr && ptr != &local->sta_list) {
struct sta_info *sta = (struct sta_info *) ptr;
ptr = ptr->next;
+ /* sta_info_free must be called with 0 as the last
+ * parameter to ensure all sysfs sta entries are
+ * unregistered. We don't need locking at this
+ * point. */
sta_info_free(local, sta, 0);
}
+ ieee80211_sta_kset_sysfs_unregister(local);
}
diff --git a/net/d80211/sta_info.h b/net/d80211/sta_info.h
index fddc80e..ddfe50e 100644
--- a/net/d80211/sta_info.h
+++ b/net/d80211/sta_info.h
@@ -32,8 +32,10 @@ #define WLAN_STA_WDS BIT(27)
struct sta_info {
struct list_head list;
+ struct kobject kobj;
struct sta_info *hnext; /* next entry in hash table list */
- atomic_t users; /* number of users (do not remove if > 0) */
+
+ struct ieee80211_local *local;
u8 addr[ETH_ALEN];
u16 aid; /* STA's unique AID (1..2007), 0 = not yet assigned */
@@ -92,7 +94,7 @@ struct sta_info {
* filtering; used only if sta->key is not
* set */
- int proc_entry_added:1;
+ int sysfs_registered:1;
int assoc_ap:1; /* whether this is an AP that we are associated with
* as a client */
@@ -130,8 +132,6 @@ #define STA_TX_BUFFER_EXPIRE (10 * HZ)
*/
#define STA_INFO_CLEANUP_INTERVAL (10 * HZ)
-struct ieee80211_local;
-
struct sta_info * sta_info_get(struct ieee80211_local *local, u8 *addr);
int sta_info_min_txrate_get(struct ieee80211_local *local);
void sta_info_put(struct ieee80211_local *local, struct sta_info *sta);
@@ -139,8 +139,9 @@ struct sta_info * sta_info_add(struct ie
struct net_device *dev, u8 *addr);
void sta_info_free(struct ieee80211_local *local, struct sta_info *sta,
int locked);
+void sta_info_release(struct kobject *kobj);
void sta_info_init(struct ieee80211_local *local);
-void sta_info_start(struct ieee80211_local *local);
+int sta_info_start(struct ieee80211_local *local);
void sta_info_stop(struct ieee80211_local *local);
void sta_info_remove_aid_ptr(struct sta_info *sta);
void sta_info_flush(struct ieee80211_local *local, struct net_device *dev);
--
1.3.0
^ permalink raw reply related
* [PATCH 9/12] d80211: remove useless parameters
From: Jiri Benc @ 2006-06-08 7:49 UTC (permalink / raw)
To: netdev; +Cc: John W. Linville
In-Reply-To: <20060608094822.014829000.midnight@suse.cz>
There is no necessity for passing ieee80211_local parameter to sta_info_put
and sta_info_free now.
Signed-off-by: Jiri Benc <jbenc@suse.cz>
---
net/d80211/ieee80211.c | 18 +++++++++---------
net/d80211/ieee80211_iface.c | 4 ++--
net/d80211/ieee80211_ioctl.c | 20 ++++++++++----------
net/d80211/ieee80211_sta.c | 8 ++++----
net/d80211/rate_control.c | 4 ++--
net/d80211/sta_info.c | 16 ++++++++--------
net/d80211/sta_info.h | 5 ++---
7 files changed, 37 insertions(+), 38 deletions(-)
bc9e55deef4924f5a4ba82487747726413636df6
diff --git a/net/d80211/ieee80211.c b/net/d80211/ieee80211.c
index 15d43f8..75aaa99 100644
--- a/net/d80211/ieee80211.c
+++ b/net/d80211/ieee80211.c
@@ -1153,7 +1153,7 @@ static int ieee80211_tx(struct net_devic
skb = tx.skb; /* handlers are allowed to change skb */
if (sta)
- sta_info_put(local, sta);
+ sta_info_put(sta);
if (unlikely(res == TXRX_DROP)) {
I802_DEBUG_INC(local->tx_handlers_drop);
@@ -1373,7 +1373,7 @@ static int ieee80211_subif_start_xmit(st
fc |= WLAN_FC_STYPE_QOS_DATA << 4;
hdrlen += 2;
}
- sta_info_put(local, sta);
+ sta_info_put(sta);
}
hdr.frame_control = cpu_to_le16(fc);
@@ -1743,7 +1743,7 @@ ieee80211_get_buffered_bc(struct net_dev
}
if (sta)
- sta_info_put(local, sta);
+ sta_info_put(sta);
return skb;
}
@@ -2330,7 +2330,7 @@ ieee80211_rx_h_data(struct ieee80211_txr
skb = NULL;
}
if (dsta)
- sta_info_put(local, dsta);
+ sta_info_put(dsta);
}
}
@@ -3469,7 +3469,7 @@ void __ieee80211_rx(struct net_device *d
end:
if (sta)
- sta_info_put(local, sta);
+ sta_info_put(sta);
}
@@ -3806,7 +3806,7 @@ void ieee80211_tx_status(struct net_devi
status->excessive_retries = 0;
status->tx_filtered = 1;
}
- sta_info_put(local, sta);
+ sta_info_put(sta);
}
}
@@ -3855,7 +3855,7 @@ void ieee80211_tx_status(struct net_devi
}
dev_kfree_skb(skb);
}
- sta_info_put(local, sta);
+ sta_info_put(sta);
return;
}
} else {
@@ -3978,8 +3978,8 @@ int ieee80211_if_update_wds(struct net_d
/* Remove STA entry for the old peer */
sta = sta_info_get(local, sdata->u.wds.remote_addr);
if (sta) {
- sta_info_put(local, sta);
- sta_info_free(local, sta, 0);
+ sta_info_put(sta);
+ sta_info_free(sta, 0);
} else {
printk(KERN_DEBUG "%s: could not find STA entry for WDS link "
"peer " MACSTR "\n",
diff --git a/net/d80211/ieee80211_iface.c b/net/d80211/ieee80211_iface.c
index 467dcba..960a90e 100644
--- a/net/d80211/ieee80211_iface.c
+++ b/net/d80211/ieee80211_iface.c
@@ -261,8 +261,8 @@ #endif
case IEEE80211_IF_TYPE_WDS:
sta = sta_info_get(local, sdata->u.wds.remote_addr);
if (sta) {
- sta_info_put(local, sta);
- sta_info_free(local, sta, 0);
+ sta_info_put(sta);
+ sta_info_free(sta, 0);
} else {
#ifdef CONFIG_D80211_VERBOSE_DEBUG
printk(KERN_DEBUG "%s: Someone had deleted my STA "
diff --git a/net/d80211/ieee80211_ioctl.c b/net/d80211/ieee80211_ioctl.c
index e1bdc03..562b9f3 100644
--- a/net/d80211/ieee80211_ioctl.c
+++ b/net/d80211/ieee80211_ioctl.c
@@ -294,7 +294,7 @@ static int ieee80211_ioctl_add_sta(struc
}
}
- sta_info_put(local, sta);
+ sta_info_put(sta);
return 0;
}
@@ -308,8 +308,8 @@ static int ieee80211_ioctl_remove_sta(st
sta = sta_info_get(local, param->sta_addr);
if (sta) {
- sta_info_put(local, sta);
- sta_info_free(local, sta, 1);
+ sta_info_put(sta);
+ sta_info_free(sta, 1);
}
return sta ? 0 : -ENOENT;
@@ -393,7 +393,7 @@ static int ieee80211_ioctl_get_info_sta(
param->u.get_info_sta.last_rssi = sta->last_rssi;
param->u.get_info_sta.last_ack_rssi = sta->last_ack_rssi[2];
- sta_info_put(local, sta);
+ sta_info_put(sta);
return 0;
}
@@ -421,7 +421,7 @@ static int ieee80211_ioctl_set_flags_sta
printk(KERN_DEBUG "%s: failed to set low-level driver "
"PAE state (unauthorized) for " MACSTR "\n",
dev->name, MAC2STR(sta->addr));
- sta_info_put(local, sta);
+ sta_info_put(sta);
}
return sta ? 0 : -ENOENT;
@@ -563,7 +563,7 @@ #endif /* CONFIG_D80211_VERBOSE_DEBUG */
if (sta->flags & WLAN_STA_WME) {
try_hwaccel = 0;
}
- sta_info_put(local, sta);
+ sta_info_put(sta);
sta = NULL;
}
}
@@ -643,7 +643,7 @@ #endif /* CONFIG_D80211_VERBOSE_DEBUG */
done:
if (sta)
- sta_info_put(local, sta);
+ sta_info_put(sta);
return ret;
}
@@ -813,7 +813,7 @@ static int ieee80211_ioctl_get_encryptio
}
if (sta)
- sta_info_put(local, sta);
+ sta_info_put(sta);
return ret;
}
@@ -842,7 +842,7 @@ static int ieee80211_ioctl_wpa_trigger(s
sta->wpa_trigger = param->u.wpa_trigger.trigger;
- sta_info_put(local, sta);
+ sta_info_put(sta);
return 0;
}
#endif /* CONFIG_HOSTAPD_WPA_TESTING */
@@ -1136,7 +1136,7 @@ #endif
sta->vlan_id = param->u.set_sta_vlan.vlan_id;
dev_put(new_vlan_dev);
}
- sta_info_put(local, sta);
+ sta_info_put(sta);
}
return sta ? 0 : -ENOENT;
diff --git a/net/d80211/ieee80211_sta.c b/net/d80211/ieee80211_sta.c
index a42c387..37d40aa 100644
--- a/net/d80211/ieee80211_sta.c
+++ b/net/d80211/ieee80211_sta.c
@@ -730,7 +730,7 @@ static void ieee80211_associated(struct
ifsta->ssid_len);
}
}
- sta_info_put(local, sta);
+ sta_info_put(sta);
}
if (disassoc) {
union iwreq_data wrqu;
@@ -1200,7 +1200,7 @@ static void ieee80211_rx_mgmt_assoc_resp
}
- sta_info_put(local, sta);
+ sta_info_put(sta);
ieee80211_associated(dev, ifsta);
}
@@ -1443,7 +1443,7 @@ #endif /* IEEE80211_IBSS_DEBUG */
dev->name, MAC2STR(sta->addr), prev_rates,
supp_rates, sta->supp_rates);
}
- sta_info_put(local, sta);
+ sta_info_put(sta);
}
if (elems.ssid == NULL)
@@ -1836,7 +1836,7 @@ static void ieee80211_sta_expire(struct
IEEE80211_IBSS_INACTIVITY_LIMIT)) {
printk(KERN_DEBUG "%s: expiring inactive STA " MACSTR
"\n", dev->name, MAC2STR(sta->addr));
- sta_info_free(local, sta, 1);
+ sta_info_free(sta, 1);
}
}
spin_unlock_bh(&local->sta_lock);
diff --git a/net/d80211/rate_control.c b/net/d80211/rate_control.c
index 9bcb8fc..e7e6791 100644
--- a/net/d80211/rate_control.c
+++ b/net/d80211/rate_control.c
@@ -209,7 +209,7 @@ #endif /* CONFIG_D80211_VERBOSE_DEBUG */
}
}
- sta_info_put(local, sta);
+ sta_info_put(sta);
}
@@ -260,7 +260,7 @@ rate_control_simple_get_rate(struct net_
extra->nonerp_idx = nonerp_idx;
extra->nonerp = &local->curr_rates[extra->nonerp_idx];
- sta_info_put(local, sta);
+ sta_info_put(sta);
return &local->curr_rates[rateidx];
}
diff --git a/net/d80211/sta_info.c b/net/d80211/sta_info.c
index bba4771..9c6adaa 100644
--- a/net/d80211/sta_info.c
+++ b/net/d80211/sta_info.c
@@ -102,7 +102,7 @@ int sta_info_min_txrate_get(struct ieee8
}
-void sta_info_put(struct ieee80211_local *local, struct sta_info *sta)
+void sta_info_put(struct sta_info *sta)
{
kobject_put(&sta->kobj);
}
@@ -200,13 +200,13 @@ #endif /* CONFIG_D80211_VERBOSE_DEBUG */
ieee80211_proc_deinit_sta(local, sta);
ieee80211_sta_sysfs_remove(sta);
- sta_info_put(local, sta);
+ sta_info_put(sta);
}
-void sta_info_free(struct ieee80211_local *local, struct sta_info *sta,
- int locked)
+void sta_info_free(struct sta_info *sta, int locked)
{
struct sk_buff *skb;
+ struct ieee80211_local *local = sta->local;
struct ieee80211_sub_if_data *sdata;
if (!locked)
@@ -320,7 +320,7 @@ static void sta_info_cleanup(unsigned lo
struct sta_info *sta = (struct sta_info *) ptr;
__sta_info_get(sta);
sta_info_cleanup_expire_buffered(local, sta);
- sta_info_put(local, sta);
+ sta_info_put(sta);
ptr = ptr->next;
}
spin_unlock_bh(&local->sta_lock);
@@ -368,7 +368,7 @@ static void sta_info_proc_add_task(void
sta->sysfs_registered = 1;
ieee80211_sta_sysfs_add(sta);
ieee80211_proc_init_sta(local, sta);
- sta_info_put(local, sta);
+ sta_info_put(sta);
}
}
@@ -412,7 +412,7 @@ void sta_info_stop(struct ieee80211_loca
* parameter to ensure all sysfs sta entries are
* unregistered. We don't need locking at this
* point. */
- sta_info_free(local, sta, 0);
+ sta_info_free(sta, 0);
}
ieee80211_sta_kset_sysfs_unregister(local);
}
@@ -449,7 +449,7 @@ void sta_info_flush(struct ieee80211_loc
list_for_each_safe(ptr, n, &local->sta_list) {
struct sta_info *sta = list_entry(ptr, struct sta_info, list);
if (dev == NULL || dev == sta->dev)
- sta_info_free(local, sta, 1);
+ sta_info_free(sta, 1);
}
spin_unlock_bh(&local->sta_lock);
}
diff --git a/net/d80211/sta_info.h b/net/d80211/sta_info.h
index ddfe50e..70334e5 100644
--- a/net/d80211/sta_info.h
+++ b/net/d80211/sta_info.h
@@ -134,11 +134,10 @@ #define STA_INFO_CLEANUP_INTERVAL (10 *
struct sta_info * sta_info_get(struct ieee80211_local *local, u8 *addr);
int sta_info_min_txrate_get(struct ieee80211_local *local);
-void sta_info_put(struct ieee80211_local *local, struct sta_info *sta);
+void sta_info_put(struct sta_info *sta);
struct sta_info * sta_info_add(struct ieee80211_local *local,
struct net_device *dev, u8 *addr);
-void sta_info_free(struct ieee80211_local *local, struct sta_info *sta,
- int locked);
+void sta_info_free(struct sta_info *sta, int locked);
void sta_info_release(struct kobject *kobj);
void sta_info_init(struct ieee80211_local *local);
int sta_info_start(struct ieee80211_local *local);
--
1.3.0
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox