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
nexedi
linux
Commits
3ee40c37
Commit
3ee40c37
authored
Jun 11, 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
67002547
98eb0f53
Changes
14
Show whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
320 additions
and
153 deletions
+320
-153
drivers/net/wimax/i2400m/control.c
drivers/net/wimax/i2400m/control.c
+16
-8
drivers/net/wimax/i2400m/driver.c
drivers/net/wimax/i2400m/driver.c
+28
-12
drivers/net/wimax/i2400m/fw.c
drivers/net/wimax/i2400m/fw.c
+20
-38
drivers/net/wimax/i2400m/i2400m-sdio.h
drivers/net/wimax/i2400m/i2400m-sdio.h
+9
-0
drivers/net/wimax/i2400m/i2400m.h
drivers/net/wimax/i2400m/i2400m.h
+43
-0
drivers/net/wimax/i2400m/op-rfkill.c
drivers/net/wimax/i2400m/op-rfkill.c
+3
-1
drivers/net/wimax/i2400m/rx.c
drivers/net/wimax/i2400m/rx.c
+2
-2
drivers/net/wimax/i2400m/sdio-fw.c
drivers/net/wimax/i2400m/sdio-fw.c
+47
-62
drivers/net/wimax/i2400m/sdio-rx.c
drivers/net/wimax/i2400m/sdio-rx.c
+36
-11
drivers/net/wimax/i2400m/sdio.c
drivers/net/wimax/i2400m/sdio.c
+40
-10
drivers/net/wimax/i2400m/tx.c
drivers/net/wimax/i2400m/tx.c
+69
-6
drivers/net/wimax/i2400m/usb.c
drivers/net/wimax/i2400m/usb.c
+4
-1
include/linux/wimax/i2400m.h
include/linux/wimax/i2400m.h
+1
-1
net/wimax/op-rfkill.c
net/wimax/op-rfkill.c
+2
-1
No files found.
drivers/net/wimax/i2400m/control.c
View file @
3ee40c37
...
@@ -505,9 +505,16 @@ void i2400m_report_hook(struct i2400m *i2400m,
...
@@ -505,9 +505,16 @@ void i2400m_report_hook(struct i2400m *i2400m,
* it. */
* it. */
case
I2400M_MT_REPORT_POWERSAVE_READY
:
/* zzzzz */
case
I2400M_MT_REPORT_POWERSAVE_READY
:
/* zzzzz */
if
(
l3l4_hdr
->
status
==
cpu_to_le16
(
I2400M_MS_DONE_OK
))
{
if
(
l3l4_hdr
->
status
==
cpu_to_le16
(
I2400M_MS_DONE_OK
))
{
d_printf
(
1
,
dev
,
"ready for powersave, requesting
\n
"
);
if
(
i2400m_power_save_disabled
)
d_printf
(
1
,
dev
,
"ready for powersave, "
"not requesting (disabled by module "
"parameter)
\n
"
);
else
{
d_printf
(
1
,
dev
,
"ready for powersave, "
"requesting
\n
"
);
i2400m_cmd_enter_powersave
(
i2400m
);
i2400m_cmd_enter_powersave
(
i2400m
);
}
}
}
break
;
break
;
};
};
d_fnend
(
3
,
dev
,
"(i2400m %p l3l4_hdr %p size %zu) = void
\n
"
,
d_fnend
(
3
,
dev
,
"(i2400m %p l3l4_hdr %p size %zu) = void
\n
"
,
...
@@ -688,8 +695,9 @@ struct sk_buff *i2400m_msg_to_dev(struct i2400m *i2400m,
...
@@ -688,8 +695,9 @@ struct sk_buff *i2400m_msg_to_dev(struct i2400m *i2400m,
d_fnstart
(
3
,
dev
,
"(i2400m %p buf %p len %zu)
\n
"
,
d_fnstart
(
3
,
dev
,
"(i2400m %p buf %p len %zu)
\n
"
,
i2400m
,
buf
,
buf_len
);
i2400m
,
buf
,
buf_len
);
rmb
();
/* Make sure we see what i2400m_dev_reset_handle() */
if
(
i2400m
->
boot_mode
)
if
(
i2400m
->
boot_mode
)
return
ERR_PTR
(
-
E
NODEV
);
return
ERR_PTR
(
-
E
L3RST
);
msg_l3l4_hdr
=
buf
;
msg_l3l4_hdr
=
buf
;
/* Check msg & payload consistency */
/* Check msg & payload consistency */
...
@@ -1389,16 +1397,16 @@ int i2400m_dev_initialize(struct i2400m *i2400m)
...
@@ -1389,16 +1397,16 @@ int i2400m_dev_initialize(struct i2400m *i2400m)
*
*
* @i2400m: device descriptor
* @i2400m: device descriptor
*
*
* Gracefully stops the device, moving it to the lowest power
* Release resources acquired during the running of the device; in
* consumption state possible.
* theory, should also tell the device to go to sleep, switch off the
* radio, all that, but at this point, in most cases (driver
* disconnection, reset handling) we can't even talk to the device.
*/
*/
void
i2400m_dev_shutdown
(
struct
i2400m
*
i2400m
)
void
i2400m_dev_shutdown
(
struct
i2400m
*
i2400m
)
{
{
int
result
=
-
ENODEV
;
struct
device
*
dev
=
i2400m_dev
(
i2400m
);
struct
device
*
dev
=
i2400m_dev
(
i2400m
);
d_fnstart
(
3
,
dev
,
"(i2400m %p)
\n
"
,
i2400m
);
d_fnstart
(
3
,
dev
,
"(i2400m %p)
\n
"
,
i2400m
);
result
=
i2400m
->
bus_reset
(
i2400m
,
I2400M_RT_WARM
);
d_fnend
(
3
,
dev
,
"(i2400m %p) = void
\n
"
,
i2400m
);
d_fnend
(
3
,
dev
,
"(i2400m %p) = void [%d]
\n
"
,
i2400m
,
result
);
return
;
return
;
}
}
drivers/net/wimax/i2400m/driver.c
View file @
3ee40c37
...
@@ -82,6 +82,14 @@ module_param_named(rx_reorder_disabled, i2400m_rx_reorder_disabled, int, 0644);
...
@@ -82,6 +82,14 @@ module_param_named(rx_reorder_disabled, i2400m_rx_reorder_disabled, int, 0644);
MODULE_PARM_DESC
(
rx_reorder_disabled
,
MODULE_PARM_DESC
(
rx_reorder_disabled
,
"If true, RX reordering will be disabled."
);
"If true, RX reordering will be disabled."
);
int
i2400m_power_save_disabled
;
/* 0 (power saving enabled) by default */
module_param_named
(
power_save_disabled
,
i2400m_power_save_disabled
,
int
,
0644
);
MODULE_PARM_DESC
(
power_save_disabled
,
"If true, the driver will not tell the device to enter "
"power saving mode when it reports it is ready for it. "
"False by default (so the device is told to do power "
"saving)."
);
/**
/**
* i2400m_queue_work - schedule work on a i2400m's queue
* i2400m_queue_work - schedule work on a i2400m's queue
*
*
...
@@ -172,7 +180,6 @@ int i2400m_schedule_work(struct i2400m *i2400m,
...
@@ -172,7 +180,6 @@ int i2400m_schedule_work(struct i2400m *i2400m,
int
result
;
int
result
;
struct
i2400m_work
*
iw
;
struct
i2400m_work
*
iw
;
BUG_ON
(
i2400m
->
work_queue
==
NULL
);
result
=
-
ENOMEM
;
result
=
-
ENOMEM
;
iw
=
kzalloc
(
sizeof
(
*
iw
),
gfp_flags
);
iw
=
kzalloc
(
sizeof
(
*
iw
),
gfp_flags
);
if
(
iw
==
NULL
)
if
(
iw
==
NULL
)
...
@@ -377,6 +384,11 @@ int i2400m_check_mac_addr(struct i2400m *i2400m)
...
@@ -377,6 +384,11 @@ int i2400m_check_mac_addr(struct i2400m *i2400m)
* Uploads firmware and brings up all the resources needed to be able
* Uploads firmware and brings up all the resources needed to be able
* to communicate with the device.
* to communicate with the device.
*
*
* The workqueue has to be setup early, at least before RX handling
* (it's only real user for now) so it can process reports as they
* arrive. We also want to destroy it if we retry, to make sure it is
* flushed...easier like this.
*
* TX needs to be setup before the bus-specific code (otherwise on
* TX needs to be setup before the bus-specific code (otherwise on
* shutdown, the bus-tx code could try to access it).
* shutdown, the bus-tx code could try to access it).
*/
*/
...
@@ -387,7 +399,7 @@ int __i2400m_dev_start(struct i2400m *i2400m, enum i2400m_bri flags)
...
@@ -387,7 +399,7 @@ int __i2400m_dev_start(struct i2400m *i2400m, enum i2400m_bri flags)
struct
wimax_dev
*
wimax_dev
=
&
i2400m
->
wimax_dev
;
struct
wimax_dev
*
wimax_dev
=
&
i2400m
->
wimax_dev
;
struct
net_device
*
net_dev
=
wimax_dev
->
net_dev
;
struct
net_device
*
net_dev
=
wimax_dev
->
net_dev
;
struct
device
*
dev
=
i2400m_dev
(
i2400m
);
struct
device
*
dev
=
i2400m_dev
(
i2400m
);
int
times
=
3
;
int
times
=
i2400m
->
bus_bm_retries
;
d_fnstart
(
3
,
dev
,
"(i2400m %p)
\n
"
,
i2400m
);
d_fnstart
(
3
,
dev
,
"(i2400m %p)
\n
"
,
i2400m
);
retry:
retry:
...
@@ -402,15 +414,15 @@ int __i2400m_dev_start(struct i2400m *i2400m, enum i2400m_bri flags)
...
@@ -402,15 +414,15 @@ int __i2400m_dev_start(struct i2400m *i2400m, enum i2400m_bri flags)
result
=
i2400m_rx_setup
(
i2400m
);
result
=
i2400m_rx_setup
(
i2400m
);
if
(
result
<
0
)
if
(
result
<
0
)
goto
error_rx_setup
;
goto
error_rx_setup
;
result
=
i2400m
->
bus_dev_start
(
i2400m
);
if
(
result
<
0
)
goto
error_bus_dev_start
;
i2400m
->
work_queue
=
create_singlethread_workqueue
(
wimax_dev
->
name
);
i2400m
->
work_queue
=
create_singlethread_workqueue
(
wimax_dev
->
name
);
if
(
i2400m
->
work_queue
==
NULL
)
{
if
(
i2400m
->
work_queue
==
NULL
)
{
result
=
-
ENOMEM
;
result
=
-
ENOMEM
;
dev_err
(
dev
,
"cannot create workqueue
\n
"
);
dev_err
(
dev
,
"cannot create workqueue
\n
"
);
goto
error_create_workqueue
;
goto
error_create_workqueue
;
}
}
result
=
i2400m
->
bus_dev_start
(
i2400m
);
if
(
result
<
0
)
goto
error_bus_dev_start
;
result
=
i2400m_firmware_check
(
i2400m
);
/* fw versions ok? */
result
=
i2400m_firmware_check
(
i2400m
);
/* fw versions ok? */
if
(
result
<
0
)
if
(
result
<
0
)
goto
error_fw_check
;
goto
error_fw_check
;
...
@@ -432,17 +444,17 @@ int __i2400m_dev_start(struct i2400m *i2400m, enum i2400m_bri flags)
...
@@ -432,17 +444,17 @@ int __i2400m_dev_start(struct i2400m *i2400m, enum i2400m_bri flags)
error_dev_initialize:
error_dev_initialize:
error_check_mac_addr:
error_check_mac_addr:
error_fw_check:
error_fw_check:
destroy_workqueue
(
i2400m
->
work_queue
);
error_create_workqueue:
i2400m
->
bus_dev_stop
(
i2400m
);
i2400m
->
bus_dev_stop
(
i2400m
);
error_bus_dev_start:
error_bus_dev_start:
destroy_workqueue
(
i2400m
->
work_queue
);
error_create_workqueue:
i2400m_rx_release
(
i2400m
);
i2400m_rx_release
(
i2400m
);
error_rx_setup:
error_rx_setup:
i2400m_tx_release
(
i2400m
);
i2400m_tx_release
(
i2400m
);
error_tx_setup:
error_tx_setup:
error_bootstrap:
error_bootstrap:
if
(
result
==
-
E
RESTARTSYS
&&
times
--
>
0
)
{
if
(
result
==
-
E
L3RST
&&
times
--
>
0
)
{
flags
=
I2400M_BRI_SOFT
;
flags
=
I2400M_BRI_SOFT
|
I2400M_BRI_MAC_REINIT
;
goto
retry
;
goto
retry
;
}
}
d_fnend
(
3
,
dev
,
"(net_dev %p [i2400m %p]) = %d
\n
"
,
d_fnend
(
3
,
dev
,
"(net_dev %p [i2400m %p]) = %d
\n
"
,
...
@@ -471,7 +483,9 @@ int i2400m_dev_start(struct i2400m *i2400m, enum i2400m_bri bm_flags)
...
@@ -471,7 +483,9 @@ int i2400m_dev_start(struct i2400m *i2400m, enum i2400m_bri bm_flags)
*
*
* Returns: 0 if ok, < 0 errno code on error.
* Returns: 0 if ok, < 0 errno code on error.
*
*
* Releases all the resources allocated to communicate with the device.
* Releases all the resources allocated to communicate with the
* device. Note we cannot destroy the workqueue earlier as until RX is
* fully destroyed, it could still try to schedule jobs.
*/
*/
static
static
void
__i2400m_dev_stop
(
struct
i2400m
*
i2400m
)
void
__i2400m_dev_stop
(
struct
i2400m
*
i2400m
)
...
@@ -483,8 +497,8 @@ void __i2400m_dev_stop(struct i2400m *i2400m)
...
@@ -483,8 +497,8 @@ void __i2400m_dev_stop(struct i2400m *i2400m)
wimax_state_change
(
wimax_dev
,
__WIMAX_ST_QUIESCING
);
wimax_state_change
(
wimax_dev
,
__WIMAX_ST_QUIESCING
);
i2400m_dev_shutdown
(
i2400m
);
i2400m_dev_shutdown
(
i2400m
);
i2400m
->
ready
=
0
;
i2400m
->
ready
=
0
;
destroy_workqueue
(
i2400m
->
work_queue
);
i2400m
->
bus_dev_stop
(
i2400m
);
i2400m
->
bus_dev_stop
(
i2400m
);
destroy_workqueue
(
i2400m
->
work_queue
);
i2400m_rx_release
(
i2400m
);
i2400m_rx_release
(
i2400m
);
i2400m_tx_release
(
i2400m
);
i2400m_tx_release
(
i2400m
);
wimax_state_change
(
wimax_dev
,
WIMAX_ST_DOWN
);
wimax_state_change
(
wimax_dev
,
WIMAX_ST_DOWN
);
...
@@ -546,7 +560,7 @@ void __i2400m_dev_reset_handle(struct work_struct *ws)
...
@@ -546,7 +560,7 @@ void __i2400m_dev_reset_handle(struct work_struct *ws)
* i2400m_dev_stop() [we are shutting down anyway, so
* i2400m_dev_stop() [we are shutting down anyway, so
* ignore it] or we are resetting somewhere else. */
* ignore it] or we are resetting somewhere else. */
dev_err
(
dev
,
"device rebooted
\n
"
);
dev_err
(
dev
,
"device rebooted
\n
"
);
i2400m_msg_to_dev_cancel_wait
(
i2400m
,
-
E
RESTARTSYS
);
i2400m_msg_to_dev_cancel_wait
(
i2400m
,
-
E
L3RST
);
complete
(
&
i2400m
->
msg_completion
);
complete
(
&
i2400m
->
msg_completion
);
goto
out
;
goto
out
;
}
}
...
@@ -596,6 +610,8 @@ void __i2400m_dev_reset_handle(struct work_struct *ws)
...
@@ -596,6 +610,8 @@ void __i2400m_dev_reset_handle(struct work_struct *ws)
*/
*/
int
i2400m_dev_reset_handle
(
struct
i2400m
*
i2400m
)
int
i2400m_dev_reset_handle
(
struct
i2400m
*
i2400m
)
{
{
i2400m
->
boot_mode
=
1
;
wmb
();
/* Make sure i2400m_msg_to_dev() sees boot_mode */
return
i2400m_schedule_work
(
i2400m
,
__i2400m_dev_reset_handle
,
return
i2400m_schedule_work
(
i2400m
,
__i2400m_dev_reset_handle
,
GFP_ATOMIC
);
GFP_ATOMIC
);
}
}
...
...
drivers/net/wimax/i2400m/fw.c
View file @
3ee40c37
...
@@ -397,7 +397,7 @@ static int i2400m_download_chunk(struct i2400m *i2400m, const void *chunk,
...
@@ -397,7 +397,7 @@ static int i2400m_download_chunk(struct i2400m *i2400m, const void *chunk,
unsigned
int
direct
,
unsigned
int
do_csum
)
unsigned
int
direct
,
unsigned
int
do_csum
)
{
{
int
ret
;
int
ret
;
size_t
chunk_len
=
ALIGN
(
__chunk_len
,
I2400M_PL_
PAD
);
size_t
chunk_len
=
ALIGN
(
__chunk_len
,
I2400M_PL_
ALIGN
);
struct
device
*
dev
=
i2400m_dev
(
i2400m
);
struct
device
*
dev
=
i2400m_dev
(
i2400m
);
struct
{
struct
{
struct
i2400m_bootrom_header
cmd
;
struct
i2400m_bootrom_header
cmd
;
...
@@ -532,14 +532,14 @@ int i2400m_dnload_finalize(struct i2400m *i2400m,
...
@@ -532,14 +532,14 @@ int i2400m_dnload_finalize(struct i2400m *i2400m,
cmd
=
(
void
*
)
bcf
+
offset
;
cmd
=
(
void
*
)
bcf
+
offset
;
if
(
i2400m
->
sboot
==
0
)
{
if
(
i2400m
->
sboot
==
0
)
{
struct
i2400m_bootrom_header
jump_ack
;
struct
i2400m_bootrom_header
jump_ack
;
d_printf
(
3
,
dev
,
"unsecure boot, jumping to 0x%08x
\n
"
,
d_printf
(
1
,
dev
,
"unsecure boot, jumping to 0x%08x
\n
"
,
le32_to_cpu
(
cmd
->
target_addr
));
le32_to_cpu
(
cmd
->
target_addr
));
i2400m_brh_set_opcode
(
cmd
,
I2400M_BRH_JUMP
);
i2400m_brh_set_opcode
(
cmd
,
I2400M_BRH_JUMP
);
cmd
->
data_size
=
0
;
cmd
->
data_size
=
0
;
ret
=
i2400m_bm_cmd
(
i2400m
,
cmd
,
sizeof
(
*
cmd
),
ret
=
i2400m_bm_cmd
(
i2400m
,
cmd
,
sizeof
(
*
cmd
),
&
jump_ack
,
sizeof
(
jump_ack
),
0
);
&
jump_ack
,
sizeof
(
jump_ack
),
0
);
}
else
{
}
else
{
d_printf
(
3
,
dev
,
"secure boot, jumping to 0x%08x
\n
"
,
d_printf
(
1
,
dev
,
"secure boot, jumping to 0x%08x
\n
"
,
le32_to_cpu
(
cmd
->
target_addr
));
le32_to_cpu
(
cmd
->
target_addr
));
cmd_buf
=
i2400m
->
bm_cmd_buf
;
cmd_buf
=
i2400m
->
bm_cmd_buf
;
memcpy
(
&
cmd_buf
->
cmd
,
cmd
,
sizeof
(
*
cmd
));
memcpy
(
&
cmd_buf
->
cmd
,
cmd
,
sizeof
(
*
cmd
));
...
@@ -696,8 +696,7 @@ int i2400m_bootrom_init(struct i2400m *i2400m, enum i2400m_bri flags)
...
@@ -696,8 +696,7 @@ int i2400m_bootrom_init(struct i2400m *i2400m, enum i2400m_bri flags)
return
result
;
return
result
;
error_timeout:
error_timeout:
dev_err
(
dev
,
"Timed out waiting for reboot ack, resetting
\n
"
);
dev_err
(
dev
,
"Timed out waiting for reboot ack
\n
"
);
i2400m
->
bus_reset
(
i2400m
,
I2400M_RT_BUS
);
result
=
-
ETIMEDOUT
;
result
=
-
ETIMEDOUT
;
goto
exit_timeout
;
goto
exit_timeout
;
}
}
...
@@ -770,40 +769,21 @@ int i2400m_read_mac_addr(struct i2400m *i2400m)
...
@@ -770,40 +769,21 @@ int i2400m_read_mac_addr(struct i2400m *i2400m)
static
static
int
i2400m_dnload_init_nonsigned
(
struct
i2400m
*
i2400m
)
int
i2400m_dnload_init_nonsigned
(
struct
i2400m
*
i2400m
)
{
{
#define POKE(a, d) { \
unsigned
i
=
0
;
.address = cpu_to_le32(a), \
int
ret
=
0
;
.data = cpu_to_le32(d) \
}
static
const
struct
{
__le32
address
;
__le32
data
;
}
i2400m_pokes
[]
=
{
POKE
(
0x081A58
,
0xA7810230
),
POKE
(
0x080040
,
0x00000000
),
POKE
(
0x080048
,
0x00000082
),
POKE
(
0x08004C
,
0x0000081F
),
POKE
(
0x080054
,
0x00000085
),
POKE
(
0x080058
,
0x00000180
),
POKE
(
0x08005C
,
0x00000018
),
POKE
(
0x080060
,
0x00000010
),
POKE
(
0x080574
,
0x00000001
),
POKE
(
0x080550
,
0x00000005
),
POKE
(
0xAE0000
,
0x00000000
),
};
#undef POKE
unsigned
i
;
int
ret
;
struct
device
*
dev
=
i2400m_dev
(
i2400m
);
struct
device
*
dev
=
i2400m_dev
(
i2400m
);
dev_warn
(
dev
,
"WARNING!!! non-signed boot UNTESTED PATH!
\n
"
);
d_fnstart
(
5
,
dev
,
"(i2400m %p)
\n
"
,
i2400m
);
d_fnstart
(
5
,
dev
,
"(i2400m %p)
\n
"
,
i2400m
);
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
i2400m_pokes
);
i
++
)
{
if
(
i2400m
->
bus_bm_pokes_table
)
{
ret
=
i2400m_download_chunk
(
i2400m
,
&
i2400m_pokes
[
i
].
data
,
while
(
i2400m
->
bus_bm_pokes_table
[
i
].
address
)
{
sizeof
(
i2400m_pokes
[
i
].
data
),
ret
=
i2400m_download_chunk
(
i2400m_pokes
[
i
].
address
,
1
,
1
);
i2400m
,
&
i2400m
->
bus_bm_pokes_table
[
i
].
data
,
sizeof
(
i2400m
->
bus_bm_pokes_table
[
i
].
data
),
i2400m
->
bus_bm_pokes_table
[
i
].
address
,
1
,
1
);
if
(
ret
<
0
)
if
(
ret
<
0
)
break
;
break
;
i
++
;
}
}
}
d_fnend
(
5
,
dev
,
"(i2400m %p) = %d
\n
"
,
i2400m
,
ret
);
d_fnend
(
5
,
dev
,
"(i2400m %p) = %d
\n
"
,
i2400m
,
ret
);
return
ret
;
return
ret
;
...
@@ -980,11 +960,12 @@ int i2400m_fw_dnload(struct i2400m *i2400m, const struct i2400m_bcf_hdr *bcf,
...
@@ -980,11 +960,12 @@ int i2400m_fw_dnload(struct i2400m *i2400m, const struct i2400m_bcf_hdr *bcf,
{
{
int
ret
=
0
;
int
ret
=
0
;
struct
device
*
dev
=
i2400m_dev
(
i2400m
);
struct
device
*
dev
=
i2400m_dev
(
i2400m
);
int
count
=
I2400M_BOOT_RETRIES
;
int
count
=
i2400m
->
bus_bm_retries
;
d_fnstart
(
5
,
dev
,
"(i2400m %p bcf %p size %zu)
\n
"
,
d_fnstart
(
5
,
dev
,
"(i2400m %p bcf %p size %zu)
\n
"
,
i2400m
,
bcf
,
bcf_size
);
i2400m
,
bcf
,
bcf_size
);
i2400m
->
boot_mode
=
1
;
i2400m
->
boot_mode
=
1
;
wmb
();
/* Make sure other readers see it */
hw_reboot:
hw_reboot:
if
(
count
--
==
0
)
{
if
(
count
--
==
0
)
{
ret
=
-
ERESTARTSYS
;
ret
=
-
ERESTARTSYS
;
...
@@ -1033,6 +1014,7 @@ int i2400m_fw_dnload(struct i2400m *i2400m, const struct i2400m_bcf_hdr *bcf,
...
@@ -1033,6 +1014,7 @@ int i2400m_fw_dnload(struct i2400m *i2400m, const struct i2400m_bcf_hdr *bcf,
d_printf
(
2
,
dev
,
"fw %s successfully uploaded
\n
"
,
d_printf
(
2
,
dev
,
"fw %s successfully uploaded
\n
"
,
i2400m
->
fw_name
);
i2400m
->
fw_name
);
i2400m
->
boot_mode
=
0
;
i2400m
->
boot_mode
=
0
;
wmb
();
/* Make sure i2400m_msg_to_dev() sees boot_mode */
error_dnload_finalize:
error_dnload_finalize:
error_dnload_bcf:
error_dnload_bcf:
error_dnload_init:
error_dnload_init:
...
...
drivers/net/wimax/i2400m/i2400m-sdio.h
View file @
3ee40c37
...
@@ -78,6 +78,8 @@ enum {
...
@@ -78,6 +78,8 @@ enum {
/* The number of ticks to wait for the device to signal that
/* The number of ticks to wait for the device to signal that
* it is ready */
* it is ready */
I2400MS_INIT_SLEEP_INTERVAL
=
10
,
I2400MS_INIT_SLEEP_INTERVAL
=
10
,
/* How long to wait for the device to settle after reset */
I2400MS_SETTLE_TIME
=
40
,
};
};
...
@@ -105,6 +107,10 @@ struct i2400ms {
...
@@ -105,6 +107,10 @@ struct i2400ms {
char
tx_wq_name
[
32
];
char
tx_wq_name
[
32
];
struct
dentry
*
debugfs_dentry
;
struct
dentry
*
debugfs_dentry
;
wait_queue_head_t
bm_wfa_wq
;
int
bm_wait_result
;
size_t
bm_ack_size
;
};
};
...
@@ -129,4 +135,7 @@ extern ssize_t i2400ms_bus_bm_cmd_send(struct i2400m *,
...
@@ -129,4 +135,7 @@ extern ssize_t i2400ms_bus_bm_cmd_send(struct i2400m *,
extern
ssize_t
i2400ms_bus_bm_wait_for_ack
(
struct
i2400m
*
,
extern
ssize_t
i2400ms_bus_bm_wait_for_ack
(
struct
i2400m
*
,
struct
i2400m_bootrom_header
*
,
struct
i2400m_bootrom_header
*
,
size_t
);
size_t
);
extern
void
i2400ms_bus_bm_release
(
struct
i2400m
*
);
extern
int
i2400ms_bus_bm_setup
(
struct
i2400m
*
);
#endif
/* #ifndef __I2400M_SDIO_H__ */
#endif
/* #ifndef __I2400M_SDIO_H__ */
drivers/net/wimax/i2400m/i2400m.h
View file @
3ee40c37
...
@@ -150,11 +150,33 @@
...
@@ -150,11 +150,33 @@
enum
{
enum
{
/* Firmware uploading */
/* Firmware uploading */
I2400M_BOOT_RETRIES
=
3
,
I2400M_BOOT_RETRIES
=
3
,
I3200_BOOT_RETRIES
=
3
,
/* Size of the Boot Mode Command buffer */
/* Size of the Boot Mode Command buffer */
I2400M_BM_CMD_BUF_SIZE
=
16
*
1024
,
I2400M_BM_CMD_BUF_SIZE
=
16
*
1024
,
I2400M_BM_ACK_BUF_SIZE
=
256
,
I2400M_BM_ACK_BUF_SIZE
=
256
,
};
};
/**
* struct i2400m_poke_table - Hardware poke table for the Intel 2400m
*
* This structure will be used to create a device specific poke table
* to put the device in a consistant state at boot time.
*
* @address: The device address to poke
*
* @data: The data value to poke to the device address
*
*/
struct
i2400m_poke_table
{
__le32
address
;
__le32
data
;
};
#define I2400M_FW_POKE(a, d) { \
.address = cpu_to_le32(a), \
.data = cpu_to_le32(d) \
}
/**
/**
* i2400m_reset_type - methods to reset a device
* i2400m_reset_type - methods to reset a device
...
@@ -224,6 +246,17 @@ struct i2400m_roq;
...
@@ -224,6 +246,17 @@ struct i2400m_roq;
* process, so it cannot rely on common infrastructure being laid
* process, so it cannot rely on common infrastructure being laid
* out.
* out.
*
*
* @bus_bm_retries: [fill] How many times shall a firmware upload /
* device initialization be retried? Different models of the same
* device might need different values, hence it is set by the
* bus-specific driver. Note this value is used in two places,
* i2400m_fw_dnload() and __i2400m_dev_start(); they won't become
* multiplicative (__i2400m_dev_start() calling N times
* i2400m_fw_dnload() and this trying N times to download the
* firmware), as if __i2400m_dev_start() only retries if the
* firmware crashed while initializing the device (not in a
* general case).
*
* @bus_bm_cmd_send: [fill] Function called to send a boot-mode
* @bus_bm_cmd_send: [fill] Function called to send a boot-mode
* command. Flags are defined in 'enum i2400m_bm_cmd_flags'. This
* command. Flags are defined in 'enum i2400m_bm_cmd_flags'. This
* is synchronous and has to return 0 if ok or < 0 errno code in
* is synchronous and has to return 0 if ok or < 0 errno code in
...
@@ -252,6 +285,12 @@ struct i2400m_roq;
...
@@ -252,6 +285,12 @@ struct i2400m_roq;
* address provided in boot mode is kind of broken and needs to
* address provided in boot mode is kind of broken and needs to
* be re-read later on.
* be re-read later on.
*
*
* @bus_bm_pokes_table: [fill/optional] A table of device addresses
* and values that will be poked at device init time to move the
* device to the correct state for the type of boot/firmware being
* used. This table MUST be terminated with (0x000000,
* 0x00000000) or bad things will happen.
*
*
*
* @wimax_dev: WiMAX generic device for linkage into the kernel WiMAX
* @wimax_dev: WiMAX generic device for linkage into the kernel WiMAX
* stack. Due to the way a net_device is allocated, we need to
* stack. Due to the way a net_device is allocated, we need to
...
@@ -399,6 +438,8 @@ struct i2400m {
...
@@ -399,6 +438,8 @@ struct i2400m {
size_t
bus_tx_block_size
;
size_t
bus_tx_block_size
;
size_t
bus_pl_size_max
;
size_t
bus_pl_size_max
;
unsigned
bus_bm_retries
;
int
(
*
bus_dev_start
)(
struct
i2400m
*
);
int
(
*
bus_dev_start
)(
struct
i2400m
*
);
void
(
*
bus_dev_stop
)(
struct
i2400m
*
);
void
(
*
bus_dev_stop
)(
struct
i2400m
*
);
void
(
*
bus_tx_kick
)(
struct
i2400m
*
);
void
(
*
bus_tx_kick
)(
struct
i2400m
*
);
...
@@ -410,6 +451,7 @@ struct i2400m {
...
@@ -410,6 +451,7 @@ struct i2400m {
struct
i2400m_bootrom_header
*
,
size_t
);
struct
i2400m_bootrom_header
*
,
size_t
);
const
char
**
bus_fw_names
;
const
char
**
bus_fw_names
;
unsigned
bus_bm_mac_addr_impaired
:
1
;
unsigned
bus_bm_mac_addr_impaired
:
1
;
const
struct
i2400m_poke_table
*
bus_bm_pokes_table
;
spinlock_t
tx_lock
;
/* protect TX state */
spinlock_t
tx_lock
;
/* protect TX state */
void
*
tx_buf
;
void
*
tx_buf
;
...
@@ -709,6 +751,7 @@ static const __le32 i2400m_SBOOT_BARKER[4] = {
...
@@ -709,6 +751,7 @@ static const __le32 i2400m_SBOOT_BARKER[4] = {
cpu_to_le32
(
I2400M_SBOOT_BARKER
)
cpu_to_le32
(
I2400M_SBOOT_BARKER
)
};
};
extern
int
i2400m_power_save_disabled
;
/*
/*
* Utility functions
* Utility functions
...
...
drivers/net/wimax/i2400m/op-rfkill.c
View file @
3ee40c37
...
@@ -54,8 +54,10 @@ int i2400m_radio_is(struct i2400m *i2400m, enum wimax_rf_state state)
...
@@ -54,8 +54,10 @@ int i2400m_radio_is(struct i2400m *i2400m, enum wimax_rf_state state)
/* state == WIMAX_RF_ON */
/* state == WIMAX_RF_ON */
return
i2400m
->
state
!=
I2400M_SS_RF_OFF
return
i2400m
->
state
!=
I2400M_SS_RF_OFF
&&
i2400m
->
state
!=
I2400M_SS_RF_SHUTDOWN
;
&&
i2400m
->
state
!=
I2400M_SS_RF_SHUTDOWN
;
else
else
{
BUG
();
BUG
();
return
-
EINVAL
;
/* shut gcc warnings on certain arches */
}
}
}
...
...
drivers/net/wimax/i2400m/rx.c
View file @
3ee40c37
...
@@ -1148,7 +1148,7 @@ int i2400m_rx(struct i2400m *i2400m, struct sk_buff *skb)
...
@@ -1148,7 +1148,7 @@ int i2400m_rx(struct i2400m *i2400m, struct sk_buff *skb)
num_pls
=
le16_to_cpu
(
msg_hdr
->
num_pls
);
num_pls
=
le16_to_cpu
(
msg_hdr
->
num_pls
);
pl_itr
=
sizeof
(
*
msg_hdr
)
+
/* Check payload descriptor(s) */
pl_itr
=
sizeof
(
*
msg_hdr
)
+
/* Check payload descriptor(s) */
num_pls
*
sizeof
(
msg_hdr
->
pld
[
0
]);
num_pls
*
sizeof
(
msg_hdr
->
pld
[
0
]);
pl_itr
=
ALIGN
(
pl_itr
,
I2400M_PL_
PAD
);
pl_itr
=
ALIGN
(
pl_itr
,
I2400M_PL_
ALIGN
);
if
(
pl_itr
>
skb
->
len
)
{
/* got all the payload descriptors? */
if
(
pl_itr
>
skb
->
len
)
{
/* got all the payload descriptors? */
dev_err
(
dev
,
"RX: HW BUG? message too short (%u bytes) for "
dev_err
(
dev
,
"RX: HW BUG? message too short (%u bytes) for "
"%u payload descriptors (%zu each, total %zu)
\n
"
,
"%u payload descriptors (%zu each, total %zu)
\n
"
,
...
@@ -1166,7 +1166,7 @@ int i2400m_rx(struct i2400m *i2400m, struct sk_buff *skb)
...
@@ -1166,7 +1166,7 @@ int i2400m_rx(struct i2400m *i2400m, struct sk_buff *skb)
single_last
=
num_pls
==
1
||
i
==
num_pls
-
1
;
single_last
=
num_pls
==
1
||
i
==
num_pls
-
1
;
i2400m_rx_payload
(
i2400m
,
skb
,
single_last
,
&
msg_hdr
->
pld
[
i
],
i2400m_rx_payload
(
i2400m
,
skb
,
single_last
,
&
msg_hdr
->
pld
[
i
],
skb
->
data
+
pl_itr
);
skb
->
data
+
pl_itr
);
pl_itr
+=
ALIGN
(
pl_size
,
I2400M_PL_
PAD
);
pl_itr
+=
ALIGN
(
pl_size
,
I2400M_PL_
ALIGN
);
cond_resched
();
/* Don't monopolize */
cond_resched
();
/* Don't monopolize */
}
}
kfree_skb
(
skb
);
kfree_skb
(
skb
);
...
...
drivers/net/wimax/i2400m/sdio-fw.c
View file @
3ee40c37
...
@@ -46,17 +46,24 @@
...
@@ -46,17 +46,24 @@
* Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com>
* Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com>
* - SDIO rehash for changes in the bus-driver model
* - SDIO rehash for changes in the bus-driver model
*
*
* Dirk Brandewie <dirk.j.brandewie@intel.com>
* - Make it IRQ based, not polling
*
* THE PROCEDURE
* THE PROCEDURE
*
*
* See fw.c for the generic description of this procedure.
* See fw.c for the generic description of this procedure.
*
*
* This file implements only the SDIO specifics. It boils down to how
* This file implements only the SDIO specifics. It boils down to how
* to send a command and waiting for an acknowledgement from the
* to send a command and waiting for an acknowledgement from the
* device. We do polled reads.
* device.
*
* All this code is sequential -- all i2400ms_bus_bm_*() functions are
* executed in the same thread, except i2400ms_bm_irq() [on its own by
* the SDIO driver]. This makes it possible to avoid locking.
*
*
* COMMAND EXECUTION
* COMMAND EXECUTION
*
*
* T
H
e generic firmware upload code will call i2400m_bus_bm_cmd_send()
* T
h
e generic firmware upload code will call i2400m_bus_bm_cmd_send()
* to send commands.
* to send commands.
*
*
* The SDIO devices expects things in 256 byte blocks, so it will pad
* The SDIO devices expects things in 256 byte blocks, so it will pad
...
@@ -64,12 +71,15 @@
...
@@ -64,12 +71,15 @@
*
*
* ACK RECEPTION
* ACK RECEPTION
*
*
* This works in
polling mode -- the fw loader says when to wait for
* This works in
IRQ mode -- the fw loader says when to wait for data
*
data
and for that it calls i2400ms_bus_bm_wait_for_ack().
* and for that it calls i2400ms_bus_bm_wait_for_ack().
*
*
* This will poll the device for data until it is received. We need to
* This checks if there is any data available (RX size > 0); if not,
* receive at least as much bytes as where asked for (although it'll
* waits for the IRQ handler to notify about it. Once there is data,
* always be a multiple of 256 bytes).
* it is read and passed to the caller. Doing it this way we don't
* need much coordination/locking, and it makes it much more difficult
* for an interrupt to be lost and the wait_for_ack() function getting
* stuck even when data is pending.
*/
*/
#include <linux/mmc/sdio_func.h>
#include <linux/mmc/sdio_func.h>
#include "i2400m-sdio.h"
#include "i2400m-sdio.h"
...
@@ -78,6 +88,7 @@
...
@@ -78,6 +88,7 @@
#define D_SUBMODULE fw
#define D_SUBMODULE fw
#include "sdio-debug-levels.h"
#include "sdio-debug-levels.h"
/*
/*
* Send a boot-mode command to the SDIO function
* Send a boot-mode command to the SDIO function
*
*
...
@@ -139,7 +150,7 @@ ssize_t i2400ms_bus_bm_cmd_send(struct i2400m *i2400m,
...
@@ -139,7 +150,7 @@ ssize_t i2400ms_bus_bm_cmd_send(struct i2400m *i2400m,
/*
/*
* Read an ack from the device's boot-mode
(polling)
* Read an ack from the device's boot-mode
*
*
* @i2400m:
* @i2400m:
* @_ack: pointer to where to store the read data
* @_ack: pointer to where to store the read data
...
@@ -150,75 +161,49 @@ ssize_t i2400ms_bus_bm_cmd_send(struct i2400m *i2400m,
...
@@ -150,75 +161,49 @@ ssize_t i2400ms_bus_bm_cmd_send(struct i2400m *i2400m,
* The ACK for a BM command is always at least sizeof(*ack) bytes, so
* The ACK for a BM command is always at least sizeof(*ack) bytes, so
* check for that. We don't need to check for device reboots
* check for that. We don't need to check for device reboots
*
*
* NOTE: We do an artificial timeout of 1 sec over the SDIO timeout;
* this way we have control over it...there is no way that I know
* of setting an SDIO transaction timeout.
*/
*/
ssize_t
i2400ms_bus_bm_wait_for_ack
(
struct
i2400m
*
i2400m
,
ssize_t
i2400ms_bus_bm_wait_for_ack
(
struct
i2400m
*
i2400m
,
struct
i2400m_bootrom_header
*
ack
,
struct
i2400m_bootrom_header
*
ack
,
size_t
ack_size
)
size_t
ack_size
)
{
{
int
result
;
ssize_t
result
;
ssize_t
rx_size
;
u64
timeout
;
struct
i2400ms
*
i2400ms
=
container_of
(
i2400m
,
struct
i2400ms
,
i2400m
);
struct
i2400ms
*
i2400ms
=
container_of
(
i2400m
,
struct
i2400ms
,
i2400m
);
struct
sdio_func
*
func
=
i2400ms
->
func
;
struct
sdio_func
*
func
=
i2400ms
->
func
;
struct
device
*
dev
=
&
func
->
dev
;
struct
device
*
dev
=
&
func
->
dev
;
int
size
;
BUG_ON
(
sizeof
(
*
ack
)
>
ack_size
);
BUG_ON
(
sizeof
(
*
ack
)
>
ack_size
);
d_fnstart
(
5
,
dev
,
"(i2400m %p ack %p size %zu)
\n
"
,
d_fnstart
(
5
,
dev
,
"(i2400m %p ack %p size %zu)
\n
"
,
i2400m
,
ack
,
ack_size
);
i2400m
,
ack
,
ack_size
);
timeout
=
get_jiffies_64
()
+
2
*
HZ
;
spin_lock
(
&
i2400m
->
rx_lock
);
sdio_claim_host
(
func
);
i2400ms
->
bm_ack_size
=
-
EINPROGRESS
;
while
(
1
)
{
spin_unlock
(
&
i2400m
->
rx_lock
);
if
(
time_after64
(
get_jiffies_64
(),
timeout
))
{
rx_size
=
-
ETIMEDOUT
;
dev_err
(
dev
,
"timeout waiting for ack data
\n
"
);
goto
error_timedout
;
}
/* Find the RX size, check if it fits or not -- it if
result
=
wait_event_timeout
(
i2400ms
->
bm_wfa_wq
,
* doesn't fit, fail, as we have no way to dispose of
i2400ms
->
bm_ack_size
!=
-
EINPROGRESS
,
* the extra data. */
2
*
HZ
);
rx_size
=
__i2400ms_rx_get_size
(
i2400ms
);
if
(
result
==
0
)
{
if
(
rx_size
<
0
)
result
=
-
ETIMEDOUT
;
goto
error_rx_get_size
;
dev_err
(
dev
,
"BM: error waiting for an ack
\n
"
);
result
=
-
ENOSPC
;
/* Check it fits */
goto
error_timeout
;
if
(
rx_size
<
sizeof
(
*
ack
))
{
rx_size
=
-
EIO
;
dev_err
(
dev
,
"HW BUG? received is too small (%zu vs "
"%zu needed)
\n
"
,
sizeof
(
*
ack
),
rx_size
);
goto
error_too_small
;
}
if
(
rx_size
>
I2400M_BM_ACK_BUF_SIZE
)
{
dev_err
(
dev
,
"SW BUG? BM_ACK_BUF is too small (%u vs "
"%zu needed)
\n
"
,
I2400M_BM_ACK_BUF_SIZE
,
rx_size
);
goto
error_too_small
;
}
}
/* Read it */
spin_lock
(
&
i2400m
->
rx_lock
);
result
=
sdio_memcpy_fromio
(
func
,
i2400m
->
bm_ack_buf
,
result
=
i2400ms
->
bm_ack_size
;
I2400MS_DATA_ADDR
,
rx_size
);
BUG_ON
(
result
==
-
EINPROGRESS
);
if
(
result
==
-
ETIMEDOUT
||
result
==
-
ETIME
)
if
(
result
<
0
)
/* so we exit when rx_release() is called */
continue
;
dev_err
(
dev
,
"BM: %s failed: %zd
\n
"
,
__func__
,
result
);
if
(
result
<
0
)
{
else
{
dev_err
(
dev
,
"BM SDIO receive (%zu B) failed: %d
\n
"
,
size
=
min
(
ack_size
,
i2400ms
->
bm_ack_size
);
rx_size
,
result
);
memcpy
(
ack
,
i2400m
->
bm_ack_buf
,
size
);
goto
error_read
;
}
else
break
;
}
}
rx_size
=
min
((
ssize_t
)
ack_size
,
rx_size
);
i2400ms
->
bm_ack_size
=
-
EINPROGRESS
;
memcpy
(
ack
,
i2400m
->
bm_ack_buf
,
rx_size
);
spin_unlock
(
&
i2400m
->
rx_lock
);
error_read:
error_too_small:
error_timeout:
error_rx_get_size:
d_fnend
(
5
,
dev
,
"(i2400m %p ack %p size %zu) = %zd
\n
"
,
error_timedout:
i2400m
,
ack
,
ack_size
,
result
);
sdio_release_host
(
func
);
return
result
;
d_fnend
(
5
,
dev
,
"(i2400m %p ack %p size %zu) = %ld
\n
"
,
i2400m
,
ack
,
ack_size
,
(
long
)
rx_size
);
return
rx_size
;
}
}
drivers/net/wimax/i2400m/sdio-rx.c
View file @
3ee40c37
...
@@ -69,6 +69,13 @@
...
@@ -69,6 +69,13 @@
#define D_SUBMODULE rx
#define D_SUBMODULE rx
#include "sdio-debug-levels.h"
#include "sdio-debug-levels.h"
static
const
__le32
i2400m_ACK_BARKER
[
4
]
=
{
__constant_cpu_to_le32
(
I2400M_ACK_BARKER
),
__constant_cpu_to_le32
(
I2400M_ACK_BARKER
),
__constant_cpu_to_le32
(
I2400M_ACK_BARKER
),
__constant_cpu_to_le32
(
I2400M_ACK_BARKER
)
};
/*
/*
* Read and return the amount of bytes available for RX
* Read and return the amount of bytes available for RX
...
@@ -131,25 +138,35 @@ void i2400ms_rx(struct i2400ms *i2400ms)
...
@@ -131,25 +138,35 @@ void i2400ms_rx(struct i2400ms *i2400ms)
ret
=
rx_size
;
ret
=
rx_size
;
goto
error_get_size
;
goto
error_get_size
;
}
}
ret
=
-
ENOMEM
;
ret
=
-
ENOMEM
;
skb
=
alloc_skb
(
rx_size
,
GFP_ATOMIC
);
skb
=
alloc_skb
(
rx_size
,
GFP_ATOMIC
);
if
(
NULL
==
skb
)
{
if
(
NULL
==
skb
)
{
dev_err
(
dev
,
"RX: unable to alloc skb
\n
"
);
dev_err
(
dev
,
"RX: unable to alloc skb
\n
"
);
goto
error_alloc_skb
;
goto
error_alloc_skb
;
}
}
ret
=
sdio_memcpy_fromio
(
func
,
skb
->
data
,
ret
=
sdio_memcpy_fromio
(
func
,
skb
->
data
,
I2400MS_DATA_ADDR
,
rx_size
);
I2400MS_DATA_ADDR
,
rx_size
);
if
(
ret
<
0
)
{
if
(
ret
<
0
)
{
dev_err
(
dev
,
"RX: SDIO data read failed: %d
\n
"
,
ret
);
dev_err
(
dev
,
"RX: SDIO data read failed: %d
\n
"
,
ret
);
goto
error_memcpy_fromio
;
goto
error_memcpy_fromio
;
}
}
/* Check if device has reset */
if
(
!
memcmp
(
skb
->
data
,
i2400m_NBOOT_BARKER
,
rmb
();
/* make sure we get boot_mode from dev_reset_handle */
if
(
i2400m
->
boot_mode
==
1
)
{
spin_lock
(
&
i2400m
->
rx_lock
);
i2400ms
->
bm_ack_size
=
rx_size
;
spin_unlock
(
&
i2400m
->
rx_lock
);
memcpy
(
i2400m
->
bm_ack_buf
,
skb
->
data
,
rx_size
);
wake_up
(
&
i2400ms
->
bm_wfa_wq
);
dev_err
(
dev
,
"RX: SDIO boot mode message
\n
"
);
kfree_skb
(
skb
);
}
else
if
(
unlikely
(
!
memcmp
(
skb
->
data
,
i2400m_NBOOT_BARKER
,
sizeof
(
i2400m_NBOOT_BARKER
))
sizeof
(
i2400m_NBOOT_BARKER
))
||
!
memcmp
(
skb
->
data
,
i2400m_SBOOT_BARKER
,
||
!
memcmp
(
skb
->
data
,
i2400m_SBOOT_BARKER
,
sizeof
(
i2400m_SBOOT_BARKER
)))
{
sizeof
(
i2400m_SBOOT_BARKER
)
)))
{
ret
=
i2400m_dev_reset_handle
(
i2400m
);
ret
=
i2400m_dev_reset_handle
(
i2400m
);
dev_err
(
dev
,
"RX: SDIO reboot barker
\n
"
);
kfree_skb
(
skb
);
kfree_skb
(
skb
);
}
else
{
}
else
{
skb_put
(
skb
,
rx_size
);
skb_put
(
skb
,
rx_size
);
...
@@ -179,7 +196,6 @@ void i2400ms_irq(struct sdio_func *func)
...
@@ -179,7 +196,6 @@ void i2400ms_irq(struct sdio_func *func)
{
{
int
ret
;
int
ret
;
struct
i2400ms
*
i2400ms
=
sdio_get_drvdata
(
func
);
struct
i2400ms
*
i2400ms
=
sdio_get_drvdata
(
func
);
struct
i2400m
*
i2400m
=
&
i2400ms
->
i2400m
;
struct
device
*
dev
=
&
func
->
dev
;
struct
device
*
dev
=
&
func
->
dev
;
int
val
;
int
val
;
...
@@ -194,9 +210,6 @@ void i2400ms_irq(struct sdio_func *func)
...
@@ -194,9 +210,6 @@ void i2400ms_irq(struct sdio_func *func)
goto
error_no_irq
;
goto
error_no_irq
;
}
}
sdio_writeb
(
func
,
1
,
I2400MS_INTR_CLEAR_ADDR
,
&
ret
);
sdio_writeb
(
func
,
1
,
I2400MS_INTR_CLEAR_ADDR
,
&
ret
);
if
(
WARN_ON
(
i2400m
->
boot_mode
!=
0
))
dev_err
(
dev
,
"RX: SW BUG? boot mode and IRQ is up?
\n
"
);
else
i2400ms_rx
(
i2400ms
);
i2400ms_rx
(
i2400ms
);
error_no_irq:
error_no_irq:
d_fnend
(
6
,
dev
,
"(i2400ms %p) = void
\n
"
,
i2400ms
);
d_fnend
(
6
,
dev
,
"(i2400ms %p) = void
\n
"
,
i2400ms
);
...
@@ -214,8 +227,15 @@ int i2400ms_rx_setup(struct i2400ms *i2400ms)
...
@@ -214,8 +227,15 @@ int i2400ms_rx_setup(struct i2400ms *i2400ms)
int
result
;
int
result
;
struct
sdio_func
*
func
=
i2400ms
->
func
;
struct
sdio_func
*
func
=
i2400ms
->
func
;
struct
device
*
dev
=
&
func
->
dev
;
struct
device
*
dev
=
&
func
->
dev
;
struct
i2400m
*
i2400m
=
&
i2400ms
->
i2400m
;
d_fnstart
(
5
,
dev
,
"(i2400ms %p)
\n
"
,
i2400ms
);
d_fnstart
(
5
,
dev
,
"(i2400ms %p)
\n
"
,
i2400ms
);
init_waitqueue_head
(
&
i2400ms
->
bm_wfa_wq
);
spin_lock
(
&
i2400m
->
rx_lock
);
i2400ms
->
bm_wait_result
=
-
EINPROGRESS
;
spin_unlock
(
&
i2400m
->
rx_lock
);
sdio_claim_host
(
func
);
sdio_claim_host
(
func
);
result
=
sdio_claim_irq
(
func
,
i2400ms_irq
);
result
=
sdio_claim_irq
(
func
,
i2400ms_irq
);
if
(
result
<
0
)
{
if
(
result
<
0
)
{
...
@@ -245,8 +265,13 @@ void i2400ms_rx_release(struct i2400ms *i2400ms)
...
@@ -245,8 +265,13 @@ void i2400ms_rx_release(struct i2400ms *i2400ms)
int
result
;
int
result
;
struct
sdio_func
*
func
=
i2400ms
->
func
;
struct
sdio_func
*
func
=
i2400ms
->
func
;
struct
device
*
dev
=
&
func
->
dev
;
struct
device
*
dev
=
&
func
->
dev
;
struct
i2400m
*
i2400m
=
&
i2400ms
->
i2400m
;
d_fnstart
(
5
,
dev
,
"(i2400ms %p)
\n
"
,
i2400ms
);
d_fnstart
(
5
,
dev
,
"(i2400ms %p)
\n
"
,
i2400ms
);
spin_lock
(
&
i2400m
->
rx_lock
);
i2400ms
->
bm_ack_size
=
-
EINTR
;
spin_unlock
(
&
i2400m
->
rx_lock
);
wake_up_all
(
&
i2400ms
->
bm_wfa_wq
);
sdio_claim_host
(
func
);
sdio_claim_host
(
func
);
sdio_writeb
(
func
,
0
,
I2400MS_INTR_ENABLE_ADDR
,
&
result
);
sdio_writeb
(
func
,
0
,
I2400MS_INTR_ENABLE_ADDR
,
&
result
);
sdio_release_irq
(
func
);
sdio_release_irq
(
func
);
...
...
drivers/net/wimax/i2400m/sdio.c
View file @
3ee40c37
...
@@ -78,6 +78,14 @@ static const char *i2400ms_bus_fw_names[] = {
...
@@ -78,6 +78,14 @@ static const char *i2400ms_bus_fw_names[] = {
};
};
static
const
struct
i2400m_poke_table
i2400ms_pokes
[]
=
{
I2400M_FW_POKE
(
0x6BE260
,
0x00000088
),
I2400M_FW_POKE
(
0x080550
,
0x00000005
),
I2400M_FW_POKE
(
0xAE0000
,
0x00000000
),
I2400M_FW_POKE
(
0x000000
,
0x00000000
),
/* MUST be 0 terminated or bad
* things will happen */
};
/*
/*
* Enable the SDIO function
* Enable the SDIO function
*
*
...
@@ -148,19 +156,14 @@ int i2400ms_bus_dev_start(struct i2400m *i2400m)
...
@@ -148,19 +156,14 @@ int i2400ms_bus_dev_start(struct i2400m *i2400m)
d_fnstart
(
3
,
dev
,
"(i2400m %p)
\n
"
,
i2400m
);
d_fnstart
(
3
,
dev
,
"(i2400m %p)
\n
"
,
i2400m
);
msleep
(
200
);
msleep
(
200
);
result
=
i2400ms_rx_setup
(
i2400ms
);
if
(
result
<
0
)
goto
error_rx_setup
;
result
=
i2400ms_tx_setup
(
i2400ms
);
result
=
i2400ms_tx_setup
(
i2400ms
);
if
(
result
<
0
)
if
(
result
<
0
)
goto
error_tx_setup
;
goto
error_tx_setup
;
d_fnend
(
3
,
dev
,
"(i2400m %p) = %d
\n
"
,
i2400m
,
result
);
d_fnend
(
3
,
dev
,
"(i2400m %p) = %d
\n
"
,
i2400m
,
result
);
return
result
;
return
result
;
i2400ms_tx_release
(
i2400ms
);
error_tx_setup:
error_tx_setup:
i2400ms_rx_release
(
i2400ms
);
i2400ms_tx_release
(
i2400ms
);
error_rx_setup:
d_fnend
(
3
,
dev
,
"(i2400m %p) = void
\n
"
,
i2400m
);
d_fnend
(
3
,
dev
,
"(i2400m %p) = void
\n
"
,
i2400m
);
return
result
;
return
result
;
}
}
...
@@ -174,7 +177,6 @@ void i2400ms_bus_dev_stop(struct i2400m *i2400m)
...
@@ -174,7 +177,6 @@ void i2400ms_bus_dev_stop(struct i2400m *i2400m)
struct
device
*
dev
=
&
func
->
dev
;
struct
device
*
dev
=
&
func
->
dev
;
d_fnstart
(
3
,
dev
,
"(i2400m %p)
\n
"
,
i2400m
);
d_fnstart
(
3
,
dev
,
"(i2400m %p)
\n
"
,
i2400m
);
i2400ms_rx_release
(
i2400ms
);
i2400ms_tx_release
(
i2400ms
);
i2400ms_tx_release
(
i2400ms
);
d_fnend
(
3
,
dev
,
"(i2400m %p) = void
\n
"
,
i2400m
);
d_fnend
(
3
,
dev
,
"(i2400m %p) = void
\n
"
,
i2400m
);
}
}
...
@@ -255,7 +257,7 @@ int __i2400ms_send_barker(struct i2400ms *i2400ms,
...
@@ -255,7 +257,7 @@ int __i2400ms_send_barker(struct i2400ms *i2400ms,
static
static
int
i2400ms_bus_reset
(
struct
i2400m
*
i2400m
,
enum
i2400m_reset_type
rt
)
int
i2400ms_bus_reset
(
struct
i2400m
*
i2400m
,
enum
i2400m_reset_type
rt
)
{
{
int
result
;
int
result
=
0
;
struct
i2400ms
*
i2400ms
=
struct
i2400ms
*
i2400ms
=
container_of
(
i2400m
,
struct
i2400ms
,
i2400m
);
container_of
(
i2400m
,
struct
i2400ms
,
i2400m
);
struct
device
*
dev
=
i2400m_dev
(
i2400m
);
struct
device
*
dev
=
i2400m_dev
(
i2400m
);
...
@@ -280,8 +282,25 @@ int i2400ms_bus_reset(struct i2400m *i2400m, enum i2400m_reset_type rt)
...
@@ -280,8 +282,25 @@ int i2400ms_bus_reset(struct i2400m *i2400m, enum i2400m_reset_type rt)
sizeof
(
i2400m_COLD_BOOT_BARKER
));
sizeof
(
i2400m_COLD_BOOT_BARKER
));
else
if
(
rt
==
I2400M_RT_BUS
)
{
else
if
(
rt
==
I2400M_RT_BUS
)
{
do_bus_reset:
do_bus_reset:
dev_err
(
dev
,
"FIXME: SDIO bus reset not implemented
\n
"
);
/* call netif_tx_disable() before sending IOE disable,
result
=
rt
==
I2400M_RT_WARM
?
-
ENODEV
:
-
ENOSYS
;
* so that all the tx from network layer are stopped
* while IOE is being reset. Make sure it is called
* only after register_netdev() was issued.
*/
if
(
i2400m
->
wimax_dev
.
net_dev
->
reg_state
==
NETREG_REGISTERED
)
netif_tx_disable
(
i2400m
->
wimax_dev
.
net_dev
);
i2400ms_rx_release
(
i2400ms
);
sdio_claim_host
(
i2400ms
->
func
);
sdio_disable_func
(
i2400ms
->
func
);
sdio_release_host
(
i2400ms
->
func
);
/* Wait for the device to settle */
msleep
(
40
);
result
=
i2400ms_enable_function
(
i2400ms
->
func
);
if
(
result
>=
0
)
i2400ms_rx_setup
(
i2400ms
);
}
else
}
else
BUG
();
BUG
();
if
(
result
<
0
&&
rt
!=
I2400M_RT_BUS
)
{
if
(
result
<
0
&&
rt
!=
I2400M_RT_BUS
)
{
...
@@ -404,10 +423,14 @@ int i2400ms_probe(struct sdio_func *func,
...
@@ -404,10 +423,14 @@ int i2400ms_probe(struct sdio_func *func,
i2400m
->
bus_dev_stop
=
i2400ms_bus_dev_stop
;
i2400m
->
bus_dev_stop
=
i2400ms_bus_dev_stop
;
i2400m
->
bus_tx_kick
=
i2400ms_bus_tx_kick
;
i2400m
->
bus_tx_kick
=
i2400ms_bus_tx_kick
;
i2400m
->
bus_reset
=
i2400ms_bus_reset
;
i2400m
->
bus_reset
=
i2400ms_bus_reset
;
/* The iwmc3200-wimax sometimes requires the driver to try
* hard when we paint it into a corner. */
i2400m
->
bus_bm_retries
=
I3200_BOOT_RETRIES
;
i2400m
->
bus_bm_cmd_send
=
i2400ms_bus_bm_cmd_send
;
i2400m
->
bus_bm_cmd_send
=
i2400ms_bus_bm_cmd_send
;
i2400m
->
bus_bm_wait_for_ack
=
i2400ms_bus_bm_wait_for_ack
;
i2400m
->
bus_bm_wait_for_ack
=
i2400ms_bus_bm_wait_for_ack
;
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
;
i2400m
->
bus_bm_pokes_table
=
&
i2400ms_pokes
[
0
];
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
);
...
@@ -423,6 +446,10 @@ int i2400ms_probe(struct sdio_func *func,
...
@@ -423,6 +446,10 @@ int i2400ms_probe(struct sdio_func *func,
goto
error_func_enable
;
goto
error_func_enable
;
}
}
result
=
i2400ms_rx_setup
(
i2400ms
);
if
(
result
<
0
)
goto
error_rx_setup
;
result
=
i2400m_setup
(
i2400m
,
I2400M_BRI_NO_REBOOT
);
result
=
i2400m_setup
(
i2400m
,
I2400M_BRI_NO_REBOOT
);
if
(
result
<
0
)
{
if
(
result
<
0
)
{
dev_err
(
dev
,
"cannot setup device: %d
\n
"
,
result
);
dev_err
(
dev
,
"cannot setup device: %d
\n
"
,
result
);
...
@@ -440,6 +467,8 @@ int i2400ms_probe(struct sdio_func *func,
...
@@ -440,6 +467,8 @@ int i2400ms_probe(struct sdio_func *func,
error_debugfs_add:
error_debugfs_add:
i2400m_release
(
i2400m
);
i2400m_release
(
i2400m
);
error_setup:
error_setup:
i2400ms_rx_release
(
i2400ms
);
error_rx_setup:
sdio_claim_host
(
func
);
sdio_claim_host
(
func
);
sdio_disable_func
(
func
);
sdio_disable_func
(
func
);
sdio_release_host
(
func
);
sdio_release_host
(
func
);
...
@@ -462,6 +491,7 @@ void i2400ms_remove(struct sdio_func *func)
...
@@ -462,6 +491,7 @@ void i2400ms_remove(struct sdio_func *func)
d_fnstart
(
3
,
dev
,
"SDIO func %p
\n
"
,
func
);
d_fnstart
(
3
,
dev
,
"SDIO func %p
\n
"
,
func
);
debugfs_remove_recursive
(
i2400ms
->
debugfs_dentry
);
debugfs_remove_recursive
(
i2400ms
->
debugfs_dentry
);
i2400ms_rx_release
(
i2400ms
);
i2400m_release
(
i2400m
);
i2400m_release
(
i2400m
);
sdio_set_drvdata
(
func
,
NULL
);
sdio_set_drvdata
(
func
,
NULL
);
sdio_claim_host
(
func
);
sdio_claim_host
(
func
);
...
...
drivers/net/wimax/i2400m/tx.c
View file @
3ee40c37
...
@@ -277,6 +277,48 @@ enum {
...
@@ -277,6 +277,48 @@ enum {
#define TAIL_FULL ((void *)~(unsigned long)NULL)
#define TAIL_FULL ((void *)~(unsigned long)NULL)
/*
* Calculate how much tail room is available
*
* Note the trick here. This path is ONLY caleed for Case A (see
* i2400m_tx_fifo_push() below), where we have:
*
* Case A
* N ___________
* | tail room |
* | |
* |<- IN ->|
* | |
* | data |
* | |
* |<- OUT ->|
* | |
* | head room |
* 0 -----------
*
* When calculating the tail_room, tx_in might get to be zero if
* i2400m->tx_in is right at the end of the buffer (really full
* buffer) if there is no head room. In this case, tail_room would be
* I2400M_TX_BUF_SIZE, although it is actually zero. Hence the final
* mod (%) operation. However, when doing this kind of optimization,
* i2400m->tx_in being zero would fail, so we treat is an a special
* case.
*/
static
inline
size_t
__i2400m_tx_tail_room
(
struct
i2400m
*
i2400m
)
{
size_t
tail_room
;
size_t
tx_in
;
if
(
unlikely
(
i2400m
->
tx_in
)
==
0
)
return
I2400M_TX_BUF_SIZE
;
tx_in
=
i2400m
->
tx_in
%
I2400M_TX_BUF_SIZE
;
tail_room
=
I2400M_TX_BUF_SIZE
-
tx_in
;
tail_room
%=
I2400M_TX_BUF_SIZE
;
return
tail_room
;
}
/*
/*
* Allocate @size bytes in the TX fifo, return a pointer to it
* Allocate @size bytes in the TX fifo, return a pointer to it
*
*
...
@@ -338,7 +380,7 @@ void *i2400m_tx_fifo_push(struct i2400m *i2400m, size_t size, size_t padding)
...
@@ -338,7 +380,7 @@ void *i2400m_tx_fifo_push(struct i2400m *i2400m, size_t size, size_t padding)
return
NULL
;
return
NULL
;
}
}
/* Is there space at the tail? */
/* Is there space at the tail? */
tail_room
=
I2400M_TX_BUF_SIZE
-
i2400m
->
tx_in
%
I2400M_TX_BUF_SIZE
;
tail_room
=
__i2400m_tx_tail_room
(
i2400m
)
;
if
(
tail_room
<
needed_size
)
{
if
(
tail_room
<
needed_size
)
{
if
(
i2400m
->
tx_out
%
I2400M_TX_BUF_SIZE
if
(
i2400m
->
tx_out
%
I2400M_TX_BUF_SIZE
<
i2400m
->
tx_in
%
I2400M_TX_BUF_SIZE
)
{
<
i2400m
->
tx_in
%
I2400M_TX_BUF_SIZE
)
{
...
@@ -367,17 +409,29 @@ void *i2400m_tx_fifo_push(struct i2400m *i2400m, size_t size, size_t padding)
...
@@ -367,17 +409,29 @@ void *i2400m_tx_fifo_push(struct i2400m *i2400m, size_t size, size_t padding)
* (I2400M_PL_PAD for the payloads, I2400M_TX_PLD_SIZE for the
* (I2400M_PL_PAD for the payloads, I2400M_TX_PLD_SIZE for the
* header).
* header).
*
*
* Tail room can get to be zero if a message was opened when there was
* space only for a header. _tx_close() will mark it as to-skip (as it
* will have no payloads) and there will be no more space to flush, so
* nothing has to be done here. This is probably cheaper than ensuring
* in _tx_new() that there is some space for payloads...as we could
* always possibly hit the same problem if the payload wouldn't fit.
*
* Note:
* Note:
*
*
* Assumes i2400m->tx_lock is taken, and we use that as a barrier
* Assumes i2400m->tx_lock is taken, and we use that as a barrier
*
* This path is only taken for Case A FIFO situations [see
* i2400m_tx_fifo_push()]
*/
*/
static
static
void
i2400m_tx_skip_tail
(
struct
i2400m
*
i2400m
)
void
i2400m_tx_skip_tail
(
struct
i2400m
*
i2400m
)
{
{
struct
device
*
dev
=
i2400m_dev
(
i2400m
);
struct
device
*
dev
=
i2400m_dev
(
i2400m
);
size_t
tx_in
=
i2400m
->
tx_in
%
I2400M_TX_BUF_SIZE
;
size_t
tx_in
=
i2400m
->
tx_in
%
I2400M_TX_BUF_SIZE
;
size_t
tail_room
=
I2400M_TX_BUF_SIZE
-
tx_in
;
size_t
tail_room
=
__i2400m_tx_tail_room
(
i2400m
)
;
struct
i2400m_msg_hdr
*
msg
=
i2400m
->
tx_buf
+
tx_in
;
struct
i2400m_msg_hdr
*
msg
=
i2400m
->
tx_buf
+
tx_in
;
if
(
unlikely
(
tail_room
==
0
))
return
;
BUG_ON
(
tail_room
<
sizeof
(
*
msg
));
BUG_ON
(
tail_room
<
sizeof
(
*
msg
));
msg
->
size
=
tail_room
|
I2400M_TX_SKIP
;
msg
->
size
=
tail_room
|
I2400M_TX_SKIP
;
d_printf
(
2
,
dev
,
"skip tail: skipping %zu bytes @%zu
\n
"
,
d_printf
(
2
,
dev
,
"skip tail: skipping %zu bytes @%zu
\n
"
,
...
@@ -474,10 +528,18 @@ void i2400m_tx_close(struct i2400m *i2400m)
...
@@ -474,10 +528,18 @@ void i2400m_tx_close(struct i2400m *i2400m)
struct
i2400m_msg_hdr
*
tx_msg_moved
;
struct
i2400m_msg_hdr
*
tx_msg_moved
;
size_t
aligned_size
,
padding
,
hdr_size
;
size_t
aligned_size
,
padding
,
hdr_size
;
void
*
pad_buf
;
void
*
pad_buf
;
unsigned
num_pls
;
if
(
tx_msg
->
size
&
I2400M_TX_SKIP
)
/* a skipper? nothing to do */
if
(
tx_msg
->
size
&
I2400M_TX_SKIP
)
/* a skipper? nothing to do */
goto
out
;
goto
out
;
num_pls
=
le16_to_cpu
(
tx_msg
->
num_pls
);
/* We can get this situation when a new message was started
* and there was no space to add payloads before hitting the
tail (and taking padding into consideration). */
if
(
num_pls
==
0
)
{
tx_msg
->
size
|=
I2400M_TX_SKIP
;
goto
out
;
}
/* Relocate the message header
/* Relocate the message header
*
*
* Find the current header size, align it to 16 and if we need
* Find the current header size, align it to 16 and if we need
...
@@ -491,7 +553,7 @@ void i2400m_tx_close(struct i2400m *i2400m)
...
@@ -491,7 +553,7 @@ void i2400m_tx_close(struct i2400m *i2400m)
*/
*/
hdr_size
=
sizeof
(
*
tx_msg
)
hdr_size
=
sizeof
(
*
tx_msg
)
+
le16_to_cpu
(
tx_msg
->
num_pls
)
*
sizeof
(
tx_msg
->
pld
[
0
]);
+
le16_to_cpu
(
tx_msg
->
num_pls
)
*
sizeof
(
tx_msg
->
pld
[
0
]);
hdr_size
=
ALIGN
(
hdr_size
,
I2400M_PL_
PAD
);
hdr_size
=
ALIGN
(
hdr_size
,
I2400M_PL_
ALIGN
);
tx_msg
->
offset
=
I2400M_TX_PLD_SIZE
-
hdr_size
;
tx_msg
->
offset
=
I2400M_TX_PLD_SIZE
-
hdr_size
;
tx_msg_moved
=
(
void
*
)
tx_msg
+
tx_msg
->
offset
;
tx_msg_moved
=
(
void
*
)
tx_msg
+
tx_msg
->
offset
;
memmove
(
tx_msg_moved
,
tx_msg
,
hdr_size
);
memmove
(
tx_msg_moved
,
tx_msg
,
hdr_size
);
...
@@ -574,7 +636,7 @@ int i2400m_tx(struct i2400m *i2400m, const void *buf, size_t buf_len,
...
@@ -574,7 +636,7 @@ int i2400m_tx(struct i2400m *i2400m, const void *buf, size_t buf_len,
d_fnstart
(
3
,
dev
,
"(i2400m %p skb %p [%zu bytes] pt %u)
\n
"
,
d_fnstart
(
3
,
dev
,
"(i2400m %p skb %p [%zu bytes] pt %u)
\n
"
,
i2400m
,
buf
,
buf_len
,
pl_type
);
i2400m
,
buf
,
buf_len
,
pl_type
);
padded_len
=
ALIGN
(
buf_len
,
I2400M_PL_
PAD
);
padded_len
=
ALIGN
(
buf_len
,
I2400M_PL_
ALIGN
);
d_printf
(
5
,
dev
,
"padded_len %zd buf_len %zd
\n
"
,
padded_len
,
buf_len
);
d_printf
(
5
,
dev
,
"padded_len %zd buf_len %zd
\n
"
,
padded_len
,
buf_len
);
/* If there is no current TX message, create one; if the
/* If there is no current TX message, create one; if the
* current one is out of payload slots or we have a singleton,
* current one is out of payload slots or we have a singleton,
...
@@ -591,6 +653,8 @@ int i2400m_tx(struct i2400m *i2400m, const void *buf, size_t buf_len,
...
@@ -591,6 +653,8 @@ int i2400m_tx(struct i2400m *i2400m, const void *buf, size_t buf_len,
i2400m_tx_close
(
i2400m
);
i2400m_tx_close
(
i2400m
);
i2400m_tx_new
(
i2400m
);
i2400m_tx_new
(
i2400m
);
}
}
if
(
i2400m
->
tx_msg
==
NULL
)
goto
error_tx_new
;
if
(
i2400m
->
tx_msg
->
size
+
padded_len
>
I2400M_TX_BUF_SIZE
/
2
)
{
if
(
i2400m
->
tx_msg
->
size
+
padded_len
>
I2400M_TX_BUF_SIZE
/
2
)
{
d_printf
(
2
,
dev
,
"TX: message too big, going new
\n
"
);
d_printf
(
2
,
dev
,
"TX: message too big, going new
\n
"
);
i2400m_tx_close
(
i2400m
);
i2400m_tx_close
(
i2400m
);
...
@@ -773,7 +837,6 @@ void i2400m_tx_msg_sent(struct i2400m *i2400m)
...
@@ -773,7 +837,6 @@ void i2400m_tx_msg_sent(struct i2400m *i2400m)
n
=
i2400m
->
tx_out
/
I2400M_TX_BUF_SIZE
;
n
=
i2400m
->
tx_out
/
I2400M_TX_BUF_SIZE
;
i2400m
->
tx_out
%=
I2400M_TX_BUF_SIZE
;
i2400m
->
tx_out
%=
I2400M_TX_BUF_SIZE
;
i2400m
->
tx_in
-=
n
*
I2400M_TX_BUF_SIZE
;
i2400m
->
tx_in
-=
n
*
I2400M_TX_BUF_SIZE
;
netif_start_queue
(
i2400m
->
wimax_dev
.
net_dev
);
spin_unlock_irqrestore
(
&
i2400m
->
tx_lock
,
flags
);
spin_unlock_irqrestore
(
&
i2400m
->
tx_lock
,
flags
);
d_fnend
(
3
,
dev
,
"(i2400m %p) = void
\n
"
,
i2400m
);
d_fnend
(
3
,
dev
,
"(i2400m %p) = void
\n
"
,
i2400m
);
}
}
...
...
drivers/net/wimax/i2400m/usb.c
View file @
3ee40c37
...
@@ -254,8 +254,10 @@ int i2400mu_bus_reset(struct i2400m *i2400m, enum i2400m_reset_type rt)
...
@@ -254,8 +254,10 @@ int i2400mu_bus_reset(struct i2400m *i2400m, enum i2400m_reset_type rt)
dev_err
(
dev
,
"USB reset failed (%d), giving up!
\n
"
,
dev_err
(
dev
,
"USB reset failed (%d), giving up!
\n
"
,
result
);
result
);
}
}
}
else
}
else
{
result
=
-
EINVAL
;
/* shut gcc up in certain arches */
BUG
();
BUG
();
}
if
(
result
<
0
if
(
result
<
0
&&
result
!=
-
EINVAL
/* device is gone */
&&
result
!=
-
EINVAL
/* device is gone */
&&
rt
!=
I2400M_RT_BUS
)
{
&&
rt
!=
I2400M_RT_BUS
)
{
...
@@ -399,6 +401,7 @@ int i2400mu_probe(struct usb_interface *iface,
...
@@ -399,6 +401,7 @@ int i2400mu_probe(struct usb_interface *iface,
i2400m
->
bus_dev_stop
=
i2400mu_bus_dev_stop
;
i2400m
->
bus_dev_stop
=
i2400mu_bus_dev_stop
;
i2400m
->
bus_tx_kick
=
i2400mu_bus_tx_kick
;
i2400m
->
bus_tx_kick
=
i2400mu_bus_tx_kick
;
i2400m
->
bus_reset
=
i2400mu_bus_reset
;
i2400m
->
bus_reset
=
i2400mu_bus_reset
;
i2400m
->
bus_bm_retries
=
I2400M_BOOT_RETRIES
;
i2400m
->
bus_bm_cmd_send
=
i2400mu_bus_bm_cmd_send
;
i2400m
->
bus_bm_cmd_send
=
i2400mu_bus_bm_cmd_send
;
i2400m
->
bus_bm_wait_for_ack
=
i2400mu_bus_bm_wait_for_ack
;
i2400m
->
bus_bm_wait_for_ack
=
i2400mu_bus_bm_wait_for_ack
;
i2400m
->
bus_fw_names
=
i2400mu_bus_fw_names
;
i2400m
->
bus_fw_names
=
i2400mu_bus_fw_names
;
...
...
include/linux/wimax/i2400m.h
View file @
3ee40c37
...
@@ -266,7 +266,7 @@ enum i2400m_ro_type {
...
@@ -266,7 +266,7 @@ enum i2400m_ro_type {
/* Misc constants */
/* Misc constants */
enum
{
enum
{
I2400M_PL_
PAD
=
16
,
/* Payload data size alignment */
I2400M_PL_
ALIGN
=
16
,
/* Payload data size alignment */
I2400M_PL_SIZE_MAX
=
0x3EFF
,
I2400M_PL_SIZE_MAX
=
0x3EFF
,
I2400M_MAX_PLS_IN_MSG
=
60
,
I2400M_MAX_PLS_IN_MSG
=
60
,
/* protocol barkers: sync sequences; for notifications they
/* protocol barkers: sync sequences; for notifications they
...
...
net/wimax/op-rfkill.c
View file @
3ee40c37
...
@@ -113,7 +113,8 @@ void wimax_report_rfkill_hw(struct wimax_dev *wimax_dev,
...
@@ -113,7 +113,8 @@ void wimax_report_rfkill_hw(struct wimax_dev *wimax_dev,
else
else
wimax_state
=
WIMAX_ST_RADIO_OFF
;
wimax_state
=
WIMAX_ST_RADIO_OFF
;
rfkill_set_hw_state
(
wimax_dev
->
rfkill
,
state
==
WIMAX_RF_OFF
);
result
=
rfkill_set_hw_state
(
wimax_dev
->
rfkill
,
state
==
WIMAX_RF_OFF
);
__wimax_state_change
(
wimax_dev
,
wimax_state
);
__wimax_state_change
(
wimax_dev
,
wimax_state
);
}
}
...
...
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