Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
L
linux-davinci
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Redmine
Redmine
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
linux
linux-davinci
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,
...
@@ -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
);
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
)
{
if
(
i2400m
->
state
!=
i2400m_state
)
{
i2400m
->
state
=
i2400m_state
;
i2400m
->
state
=
i2400m_state
;
wake_up_all
(
&
i2400m
->
state_wq
);
wake_up_all
(
&
i2400m
->
state_wq
);
...
@@ -341,7 +339,6 @@ void i2400m_report_tlv_system_state(struct i2400m *i2400m,
...
@@ -341,7 +339,6 @@ void i2400m_report_tlv_system_state(struct i2400m *i2400m,
i2400m
->
bus_reset
(
i2400m
,
I2400M_RT_WARM
);
i2400m
->
bus_reset
(
i2400m
,
I2400M_RT_WARM
);
break
;
break
;
};
};
out:
d_fnend
(
3
,
dev
,
"(i2400m %p ss %p [%u]) = void
\n
"
,
d_fnend
(
3
,
dev
,
"(i2400m %p ss %p [%u]) = void
\n
"
,
i2400m
,
ss
,
i2400m_state
);
i2400m
,
ss
,
i2400m_state
);
}
}
...
@@ -372,8 +369,6 @@ void i2400m_report_tlv_media_status(struct i2400m *i2400m,
...
@@ -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
);
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
)
{
switch
(
status
)
{
case
I2400M_MEDIA_STATUS_LINK_UP
:
case
I2400M_MEDIA_STATUS_LINK_UP
:
netif_carrier_on
(
net_dev
);
netif_carrier_on
(
net_dev
);
...
@@ -393,50 +388,32 @@ void i2400m_report_tlv_media_status(struct i2400m *i2400m,
...
@@ -393,50 +388,32 @@ void i2400m_report_tlv_media_status(struct i2400m *i2400m,
dev_err
(
dev
,
"HW BUG? unknown media status %u
\n
"
,
dev_err
(
dev
,
"HW BUG? unknown media status %u
\n
"
,
status
);
status
);
};
};
out:
d_fnend
(
3
,
dev
,
"(i2400m %p ms %p [%u]) = void
\n
"
,
d_fnend
(
3
,
dev
,
"(i2400m %p ms %p [%u]) = void
\n
"
,
i2400m
,
ms
,
status
);
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
* @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.
* consistent size.
* @size: size of the message (header + payload). The header length
* @tag: for error messages
* 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.
*
*
* When setting the carrier, it's fine to set OFF twice (for example),
* Act on the TLVs from a 'state report'.
* as netif_carrier_off() will not generate two OFF events (just on
* the transitions).
*/
*/
static
static
void
i2400m_report_state_
hook
(
struct
i2400m
*
i2400m
,
void
i2400m_report_state_
parse_tlv
(
struct
i2400m
*
i2400m
,
const
struct
i2400m_l3l4_hdr
*
l3l4_hdr
,
const
struct
i2400m_tlv_hdr
*
tlv
,
size_t
size
,
const
char
*
tag
)
const
char
*
tag
)
{
{
struct
device
*
dev
=
i2400m_dev
(
i2400m
);
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_system_state
*
ss
;
const
struct
i2400m_tlv_rf_switches_status
*
rfss
;
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
"
,
if
(
0
==
i2400m_tlv_match
(
tlv
,
I2400M_TLV_SYSTEM_STATE
,
sizeof
(
*
ss
)))
{
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
)))
{
ss
=
container_of
(
tlv
,
typeof
(
*
ss
),
hdr
);
ss
=
container_of
(
tlv
,
typeof
(
*
ss
),
hdr
);
d_printf
(
2
,
dev
,
"%s: system state TLV "
d_printf
(
2
,
dev
,
"%s: system state TLV "
"found (0x%04x), state 0x%08x
\n
"
,
"found (0x%04x), state 0x%08x
\n
"
,
...
@@ -444,8 +421,7 @@ void i2400m_report_state_hook(struct i2400m *i2400m,
...
@@ -444,8 +421,7 @@ void i2400m_report_state_hook(struct i2400m *i2400m,
le32_to_cpu
(
ss
->
state
));
le32_to_cpu
(
ss
->
state
));
i2400m_report_tlv_system_state
(
i2400m
,
ss
);
i2400m_report_tlv_system_state
(
i2400m
,
ss
);
}
}
if
(
0
==
i2400m_tlv_match
(
tlv
,
I2400M_TLV_RF_STATUS
,
if
(
0
==
i2400m_tlv_match
(
tlv
,
I2400M_TLV_RF_STATUS
,
sizeof
(
*
rfss
)))
{
sizeof
(
*
rfss
)))
{
rfss
=
container_of
(
tlv
,
typeof
(
*
rfss
),
hdr
);
rfss
=
container_of
(
tlv
,
typeof
(
*
rfss
),
hdr
);
d_printf
(
2
,
dev
,
"%s: RF status TLV "
d_printf
(
2
,
dev
,
"%s: RF status TLV "
"found (0x%04x), sw 0x%02x hw 0x%02x
\n
"
,
"found (0x%04x), sw 0x%02x hw 0x%02x
\n
"
,
...
@@ -454,14 +430,43 @@ void i2400m_report_state_hook(struct i2400m *i2400m,
...
@@ -454,14 +430,43 @@ void i2400m_report_state_hook(struct i2400m *i2400m,
le32_to_cpu
(
rfss
->
hw_rf_switch
));
le32_to_cpu
(
rfss
->
hw_rf_switch
));
i2400m_report_tlv_rf_switches_status
(
i2400m
,
rfss
);
i2400m_report_tlv_rf_switches_status
(
i2400m
,
rfss
);
}
}
if
(
0
==
i2400m_tlv_match
(
tlv
,
I2400M_TLV_MEDIA_STATUS
,
if
(
0
==
i2400m_tlv_match
(
tlv
,
I2400M_TLV_MEDIA_STATUS
,
sizeof
(
*
ms
)))
{
sizeof
(
*
ms
)))
{
ms
=
container_of
(
tlv
,
typeof
(
*
ms
),
hdr
);
ms
=
container_of
(
tlv
,
typeof
(
*
ms
),
hdr
);
d_printf
(
2
,
dev
,
"%s: Media Status TLV: %u
\n
"
,
d_printf
(
2
,
dev
,
"%s: Media Status TLV: %u
\n
"
,
tag
,
le32_to_cpu
(
ms
->
media_status
));
tag
,
le32_to_cpu
(
ms
->
media_status
));
i2400m_report_tlv_media_status
(
i2400m
,
ms
);
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
"
,
d_fnend
(
4
,
dev
,
"(i2400m %p, l3l4_hdr %p, size %zu, %s) = void
\n
"
,
i2400m
,
l3l4_hdr
,
size
,
tag
);
i2400m
,
l3l4_hdr
,
size
,
tag
);
}
}
...
@@ -721,6 +726,8 @@ struct sk_buff *i2400m_msg_to_dev(struct i2400m *i2400m,
...
@@ -721,6 +726,8 @@ struct sk_buff *i2400m_msg_to_dev(struct i2400m *i2400m,
ack_timeout
=
HZ
;
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
/* 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,
* 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
* 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,
...
@@ -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
);
ack_l3l4_hdr
=
wimax_msg_data_len
(
ack_skb
,
&
ack_len
);
/* Check the ack and deliver it if it is ok */
/* 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
);
result
=
i2400m_msg_size_check
(
i2400m
,
ack_l3l4_hdr
,
ack_len
);
if
(
result
<
0
)
{
if
(
result
<
0
)
{
dev_err
(
dev
,
"HW BUG? reply to message 0x%04x: %d
\n
"
,
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 @@
...
@@ -62,6 +62,7 @@
* unregister_netdev()
* unregister_netdev()
*/
*/
#include "i2400m.h"
#include "i2400m.h"
#include <linux/etherdevice.h>
#include <linux/wimax/i2400m.h>
#include <linux/wimax/i2400m.h>
#include <linux/module.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/moduleparam.h>
...
@@ -234,9 +235,6 @@ int i2400m_op_msg_from_user(struct wimax_dev *wimax_dev,
...
@@ -234,9 +235,6 @@ int i2400m_op_msg_from_user(struct wimax_dev *wimax_dev,
result
=
PTR_ERR
(
ack_skb
);
result
=
PTR_ERR
(
ack_skb
);
if
(
IS_ERR
(
ack_skb
))
if
(
IS_ERR
(
ack_skb
))
goto
error_msg_to_dev
;
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
);
result
=
wimax_msg_send
(
&
i2400m
->
wimax_dev
,
ack_skb
);
error_msg_to_dev:
error_msg_to_dev:
d_fnend
(
4
,
dev
,
"(wimax_dev %p [i2400m %p] msg_buf %p msg_len %zu "
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)
...
@@ -650,6 +648,7 @@ int i2400m_setup(struct i2400m *i2400m, enum i2400m_bri bm_flags)
result
=
i2400m_read_mac_addr
(
i2400m
);
result
=
i2400m_read_mac_addr
(
i2400m
);
if
(
result
<
0
)
if
(
result
<
0
)
goto
error_read_mac_addr
;
goto
error_read_mac_addr
;
random_ether_addr
(
i2400m
->
src_mac_addr
);
result
=
register_netdev
(
net_dev
);
/* Okey dokey, bring it up */
result
=
register_netdev
(
net_dev
);
/* Okey dokey, bring it up */
if
(
result
<
0
)
{
if
(
result
<
0
)
{
...
...
drivers/net/wimax/i2400m/i2400m.h
View file @
3f1f39c4
...
@@ -323,6 +323,10 @@ struct i2400m_roq;
...
@@ -323,6 +323,10 @@ struct i2400m_roq;
* delivered. Then the driver can release them to the host. See
* delivered. Then the driver can release them to the host. See
* drivers/net/i2400m/rx.c for details.
* 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
* @init_mutex: Mutex used for serializing the device bringup
* sequence; this way if the device reboots in the middle, we
* 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
* don't try to do a bringup again while we are tearing down the
...
@@ -421,6 +425,7 @@ struct i2400m {
...
@@ -421,6 +425,7 @@ struct i2400m {
unsigned
rx_pl_num
,
rx_pl_max
,
rx_pl_min
,
unsigned
rx_pl_num
,
rx_pl_max
,
rx_pl_min
,
rx_num
,
rx_size_acc
,
rx_size_min
,
rx_size_max
;
rx_num
,
rx_size_acc
,
rx_size_min
,
rx_size_max
;
struct
i2400m_roq
*
rx_roq
;
/* not under rx_lock! */
struct
i2400m_roq
*
rx_roq
;
/* not under rx_lock! */
u8
src_mac_addr
[
ETH_HLEN
];
struct
mutex
msg_mutex
;
/* serialize command execution */
struct
mutex
msg_mutex
;
/* serialize command execution */
struct
completion
msg_completion
;
struct
completion
msg_completion
;
...
...
drivers/net/wimax/i2400m/netdev.c
View file @
3f1f39c4
...
@@ -404,10 +404,12 @@ static
...
@@ -404,10 +404,12 @@ static
void
i2400m_rx_fake_eth_header
(
struct
net_device
*
net_dev
,
void
i2400m_rx_fake_eth_header
(
struct
net_device
*
net_dev
,
void
*
_eth_hdr
,
__be16
protocol
)
void
*
_eth_hdr
,
__be16
protocol
)
{
{
struct
i2400m
*
i2400m
=
net_dev_to_i2400m
(
net_dev
);
struct
ethhdr
*
eth_hdr
=
_eth_hdr
;
struct
ethhdr
*
eth_hdr
=
_eth_hdr
;
memcpy
(
eth_hdr
->
h_dest
,
net_dev
->
dev_addr
,
sizeof
(
eth_hdr
->
h_dest
));
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
;
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)
...
@@ -177,6 +177,7 @@ void i2400m_report_hook_work(struct work_struct *ws)
struct
i2400m_work
*
iw
=
struct
i2400m_work
*
iw
=
container_of
(
ws
,
struct
i2400m_work
,
ws
);
container_of
(
ws
,
struct
i2400m_work
,
ws
);
struct
i2400m_report_hook_args
*
args
=
(
void
*
)
iw
->
pl
;
struct
i2400m_report_hook_args
*
args
=
(
void
*
)
iw
->
pl
;
if
(
iw
->
i2400m
->
ready
)
i2400m_report_hook
(
iw
->
i2400m
,
args
->
l3l4_hdr
,
args
->
size
);
i2400m_report_hook
(
iw
->
i2400m
,
args
->
l3l4_hdr
,
args
->
size
);
kfree_skb
(
args
->
skb_rx
);
kfree_skb
(
args
->
skb_rx
);
i2400m_put
(
iw
->
i2400m
);
i2400m_put
(
iw
->
i2400m
);
...
@@ -309,6 +310,9 @@ void i2400m_rx_ctl(struct i2400m *i2400m, struct sk_buff *skb_rx,
...
@@ -309,6 +310,9 @@ void i2400m_rx_ctl(struct i2400m *i2400m, struct sk_buff *skb_rx,
skb_get
(
skb_rx
);
skb_get
(
skb_rx
);
i2400m_queue_work
(
i2400m
,
i2400m_report_hook_work
,
i2400m_queue_work
(
i2400m
,
i2400m_report_hook_work
,
GFP_KERNEL
,
&
args
,
sizeof
(
args
));
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
,
result
=
wimax_msg
(
&
i2400m
->
wimax_dev
,
NULL
,
l3l4_hdr
,
size
,
GFP_KERNEL
);
GFP_KERNEL
);
if
(
result
<
0
)
if
(
result
<
0
)
...
...
drivers/net/wimax/i2400m/sdio.c
View file @
3f1f39c4
...
@@ -409,19 +409,19 @@ int i2400ms_probe(struct sdio_func *func,
...
@@ -409,19 +409,19 @@ int i2400ms_probe(struct sdio_func *func,
i2400m
->
bus_fw_names
=
i2400ms_bus_fw_names
;
i2400m
->
bus_fw_names
=
i2400ms_bus_fw_names
;
i2400m
->
bus_bm_mac_addr_impaired
=
1
;
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
);
sdio_claim_host
(
func
);
result
=
sdio_set_block_size
(
func
,
I2400MS_BLK_SIZE
);
result
=
sdio_set_block_size
(
func
,
I2400MS_BLK_SIZE
);
sdio_release_host
(
func
);
if
(
result
<
0
)
{
if
(
result
<
0
)
{
dev_err
(
dev
,
"Failed to set block size: %d
\n
"
,
result
);
dev_err
(
dev
,
"Failed to set block size: %d
\n
"
,
result
);
goto
error_set_blk_size
;
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
);
result
=
i2400m_setup
(
i2400m
,
I2400M_BRI_NO_REBOOT
);
if
(
result
<
0
)
{
if
(
result
<
0
)
{
...
@@ -440,12 +440,12 @@ int i2400ms_probe(struct sdio_func *func,
...
@@ -440,12 +440,12 @@ int i2400ms_probe(struct sdio_func *func,
error_debugfs_add:
error_debugfs_add:
i2400m_release
(
i2400m
);
i2400m_release
(
i2400m
);
error_setup:
error_setup:
sdio_set_drvdata
(
func
,
NULL
);
sdio_claim_host
(
func
);
sdio_claim_host
(
func
);
error_set_blk_size:
sdio_disable_func
(
func
);
sdio_disable_func
(
func
);
sdio_release_host
(
func
);
sdio_release_host
(
func
);
error_func_enable:
error_func_enable:
error_set_blk_size:
sdio_set_drvdata
(
func
,
NULL
);
free_netdev
(
net_dev
);
free_netdev
(
net_dev
);
error_alloc_netdev:
error_alloc_netdev:
return
result
;
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)
...
@@ -505,27 +505,52 @@ int i2400mu_suspend(struct usb_interface *iface, pm_message_t pm_msg)
#ifdef CONFIG_PM
#ifdef CONFIG_PM
struct
usb_device
*
usb_dev
=
i2400mu
->
usb_dev
;
struct
usb_device
*
usb_dev
=
i2400mu
->
usb_dev
;
#endif
#endif
unsigned
is_autosuspend
=
0
;
struct
i2400m
*
i2400m
=
&
i2400mu
->
i2400m
;
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
);
d_fnstart
(
3
,
dev
,
"(iface %p pm_msg %u)
\n
"
,
iface
,
pm_msg
.
event
);
if
(
i2400m
->
updown
==
0
)
if
(
i2400m
->
updown
==
0
)
goto
no_firmware
;
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
);
atomic_dec
(
&
i2400mu
->
do_autopm
);
result
=
i2400m_cmd_enter_powersave
(
i2400m
);
result
=
i2400m_cmd_enter_powersave
(
i2400m
);
atomic_inc
(
&
i2400mu
->
do_autopm
);
atomic_inc
(
&
i2400mu
->
do_autopm
);
#ifdef CONFIG_PM
if
(
result
<
0
&&
!
is_autosuspend
)
{
if
(
result
<
0
&&
usb_dev
->
auto_pm
==
0
)
{
/* System suspend, can't fail */
/* System suspend, can't fail */
dev_err
(
dev
,
"failed to suspend, will reset on resume
\n
"
);
dev_err
(
dev
,
"failed to suspend, will reset on resume
\n
"
);
result
=
0
;
result
=
0
;
}
}
#endif
if
(
result
<
0
)
if
(
result
<
0
)
goto
error_enter_powersave
;
goto
error_enter_powersave
;
i2400mu_notification_release
(
i2400mu
);
i2400mu_notification_release
(
i2400mu
);
d_printf
(
1
,
dev
,
"
fw up, got standby
\n
"
);
d_printf
(
1
,
dev
,
"
powersave requested
\n
"
);
error_enter_powersave:
error_enter_powersave:
error_not_now:
no_firmware:
no_firmware:
d_fnend
(
3
,
dev
,
"(iface %p pm_msg %u) = %d
\n
"
,
d_fnend
(
3
,
dev
,
"(iface %p pm_msg %u) = %d
\n
"
,
iface
,
pm_msg
.
event
,
result
);
iface
,
pm_msg
.
event
,
result
);
...
...
include/linux/wimax.h
View file @
3f1f39c4
...
@@ -59,7 +59,7 @@ enum {
...
@@ -59,7 +59,7 @@ enum {
* M - Major: change if removing or modifying an existing call.
* M - Major: change if removing or modifying an existing call.
* m - minor: change when adding a new call
* m - minor: change when adding a new call
*/
*/
WIMAX_GNL_VERSION
=
0
0
,
WIMAX_GNL_VERSION
=
0
1
,
/* Generic NetLink attributes */
/* Generic NetLink attributes */
WIMAX_GNL_ATTR_INVALID
=
0x00
,
WIMAX_GNL_ATTR_INVALID
=
0x00
,
WIMAX_GNL_ATTR_MAX
=
10
,
WIMAX_GNL_ATTR_MAX
=
10
,
...
@@ -78,6 +78,7 @@ enum {
...
@@ -78,6 +78,7 @@ enum {
WIMAX_GNL_OP_RFKILL
,
/* Run wimax_rfkill() */
WIMAX_GNL_OP_RFKILL
,
/* Run wimax_rfkill() */
WIMAX_GNL_OP_RESET
,
/* Run wimax_rfkill() */
WIMAX_GNL_OP_RESET
,
/* Run wimax_rfkill() */
WIMAX_GNL_RE_STATE_CHANGE
,
/* Report: status change */
WIMAX_GNL_RE_STATE_CHANGE
,
/* Report: status change */
WIMAX_GNL_OP_STATE_GET
,
/* Request for current state */
};
};
...
@@ -113,6 +114,10 @@ enum {
...
@@ -113,6 +114,10 @@ enum {
WIMAX_GNL_RESET_IFIDX
=
1
,
WIMAX_GNL_RESET_IFIDX
=
1
,
};
};
/* Atributes for wimax_state_get() */
enum
{
WIMAX_GNL_STGET_IFIDX
=
1
,
};
/*
/*
* Attributes for the Report State Change
* Attributes for the Report State Change
...
...
net/wimax/Makefile
View file @
3f1f39c4
...
@@ -6,6 +6,7 @@ wimax-y := \
...
@@ -6,6 +6,7 @@ wimax-y := \
op-msg.o
\
op-msg.o
\
op-reset.o
\
op-reset.o
\
op-rfkill.o
\
op-rfkill.o
\
op-state-get.o
\
stack.o
stack.o
wimax-$(CONFIG_DEBUG_FS)
+=
debugfs.o
wimax-$(CONFIG_DEBUG_FS)
+=
debugfs.o
...
...
net/wimax/debug-levels.h
View file @
3f1f39c4
...
@@ -36,6 +36,7 @@ enum d_module {
...
@@ -36,6 +36,7 @@ enum d_module {
D_SUBMODULE_DECLARE
(
op_msg
),
D_SUBMODULE_DECLARE
(
op_msg
),
D_SUBMODULE_DECLARE
(
op_reset
),
D_SUBMODULE_DECLARE
(
op_reset
),
D_SUBMODULE_DECLARE
(
op_rfkill
),
D_SUBMODULE_DECLARE
(
op_rfkill
),
D_SUBMODULE_DECLARE
(
op_state_get
),
D_SUBMODULE_DECLARE
(
stack
),
D_SUBMODULE_DECLARE
(
stack
),
};
};
...
...
net/wimax/debugfs.c
View file @
3f1f39c4
...
@@ -61,6 +61,7 @@ int wimax_debugfs_add(struct wimax_dev *wimax_dev)
...
@@ -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_msg
,
dentry
);
__debugfs_register
(
"wimax_dl_"
,
op_reset
,
dentry
);
__debugfs_register
(
"wimax_dl_"
,
op_reset
,
dentry
);
__debugfs_register
(
"wimax_dl_"
,
op_rfkill
,
dentry
);
__debugfs_register
(
"wimax_dl_"
,
op_rfkill
,
dentry
);
__debugfs_register
(
"wimax_dl_"
,
op_state_get
,
dentry
);
__debugfs_register
(
"wimax_dl_"
,
stack
,
dentry
);
__debugfs_register
(
"wimax_dl_"
,
stack
,
dentry
);
result
=
0
;
result
=
0
;
out:
out:
...
...
net/wimax/op-msg.c
View file @
3f1f39c4
...
@@ -108,6 +108,12 @@
...
@@ -108,6 +108,12 @@
* Don't use skb_push()/skb_pull()/skb_reserve() on the skb, as
* Don't use skb_push()/skb_pull()/skb_reserve() on the skb, as
* wimax_msg_send() depends on skb->data being placed at the
* wimax_msg_send() depends on skb->data being placed at the
* beginning of the user message.
* 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
,
struct
sk_buff
*
wimax_msg_alloc
(
struct
wimax_dev
*
wimax_dev
,
const
char
*
pipe_name
,
const
char
*
pipe_name
,
...
@@ -115,7 +121,7 @@ struct sk_buff *wimax_msg_alloc(struct wimax_dev *wimax_dev,
...
@@ -115,7 +121,7 @@ struct sk_buff *wimax_msg_alloc(struct wimax_dev *wimax_dev,
gfp_t
gfp_flags
)
gfp_t
gfp_flags
)
{
{
int
result
;
int
result
;
struct
device
*
dev
=
wimax_dev
->
net_dev
->
dev
.
parent
;
struct
device
*
dev
=
wimax_dev
_to_dev
(
wimax_dev
)
;
size_t
msg_size
;
size_t
msg_size
;
void
*
genl_msg
;
void
*
genl_msg
;
struct
sk_buff
*
skb
;
struct
sk_buff
*
skb
;
...
@@ -161,7 +167,6 @@ error_genlmsg_put:
...
@@ -161,7 +167,6 @@ error_genlmsg_put:
error_new:
error_new:
nlmsg_free
(
skb
);
nlmsg_free
(
skb
);
return
ERR_PTR
(
result
);
return
ERR_PTR
(
result
);
}
}
EXPORT_SYMBOL_GPL
(
wimax_msg_alloc
);
EXPORT_SYMBOL_GPL
(
wimax_msg_alloc
);
...
@@ -256,10 +261,16 @@ EXPORT_SYMBOL_GPL(wimax_msg_len);
...
@@ -256,10 +261,16 @@ EXPORT_SYMBOL_GPL(wimax_msg_len);
* Don't use skb_push()/skb_pull()/skb_reserve() on the skb, as
* Don't use skb_push()/skb_pull()/skb_reserve() on the skb, as
* wimax_msg_send() depends on skb->data being placed at the
* wimax_msg_send() depends on skb->data being placed at the
* beginning of the user message.
* 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
)
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
;
void
*
msg
=
skb
->
data
;
size_t
size
=
skb
->
len
;
size_t
size
=
skb
->
len
;
might_sleep
();
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);
...
@@ -402,13 +402,15 @@ EXPORT_SYMBOL_GPL(wimax_dev_init);
extern
struct
genl_ops
extern
struct
genl_ops
wimax_gnl_msg_from_user
,
wimax_gnl_msg_from_user
,
wimax_gnl_reset
,
wimax_gnl_reset
,
wimax_gnl_rfkill
;
wimax_gnl_rfkill
,
wimax_gnl_state_get
;
static
static
struct
genl_ops
*
wimax_gnl_ops
[]
=
{
struct
genl_ops
*
wimax_gnl_ops
[]
=
{
&
wimax_gnl_msg_from_user
,
&
wimax_gnl_msg_from_user
,
&
wimax_gnl_reset
,
&
wimax_gnl_reset
,
&
wimax_gnl_rfkill
,
&
wimax_gnl_rfkill
,
&
wimax_gnl_state_get
,
};
};
...
@@ -533,6 +535,7 @@ struct d_level D_LEVEL[] = {
...
@@ -533,6 +535,7 @@ struct d_level D_LEVEL[] = {
D_SUBMODULE_DEFINE
(
op_msg
),
D_SUBMODULE_DEFINE
(
op_msg
),
D_SUBMODULE_DEFINE
(
op_reset
),
D_SUBMODULE_DEFINE
(
op_reset
),
D_SUBMODULE_DEFINE
(
op_rfkill
),
D_SUBMODULE_DEFINE
(
op_rfkill
),
D_SUBMODULE_DEFINE
(
op_state_get
),
D_SUBMODULE_DEFINE
(
stack
),
D_SUBMODULE_DEFINE
(
stack
),
};
};
size_t
D_LEVEL_SIZE
=
ARRAY_SIZE
(
D_LEVEL
);
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