Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
linux
Commits
3f1f39c4
Commit
3f1f39c4
authored
May 29, 2009
by
David S. Miller
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'linux-2.6.31.y' of
git://git.kernel.org/pub/scm/linux/kernel/git/inaky/wimax
parents
dfe9a837
7481806d
Changes
14
Show whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
222 additions
and
69 deletions
+222
-69
drivers/net/wimax/i2400m/control.c
drivers/net/wimax/i2400m/control.c
+55
-45
drivers/net/wimax/i2400m/driver.c
drivers/net/wimax/i2400m/driver.c
+2
-3
drivers/net/wimax/i2400m/i2400m.h
drivers/net/wimax/i2400m/i2400m.h
+5
-0
drivers/net/wimax/i2400m/netdev.c
drivers/net/wimax/i2400m/netdev.c
+3
-1
drivers/net/wimax/i2400m/rx.c
drivers/net/wimax/i2400m/rx.c
+5
-1
drivers/net/wimax/i2400m/sdio.c
drivers/net/wimax/i2400m/sdio.c
+9
-9
drivers/net/wimax/i2400m/usb.c
drivers/net/wimax/i2400m/usb.c
+30
-5
include/linux/wimax.h
include/linux/wimax.h
+6
-1
net/wimax/Makefile
net/wimax/Makefile
+1
-0
net/wimax/debug-levels.h
net/wimax/debug-levels.h
+1
-0
net/wimax/debugfs.c
net/wimax/debugfs.c
+1
-0
net/wimax/op-msg.c
net/wimax/op-msg.c
+14
-3
net/wimax/op-state-get.c
net/wimax/op-state-get.c
+86
-0
net/wimax/stack.c
net/wimax/stack.c
+4
-1
No files found.
drivers/net/wimax/i2400m/control.c
View file @
3f1f39c4
...
...
@@ -292,8 +292,6 @@ void i2400m_report_tlv_system_state(struct i2400m *i2400m,
d_fnstart
(
3
,
dev
,
"(i2400m %p ss %p [%u])
\n
"
,
i2400m
,
ss
,
i2400m_state
);
if
(
unlikely
(
i2400m
->
ready
==
0
))
/* act if up */
goto
out
;
if
(
i2400m
->
state
!=
i2400m_state
)
{
i2400m
->
state
=
i2400m_state
;
wake_up_all
(
&
i2400m
->
state_wq
);
...
...
@@ -341,7 +339,6 @@ void i2400m_report_tlv_system_state(struct i2400m *i2400m,
i2400m
->
bus_reset
(
i2400m
,
I2400M_RT_WARM
);
break
;
};
out:
d_fnend
(
3
,
dev
,
"(i2400m %p ss %p [%u]) = void
\n
"
,
i2400m
,
ss
,
i2400m_state
);
}
...
...
@@ -372,8 +369,6 @@ void i2400m_report_tlv_media_status(struct i2400m *i2400m,
d_fnstart
(
3
,
dev
,
"(i2400m %p ms %p [%u])
\n
"
,
i2400m
,
ms
,
status
);
if
(
unlikely
(
i2400m
->
ready
==
0
))
/* act if up */
goto
out
;
switch
(
status
)
{
case
I2400M_MEDIA_STATUS_LINK_UP
:
netif_carrier_on
(
net_dev
);
...
...
@@ -393,50 +388,32 @@ void i2400m_report_tlv_media_status(struct i2400m *i2400m,
dev_err
(
dev
,
"HW BUG? unknown media status %u
\n
"
,
status
);
};
out:
d_fnend
(
3
,
dev
,
"(i2400m %p ms %p [%u]) = void
\n
"
,
i2400m
,
ms
,
status
);
}
/*
* P
arse a 'state report' and extract carrier on/off information
* P
rocess a TLV from a 'state report'
*
* @i2400m: device descriptor
* @
l3l4_hdr: pointer to message
; it has been already validated for
* @
tlv: pointer to the TLV header
; it has been already validated for
* consistent size.
* @size: size of the message (header + payload). The header length
* declaration is assumed to be congruent with @size (as in
* sizeof(*l3l4_hdr) + l3l4_hdr->length == size)
*
* Extract from the report state the system state TLV and infer from
* there if we have a carrier or not. Update our local state and tell
* netdev.
* @tag: for error messages
*
* When setting the carrier, it's fine to set OFF twice (for example),
* as netif_carrier_off() will not generate two OFF events (just on
* the transitions).
* Act on the TLVs from a 'state report'.
*/
static
void
i2400m_report_state_
hook
(
struct
i2400m
*
i2400m
,
const
struct
i2400m_l3l4_hdr
*
l3l4_hdr
,
size_t
size
,
const
char
*
tag
)
void
i2400m_report_state_
parse_tlv
(
struct
i2400m
*
i2400m
,
const
struct
i2400m_tlv_hdr
*
tlv
,
const
char
*
tag
)
{
struct
device
*
dev
=
i2400m_dev
(
i2400m
);
const
struct
i2400m_tlv_
hdr
*
tlv
;
const
struct
i2400m_tlv_
media_status
*
ms
;
const
struct
i2400m_tlv_system_state
*
ss
;
const
struct
i2400m_tlv_rf_switches_status
*
rfss
;
const
struct
i2400m_tlv_media_status
*
ms
;
size_t
tlv_size
=
le16_to_cpu
(
l3l4_hdr
->
length
);
d_fnstart
(
4
,
dev
,
"(i2400m %p, l3l4_hdr %p, size %zu, %s)
\n
"
,
i2400m
,
l3l4_hdr
,
size
,
tag
);
tlv
=
NULL
;
while
((
tlv
=
i2400m_tlv_buffer_walk
(
i2400m
,
&
l3l4_hdr
->
pl
,
tlv_size
,
tlv
)))
{
if
(
0
==
i2400m_tlv_match
(
tlv
,
I2400M_TLV_SYSTEM_STATE
,
sizeof
(
*
ss
)))
{
if
(
0
==
i2400m_tlv_match
(
tlv
,
I2400M_TLV_SYSTEM_STATE
,
sizeof
(
*
ss
)))
{
ss
=
container_of
(
tlv
,
typeof
(
*
ss
),
hdr
);
d_printf
(
2
,
dev
,
"%s: system state TLV "
"found (0x%04x), state 0x%08x
\n
"
,
...
...
@@ -444,8 +421,7 @@ void i2400m_report_state_hook(struct i2400m *i2400m,
le32_to_cpu
(
ss
->
state
));
i2400m_report_tlv_system_state
(
i2400m
,
ss
);
}
if
(
0
==
i2400m_tlv_match
(
tlv
,
I2400M_TLV_RF_STATUS
,
sizeof
(
*
rfss
)))
{
if
(
0
==
i2400m_tlv_match
(
tlv
,
I2400M_TLV_RF_STATUS
,
sizeof
(
*
rfss
)))
{
rfss
=
container_of
(
tlv
,
typeof
(
*
rfss
),
hdr
);
d_printf
(
2
,
dev
,
"%s: RF status TLV "
"found (0x%04x), sw 0x%02x hw 0x%02x
\n
"
,
...
...
@@ -454,14 +430,43 @@ void i2400m_report_state_hook(struct i2400m *i2400m,
le32_to_cpu
(
rfss
->
hw_rf_switch
));
i2400m_report_tlv_rf_switches_status
(
i2400m
,
rfss
);
}
if
(
0
==
i2400m_tlv_match
(
tlv
,
I2400M_TLV_MEDIA_STATUS
,
sizeof
(
*
ms
)))
{
if
(
0
==
i2400m_tlv_match
(
tlv
,
I2400M_TLV_MEDIA_STATUS
,
sizeof
(
*
ms
)))
{
ms
=
container_of
(
tlv
,
typeof
(
*
ms
),
hdr
);
d_printf
(
2
,
dev
,
"%s: Media Status TLV: %u
\n
"
,
tag
,
le32_to_cpu
(
ms
->
media_status
));
i2400m_report_tlv_media_status
(
i2400m
,
ms
);
}
}
}
/*
* Parse a 'state report' and extract information
*
* @i2400m: device descriptor
* @l3l4_hdr: pointer to message; it has been already validated for
* consistent size.
* @size: size of the message (header + payload). The header length
* declaration is assumed to be congruent with @size (as in
* sizeof(*l3l4_hdr) + l3l4_hdr->length == size)
*
* Walk over the TLVs in a report state and act on them.
*/
static
void
i2400m_report_state_hook
(
struct
i2400m
*
i2400m
,
const
struct
i2400m_l3l4_hdr
*
l3l4_hdr
,
size_t
size
,
const
char
*
tag
)
{
struct
device
*
dev
=
i2400m_dev
(
i2400m
);
const
struct
i2400m_tlv_hdr
*
tlv
;
size_t
tlv_size
=
le16_to_cpu
(
l3l4_hdr
->
length
);
d_fnstart
(
4
,
dev
,
"(i2400m %p, l3l4_hdr %p, size %zu, %s)
\n
"
,
i2400m
,
l3l4_hdr
,
size
,
tag
);
tlv
=
NULL
;
while
((
tlv
=
i2400m_tlv_buffer_walk
(
i2400m
,
&
l3l4_hdr
->
pl
,
tlv_size
,
tlv
)))
i2400m_report_state_parse_tlv
(
i2400m
,
tlv
,
tag
);
d_fnend
(
4
,
dev
,
"(i2400m %p, l3l4_hdr %p, size %zu, %s) = void
\n
"
,
i2400m
,
l3l4_hdr
,
size
,
tag
);
}
...
...
@@ -721,6 +726,8 @@ struct sk_buff *i2400m_msg_to_dev(struct i2400m *i2400m,
ack_timeout
=
HZ
;
};
if
(
unlikely
(
i2400m
->
trace_msg_from_user
))
wimax_msg
(
&
i2400m
->
wimax_dev
,
"echo"
,
buf
,
buf_len
,
GFP_KERNEL
);
/* The RX path in rx.c will put any response for this message
* in i2400m->ack_skb and wake us up. If we cancel the wait,
* we need to change the value of i2400m->ack_skb to something
...
...
@@ -755,6 +762,9 @@ struct sk_buff *i2400m_msg_to_dev(struct i2400m *i2400m,
ack_l3l4_hdr
=
wimax_msg_data_len
(
ack_skb
,
&
ack_len
);
/* Check the ack and deliver it if it is ok */
if
(
unlikely
(
i2400m
->
trace_msg_from_user
))
wimax_msg
(
&
i2400m
->
wimax_dev
,
"echo"
,
ack_l3l4_hdr
,
ack_len
,
GFP_KERNEL
);
result
=
i2400m_msg_size_check
(
i2400m
,
ack_l3l4_hdr
,
ack_len
);
if
(
result
<
0
)
{
dev_err
(
dev
,
"HW BUG? reply to message 0x%04x: %d
\n
"
,
...
...
drivers/net/wimax/i2400m/driver.c
View file @
3f1f39c4
...
...
@@ -62,6 +62,7 @@
* unregister_netdev()
*/
#include "i2400m.h"
#include <linux/etherdevice.h>
#include <linux/wimax/i2400m.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
...
...
@@ -234,9 +235,6 @@ int i2400m_op_msg_from_user(struct wimax_dev *wimax_dev,
result
=
PTR_ERR
(
ack_skb
);
if
(
IS_ERR
(
ack_skb
))
goto
error_msg_to_dev
;
if
(
unlikely
(
i2400m
->
trace_msg_from_user
))
wimax_msg
(
&
i2400m
->
wimax_dev
,
"trace"
,
msg_buf
,
msg_len
,
GFP_KERNEL
);
result
=
wimax_msg_send
(
&
i2400m
->
wimax_dev
,
ack_skb
);
error_msg_to_dev:
d_fnend
(
4
,
dev
,
"(wimax_dev %p [i2400m %p] msg_buf %p msg_len %zu "
...
...
@@ -650,6 +648,7 @@ int i2400m_setup(struct i2400m *i2400m, enum i2400m_bri bm_flags)
result
=
i2400m_read_mac_addr
(
i2400m
);
if
(
result
<
0
)
goto
error_read_mac_addr
;
random_ether_addr
(
i2400m
->
src_mac_addr
);
result
=
register_netdev
(
net_dev
);
/* Okey dokey, bring it up */
if
(
result
<
0
)
{
...
...
drivers/net/wimax/i2400m/i2400m.h
View file @
3f1f39c4
...
...
@@ -323,6 +323,10 @@ struct i2400m_roq;
* delivered. Then the driver can release them to the host. See
* drivers/net/i2400m/rx.c for details.
*
* @src_mac_addr: MAC address used to make ethernet packets be coming
* from. This is generated at i2400m_setup() time and used during
* the life cycle of the instance. See i2400m_fake_eth_header().
*
* @init_mutex: Mutex used for serializing the device bringup
* sequence; this way if the device reboots in the middle, we
* don't try to do a bringup again while we are tearing down the
...
...
@@ -421,6 +425,7 @@ struct i2400m {
unsigned
rx_pl_num
,
rx_pl_max
,
rx_pl_min
,
rx_num
,
rx_size_acc
,
rx_size_min
,
rx_size_max
;
struct
i2400m_roq
*
rx_roq
;
/* not under rx_lock! */
u8
src_mac_addr
[
ETH_HLEN
];
struct
mutex
msg_mutex
;
/* serialize command execution */
struct
completion
msg_completion
;
...
...
drivers/net/wimax/i2400m/netdev.c
View file @
3f1f39c4
...
...
@@ -404,10 +404,12 @@ static
void
i2400m_rx_fake_eth_header
(
struct
net_device
*
net_dev
,
void
*
_eth_hdr
,
__be16
protocol
)
{
struct
i2400m
*
i2400m
=
net_dev_to_i2400m
(
net_dev
);
struct
ethhdr
*
eth_hdr
=
_eth_hdr
;
memcpy
(
eth_hdr
->
h_dest
,
net_dev
->
dev_addr
,
sizeof
(
eth_hdr
->
h_dest
));
memset
(
eth_hdr
->
h_source
,
0
,
sizeof
(
eth_hdr
->
h_dest
));
memcpy
(
eth_hdr
->
h_source
,
i2400m
->
src_mac_addr
,
sizeof
(
eth_hdr
->
h_source
));
eth_hdr
->
h_proto
=
protocol
;
}
...
...
drivers/net/wimax/i2400m/rx.c
View file @
3f1f39c4
...
...
@@ -177,6 +177,7 @@ void i2400m_report_hook_work(struct work_struct *ws)
struct
i2400m_work
*
iw
=
container_of
(
ws
,
struct
i2400m_work
,
ws
);
struct
i2400m_report_hook_args
*
args
=
(
void
*
)
iw
->
pl
;
if
(
iw
->
i2400m
->
ready
)
i2400m_report_hook
(
iw
->
i2400m
,
args
->
l3l4_hdr
,
args
->
size
);
kfree_skb
(
args
->
skb_rx
);
i2400m_put
(
iw
->
i2400m
);
...
...
@@ -309,6 +310,9 @@ void i2400m_rx_ctl(struct i2400m *i2400m, struct sk_buff *skb_rx,
skb_get
(
skb_rx
);
i2400m_queue_work
(
i2400m
,
i2400m_report_hook_work
,
GFP_KERNEL
,
&
args
,
sizeof
(
args
));
if
(
unlikely
(
i2400m
->
trace_msg_from_user
))
wimax_msg
(
&
i2400m
->
wimax_dev
,
"echo"
,
l3l4_hdr
,
size
,
GFP_KERNEL
);
result
=
wimax_msg
(
&
i2400m
->
wimax_dev
,
NULL
,
l3l4_hdr
,
size
,
GFP_KERNEL
);
if
(
result
<
0
)
...
...
drivers/net/wimax/i2400m/sdio.c
View file @
3f1f39c4
...
...
@@ -409,19 +409,19 @@ int i2400ms_probe(struct sdio_func *func,
i2400m
->
bus_fw_names
=
i2400ms_bus_fw_names
;
i2400m
->
bus_bm_mac_addr_impaired
=
1
;
result
=
i2400ms_enable_function
(
i2400ms
->
func
);
if
(
result
<
0
)
{
dev_err
(
dev
,
"Cannot enable SDIO function: %d
\n
"
,
result
);
goto
error_func_enable
;
}
sdio_claim_host
(
func
);
result
=
sdio_set_block_size
(
func
,
I2400MS_BLK_SIZE
);
sdio_release_host
(
func
);
if
(
result
<
0
)
{
dev_err
(
dev
,
"Failed to set block size: %d
\n
"
,
result
);
goto
error_set_blk_size
;
}
sdio_release_host
(
func
);
result
=
i2400ms_enable_function
(
i2400ms
->
func
);
if
(
result
<
0
)
{
dev_err
(
dev
,
"Cannot enable SDIO function: %d
\n
"
,
result
);
goto
error_func_enable
;
}
result
=
i2400m_setup
(
i2400m
,
I2400M_BRI_NO_REBOOT
);
if
(
result
<
0
)
{
...
...
@@ -440,12 +440,12 @@ int i2400ms_probe(struct sdio_func *func,
error_debugfs_add:
i2400m_release
(
i2400m
);
error_setup:
sdio_set_drvdata
(
func
,
NULL
);
sdio_claim_host
(
func
);
error_set_blk_size:
sdio_disable_func
(
func
);
sdio_release_host
(
func
);
error_func_enable:
error_set_blk_size:
sdio_set_drvdata
(
func
,
NULL
);
free_netdev
(
net_dev
);
error_alloc_netdev:
return
result
;
...
...
drivers/net/wimax/i2400m/usb.c
View file @
3f1f39c4
...
...
@@ -505,27 +505,52 @@ int i2400mu_suspend(struct usb_interface *iface, pm_message_t pm_msg)
#ifdef CONFIG_PM
struct
usb_device
*
usb_dev
=
i2400mu
->
usb_dev
;
#endif
unsigned
is_autosuspend
=
0
;
struct
i2400m
*
i2400m
=
&
i2400mu
->
i2400m
;
#ifdef CONFIG_PM
if
(
usb_dev
->
auto_pm
>
0
)
is_autosuspend
=
1
;
#endif
d_fnstart
(
3
,
dev
,
"(iface %p pm_msg %u)
\n
"
,
iface
,
pm_msg
.
event
);
if
(
i2400m
->
updown
==
0
)
goto
no_firmware
;
d_printf
(
1
,
dev
,
"fw up, requesting standby
\n
"
);
if
(
i2400m
->
state
==
I2400M_SS_DATA_PATH_CONNECTED
&&
is_autosuspend
)
{
/* ugh -- the device is connected and this suspend
* request is an autosuspend one (not a system standby
* / hibernate).
*
* The only way the device can go to standby is if the
* link with the base station is in IDLE mode; that
* were the case, we'd be in status
* I2400M_SS_CONNECTED_IDLE. But we are not.
*
* If we *tell* him to go power save now, it'll reset
* as a precautionary measure, so if this is an
* autosuspend thing, say no and it'll come back
* later, when the link is IDLE
*/
result
=
-
EBADF
;
d_printf
(
1
,
dev
,
"fw up, link up, not-idle, autosuspend: "
"not entering powersave
\n
"
);
goto
error_not_now
;
}
d_printf
(
1
,
dev
,
"fw up: entering powersave
\n
"
);
atomic_dec
(
&
i2400mu
->
do_autopm
);
result
=
i2400m_cmd_enter_powersave
(
i2400m
);
atomic_inc
(
&
i2400mu
->
do_autopm
);
#ifdef CONFIG_PM
if
(
result
<
0
&&
usb_dev
->
auto_pm
==
0
)
{
if
(
result
<
0
&&
!
is_autosuspend
)
{
/* System suspend, can't fail */
dev_err
(
dev
,
"failed to suspend, will reset on resume
\n
"
);
result
=
0
;
}
#endif
if
(
result
<
0
)
goto
error_enter_powersave
;
i2400mu_notification_release
(
i2400mu
);
d_printf
(
1
,
dev
,
"
fw up, got standby
\n
"
);
d_printf
(
1
,
dev
,
"
powersave requested
\n
"
);
error_enter_powersave:
error_not_now:
no_firmware:
d_fnend
(
3
,
dev
,
"(iface %p pm_msg %u) = %d
\n
"
,
iface
,
pm_msg
.
event
,
result
);
...
...
include/linux/wimax.h
View file @
3f1f39c4
...
...
@@ -59,7 +59,7 @@ enum {
* M - Major: change if removing or modifying an existing call.
* m - minor: change when adding a new call
*/
WIMAX_GNL_VERSION
=
0
0
,
WIMAX_GNL_VERSION
=
0
1
,
/* Generic NetLink attributes */
WIMAX_GNL_ATTR_INVALID
=
0x00
,
WIMAX_GNL_ATTR_MAX
=
10
,
...
...
@@ -78,6 +78,7 @@ enum {
WIMAX_GNL_OP_RFKILL
,
/* Run wimax_rfkill() */
WIMAX_GNL_OP_RESET
,
/* Run wimax_rfkill() */
WIMAX_GNL_RE_STATE_CHANGE
,
/* Report: status change */
WIMAX_GNL_OP_STATE_GET
,
/* Request for current state */
};
...
...
@@ -113,6 +114,10 @@ enum {
WIMAX_GNL_RESET_IFIDX
=
1
,
};
/* Atributes for wimax_state_get() */
enum
{
WIMAX_GNL_STGET_IFIDX
=
1
,
};
/*
* Attributes for the Report State Change
...
...
net/wimax/Makefile
View file @
3f1f39c4
...
...
@@ -6,6 +6,7 @@ wimax-y := \
op-msg.o
\
op-reset.o
\
op-rfkill.o
\
op-state-get.o
\
stack.o
wimax-$(CONFIG_DEBUG_FS)
+=
debugfs.o
...
...
net/wimax/debug-levels.h
View file @
3f1f39c4
...
...
@@ -36,6 +36,7 @@ enum d_module {
D_SUBMODULE_DECLARE
(
op_msg
),
D_SUBMODULE_DECLARE
(
op_reset
),
D_SUBMODULE_DECLARE
(
op_rfkill
),
D_SUBMODULE_DECLARE
(
op_state_get
),
D_SUBMODULE_DECLARE
(
stack
),
};
...
...
net/wimax/debugfs.c
View file @
3f1f39c4
...
...
@@ -61,6 +61,7 @@ int wimax_debugfs_add(struct wimax_dev *wimax_dev)
__debugfs_register
(
"wimax_dl_"
,
op_msg
,
dentry
);
__debugfs_register
(
"wimax_dl_"
,
op_reset
,
dentry
);
__debugfs_register
(
"wimax_dl_"
,
op_rfkill
,
dentry
);
__debugfs_register
(
"wimax_dl_"
,
op_state_get
,
dentry
);
__debugfs_register
(
"wimax_dl_"
,
stack
,
dentry
);
result
=
0
;
out:
...
...
net/wimax/op-msg.c
View file @
3f1f39c4
...
...
@@ -108,6 +108,12 @@
* Don't use skb_push()/skb_pull()/skb_reserve() on the skb, as
* wimax_msg_send() depends on skb->data being placed at the
* beginning of the user message.
*
* Unlike other WiMAX stack calls, this call can be used way early,
* even before wimax_dev_add() is called, as long as the
* wimax_dev->net_dev pointer is set to point to a proper
* net_dev. This is so that drivers can use it early in case they need
* to send stuff around or communicate with user space.
*/
struct
sk_buff
*
wimax_msg_alloc
(
struct
wimax_dev
*
wimax_dev
,
const
char
*
pipe_name
,
...
...
@@ -115,7 +121,7 @@ struct sk_buff *wimax_msg_alloc(struct wimax_dev *wimax_dev,
gfp_t
gfp_flags
)
{
int
result
;
struct
device
*
dev
=
wimax_dev
->
net_dev
->
dev
.
parent
;
struct
device
*
dev
=
wimax_dev
_to_dev
(
wimax_dev
)
;
size_t
msg_size
;
void
*
genl_msg
;
struct
sk_buff
*
skb
;
...
...
@@ -161,7 +167,6 @@ struct sk_buff *wimax_msg_alloc(struct wimax_dev *wimax_dev,
error_new:
nlmsg_free
(
skb
);
return
ERR_PTR
(
result
);
}
EXPORT_SYMBOL_GPL
(
wimax_msg_alloc
);
...
...
@@ -256,10 +261,16 @@ EXPORT_SYMBOL_GPL(wimax_msg_len);
* Don't use skb_push()/skb_pull()/skb_reserve() on the skb, as
* wimax_msg_send() depends on skb->data being placed at the
* beginning of the user message.
*
* Unlike other WiMAX stack calls, this call can be used way early,
* even before wimax_dev_add() is called, as long as the
* wimax_dev->net_dev pointer is set to point to a proper
* net_dev. This is so that drivers can use it early in case they need
* to send stuff around or communicate with user space.
*/
int
wimax_msg_send
(
struct
wimax_dev
*
wimax_dev
,
struct
sk_buff
*
skb
)
{
struct
device
*
dev
=
wimax_dev
->
net_dev
->
dev
.
parent
;
struct
device
*
dev
=
wimax_dev
_to_dev
(
wimax_dev
)
;
void
*
msg
=
skb
->
data
;
size_t
size
=
skb
->
len
;
might_sleep
();
...
...
net/wimax/op-state-get.c
0 → 100644
View file @
3f1f39c4
/*
* Linux WiMAX
* Implement and export a method for getting a WiMAX device current state
*
* Copyright (C) 2009 Paulius Zaleckas <paulius.zaleckas@teltonika.lt>
*
* Based on previous WiMAX core work by:
* Copyright (C) 2008 Intel Corporation <linux-wimax@intel.com>
* Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License version
* 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*/
#include <net/wimax.h>
#include <net/genetlink.h>
#include <linux/wimax.h>
#include <linux/security.h>
#include "wimax-internal.h"
#define D_SUBMODULE op_state_get
#include "debug-levels.h"
static
const
struct
nla_policy
wimax_gnl_state_get_policy
[
WIMAX_GNL_ATTR_MAX
+
1
]
=
{
[
WIMAX_GNL_STGET_IFIDX
]
=
{
.
type
=
NLA_U32
,
},
};
/*
* Exporting to user space over generic netlink
*
* Parse the state get command from user space, return a combination
* value that describe the current state.
*
* No attributes.
*/
static
int
wimax_gnl_doit_state_get
(
struct
sk_buff
*
skb
,
struct
genl_info
*
info
)
{
int
result
,
ifindex
;
struct
wimax_dev
*
wimax_dev
;
struct
device
*
dev
;
d_fnstart
(
3
,
NULL
,
"(skb %p info %p)
\n
"
,
skb
,
info
);
result
=
-
ENODEV
;
if
(
info
->
attrs
[
WIMAX_GNL_STGET_IFIDX
]
==
NULL
)
{
printk
(
KERN_ERR
"WIMAX_GNL_OP_STATE_GET: can't find IFIDX "
"attribute
\n
"
);
goto
error_no_wimax_dev
;
}
ifindex
=
nla_get_u32
(
info
->
attrs
[
WIMAX_GNL_STGET_IFIDX
]);
wimax_dev
=
wimax_dev_get_by_genl_info
(
info
,
ifindex
);
if
(
wimax_dev
==
NULL
)
goto
error_no_wimax_dev
;
dev
=
wimax_dev_to_dev
(
wimax_dev
);
/* Execute the operation and send the result back to user space */
result
=
wimax_state_get
(
wimax_dev
);
dev_put
(
wimax_dev
->
net_dev
);
error_no_wimax_dev:
d_fnend
(
3
,
NULL
,
"(skb %p info %p) = %d
\n
"
,
skb
,
info
,
result
);
return
result
;
}
struct
genl_ops
wimax_gnl_state_get
=
{
.
cmd
=
WIMAX_GNL_OP_STATE_GET
,
.
flags
=
GENL_ADMIN_PERM
,
.
policy
=
wimax_gnl_state_get_policy
,
.
doit
=
wimax_gnl_doit_state_get
,
.
dumpit
=
NULL
,
};
net/wimax/stack.c
View file @
3f1f39c4
...
...
@@ -402,13 +402,15 @@ EXPORT_SYMBOL_GPL(wimax_dev_init);
extern
struct
genl_ops
wimax_gnl_msg_from_user
,
wimax_gnl_reset
,
wimax_gnl_rfkill
;
wimax_gnl_rfkill
,
wimax_gnl_state_get
;
static
struct
genl_ops
*
wimax_gnl_ops
[]
=
{
&
wimax_gnl_msg_from_user
,
&
wimax_gnl_reset
,
&
wimax_gnl_rfkill
,
&
wimax_gnl_state_get
,
};
...
...
@@ -533,6 +535,7 @@ struct d_level D_LEVEL[] = {
D_SUBMODULE_DEFINE
(
op_msg
),
D_SUBMODULE_DEFINE
(
op_reset
),
D_SUBMODULE_DEFINE
(
op_rfkill
),
D_SUBMODULE_DEFINE
(
op_state_get
),
D_SUBMODULE_DEFINE
(
stack
),
};
size_t
D_LEVEL_SIZE
=
ARRAY_SIZE
(
D_LEVEL
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment