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
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
Hide 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,8 +505,15 @@ void i2400m_report_hook(struct i2400m *i2400m,
* it. */
case
I2400M_MT_REPORT_POWERSAVE_READY
:
/* zzzzz */
if
(
l3l4_hdr
->
status
==
cpu_to_le16
(
I2400M_MS_DONE_OK
))
{
d_printf
(
1
,
dev
,
"ready for powersave, requesting
\n
"
);
i2400m_cmd_enter_powersave
(
i2400m
);
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
);
}
}
break
;
};
...
...
@@ -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
"
,
i2400m
,
buf
,
buf_len
);
rmb
();
/* Make sure we see what i2400m_dev_reset_handle() */
if
(
i2400m
->
boot_mode
)
return
ERR_PTR
(
-
E
NODEV
);
return
ERR_PTR
(
-
E
L3RST
);
msg_l3l4_hdr
=
buf
;
/* Check msg & payload consistency */
...
...
@@ -1389,16 +1397,16 @@ error:
*
* @i2400m: device descriptor
*
* Gracefully stops the device, moving it to the lowest power
* consumption state possible.
* Release resources acquired during the running of the device; in
* 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
)
{
int
result
=
-
ENODEV
;
struct
device
*
dev
=
i2400m_dev
(
i2400m
);
d_fnstart
(
3
,
dev
,
"(i2400m %p)
\n
"
,
i2400m
);
result
=
i2400m
->
bus_reset
(
i2400m
,
I2400M_RT_WARM
);
d_fnend
(
3
,
dev
,
"(i2400m %p) = void [%d]
\n
"
,
i2400m
,
result
);
d_fnend
(
3
,
dev
,
"(i2400m %p) = void
\n
"
,
i2400m
);
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);
MODULE_PARM_DESC
(
rx_reorder_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
*
...
...
@@ -172,7 +180,6 @@ int i2400m_schedule_work(struct i2400m *i2400m,
int
result
;
struct
i2400m_work
*
iw
;
BUG_ON
(
i2400m
->
work_queue
==
NULL
);
result
=
-
ENOMEM
;
iw
=
kzalloc
(
sizeof
(
*
iw
),
gfp_flags
);
if
(
iw
==
NULL
)
...
...
@@ -377,6 +384,11 @@ error:
* Uploads firmware and brings up all the resources needed to be able
* 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
* 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)
struct
wimax_dev
*
wimax_dev
=
&
i2400m
->
wimax_dev
;
struct
net_device
*
net_dev
=
wimax_dev
->
net_dev
;
struct
device
*
dev
=
i2400m_dev
(
i2400m
);
int
times
=
3
;
int
times
=
i2400m
->
bus_bm_retries
;
d_fnstart
(
3
,
dev
,
"(i2400m %p)
\n
"
,
i2400m
);
retry:
...
...
@@ -402,15 +414,15 @@ retry:
result
=
i2400m_rx_setup
(
i2400m
);
if
(
result
<
0
)
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
);
if
(
i2400m
->
work_queue
==
NULL
)
{
result
=
-
ENOMEM
;
dev_err
(
dev
,
"cannot create workqueue
\n
"
);
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? */
if
(
result
<
0
)
goto
error_fw_check
;
...
...
@@ -432,17 +444,17 @@ retry:
error_dev_initialize:
error_check_mac_addr:
error_fw_check:
destroy_workqueue
(
i2400m
->
work_queue
);
error_create_workqueue:
i2400m
->
bus_dev_stop
(
i2400m
);
error_bus_dev_start:
destroy_workqueue
(
i2400m
->
work_queue
);
error_create_workqueue:
i2400m_rx_release
(
i2400m
);
error_rx_setup:
i2400m_tx_release
(
i2400m
);
error_tx_setup:
error_bootstrap:
if
(
result
==
-
E
RESTARTSYS
&&
times
--
>
0
)
{
flags
=
I2400M_BRI_SOFT
;
if
(
result
==
-
E
L3RST
&&
times
--
>
0
)
{
flags
=
I2400M_BRI_SOFT
|
I2400M_BRI_MAC_REINIT
;
goto
retry
;
}
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)
*
* 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
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
);
i2400m_dev_shutdown
(
i2400m
);
i2400m
->
ready
=
0
;
destroy_workqueue
(
i2400m
->
work_queue
);
i2400m
->
bus_dev_stop
(
i2400m
);
destroy_workqueue
(
i2400m
->
work_queue
);
i2400m_rx_release
(
i2400m
);
i2400m_tx_release
(
i2400m
);
wimax_state_change
(
wimax_dev
,
WIMAX_ST_DOWN
);
...
...
@@ -546,7 +560,7 @@ void __i2400m_dev_reset_handle(struct work_struct *ws)
* i2400m_dev_stop() [we are shutting down anyway, so
* ignore it] or we are resetting somewhere else. */
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
);
goto
out
;
}
...
...
@@ -596,6 +610,8 @@ out:
*/
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
,
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,
unsigned
int
direct
,
unsigned
int
do_csum
)
{
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
{
struct
i2400m_bootrom_header
cmd
;
...
...
@@ -532,14 +532,14 @@ int i2400m_dnload_finalize(struct i2400m *i2400m,
cmd
=
(
void
*
)
bcf
+
offset
;
if
(
i2400m
->
sboot
==
0
)
{
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
));
i2400m_brh_set_opcode
(
cmd
,
I2400M_BRH_JUMP
);
cmd
->
data_size
=
0
;
ret
=
i2400m_bm_cmd
(
i2400m
,
cmd
,
sizeof
(
*
cmd
),
&
jump_ack
,
sizeof
(
jump_ack
),
0
);
}
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
));
cmd_buf
=
i2400m
->
bm_cmd_buf
;
memcpy
(
&
cmd_buf
->
cmd
,
cmd
,
sizeof
(
*
cmd
));
...
...
@@ -696,8 +696,7 @@ error_dev_gone:
return
result
;
error_timeout:
dev_err
(
dev
,
"Timed out waiting for reboot ack, resetting
\n
"
);
i2400m
->
bus_reset
(
i2400m
,
I2400M_RT_BUS
);
dev_err
(
dev
,
"Timed out waiting for reboot ack
\n
"
);
result
=
-
ETIMEDOUT
;
goto
exit_timeout
;
}
...
...
@@ -770,40 +769,21 @@ error_read_mac:
static
int
i2400m_dnload_init_nonsigned
(
struct
i2400m
*
i2400m
)
{
#define POKE(a, d) { \
.address = cpu_to_le32(a), \
.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
;
unsigned
i
=
0
;
int
ret
=
0
;
struct
device
*
dev
=
i2400m_dev
(
i2400m
);
dev_warn
(
dev
,
"WARNING!!! non-signed boot UNTESTED PATH!
\n
"
);
d_fnstart
(
5
,
dev
,
"(i2400m %p)
\n
"
,
i2400m
);
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
i2400m_pokes
);
i
++
)
{
ret
=
i2400m_download_chunk
(
i2400m
,
&
i2400m_pokes
[
i
].
data
,
sizeof
(
i2400m_pokes
[
i
].
data
),
i2400m_pokes
[
i
].
address
,
1
,
1
);
if
(
ret
<
0
)
break
;
if
(
i2400m
->
bus_bm_pokes_table
)
{
while
(
i2400m
->
bus_bm_pokes_table
[
i
].
address
)
{
ret
=
i2400m_download_chunk
(
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
)
break
;
i
++
;
}
}
d_fnend
(
5
,
dev
,
"(i2400m %p) = %d
\n
"
,
i2400m
,
ret
);
return
ret
;
...
...
@@ -980,11 +960,12 @@ int i2400m_fw_dnload(struct i2400m *i2400m, const struct i2400m_bcf_hdr *bcf,
{
int
ret
=
0
;
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
"
,
i2400m
,
bcf
,
bcf_size
);
i2400m
->
boot_mode
=
1
;
wmb
();
/* Make sure other readers see it */
hw_reboot:
if
(
count
--
==
0
)
{
ret
=
-
ERESTARTSYS
;
...
...
@@ -1033,6 +1014,7 @@ hw_reboot:
d_printf
(
2
,
dev
,
"fw %s successfully uploaded
\n
"
,
i2400m
->
fw_name
);
i2400m
->
boot_mode
=
0
;
wmb
();
/* Make sure i2400m_msg_to_dev() sees boot_mode */
error_dnload_finalize:
error_dnload_bcf:
error_dnload_init:
...
...
drivers/net/wimax/i2400m/i2400m-sdio.h
View file @
3ee40c37
...
...
@@ -78,6 +78,8 @@ enum {
/* The number of ticks to wait for the device to signal that
* it is ready */
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 {
char
tx_wq_name
[
32
];
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 *,
extern
ssize_t
i2400ms_bus_bm_wait_for_ack
(
struct
i2400m
*
,
struct
i2400m_bootrom_header
*
,
size_t
);
extern
void
i2400ms_bus_bm_release
(
struct
i2400m
*
);
extern
int
i2400ms_bus_bm_setup
(
struct
i2400m
*
);
#endif
/* #ifndef __I2400M_SDIO_H__ */
drivers/net/wimax/i2400m/i2400m.h
View file @
3ee40c37
...
...
@@ -150,11 +150,33 @@
enum
{
/* Firmware uploading */
I2400M_BOOT_RETRIES
=
3
,
I3200_BOOT_RETRIES
=
3
,
/* Size of the Boot Mode Command buffer */
I2400M_BM_CMD_BUF_SIZE
=
16
*
1024
,
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
...
...
@@ -224,6 +246,17 @@ struct i2400m_roq;
* process, so it cannot rely on common infrastructure being laid
* 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
* 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
...
...
@@ -252,6 +285,12 @@ struct i2400m_roq;
* address provided in boot mode is kind of broken and needs to
* 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
* stack. Due to the way a net_device is allocated, we need to
...
...
@@ -399,6 +438,8 @@ struct i2400m {
size_t
bus_tx_block_size
;
size_t
bus_pl_size_max
;
unsigned
bus_bm_retries
;
int
(
*
bus_dev_start
)(
struct
i2400m
*
);
void
(
*
bus_dev_stop
)(
struct
i2400m
*
);
void
(
*
bus_tx_kick
)(
struct
i2400m
*
);
...
...
@@ -410,6 +451,7 @@ struct i2400m {
struct
i2400m_bootrom_header
*
,
size_t
);
const
char
**
bus_fw_names
;
unsigned
bus_bm_mac_addr_impaired
:
1
;
const
struct
i2400m_poke_table
*
bus_bm_pokes_table
;
spinlock_t
tx_lock
;
/* protect TX state */
void
*
tx_buf
;
...
...
@@ -709,6 +751,7 @@ static const __le32 i2400m_SBOOT_BARKER[4] = {
cpu_to_le32
(
I2400M_SBOOT_BARKER
)
};
extern
int
i2400m_power_save_disabled
;
/*
* 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)
/* state == WIMAX_RF_ON */
return
i2400m
->
state
!=
I2400M_SS_RF_OFF
&&
i2400m
->
state
!=
I2400M_SS_RF_SHUTDOWN
;
else
else
{
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)
num_pls
=
le16_to_cpu
(
msg_hdr
->
num_pls
);
pl_itr
=
sizeof
(
*
msg_hdr
)
+
/* Check payload descriptor(s) */
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? */
dev_err
(
dev
,
"RX: HW BUG? message too short (%u bytes) for "
"%u payload descriptors (%zu each, total %zu)
\n
"
,
...
...
@@ -1166,7 +1166,7 @@ int i2400m_rx(struct i2400m *i2400m, struct sk_buff *skb)
single_last
=
num_pls
==
1
||
i
==
num_pls
-
1
;
i2400m_rx_payload
(
i2400m
,
skb
,
single_last
,
&
msg_hdr
->
pld
[
i
],
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 */
}
kfree_skb
(
skb
);
...
...
drivers/net/wimax/i2400m/sdio-fw.c
View file @
3ee40c37
...
...
@@ -46,17 +46,24 @@
* Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com>
* - SDIO rehash for changes in the bus-driver model
*
* Dirk Brandewie <dirk.j.brandewie@intel.com>
* - Make it IRQ based, not polling
*
* THE PROCEDURE
*
* See fw.c for the generic description of this procedure.
*
* This file implements only the SDIO specifics. It boils down to how
* 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
*
* 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.
*
* The SDIO devices expects things in 256 byte blocks, so it will pad
...
...
@@ -64,12 +71,15 @@
*
* ACK RECEPTION
*
* This works in
polling mode -- the fw loader says when to wait for
*
data
and for that it calls i2400ms_bus_bm_wait_for_ack().
* This works in
IRQ mode -- the fw loader says when to wait for data
* 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
* receive at least as much bytes as where asked for (although it'll
* always be a multiple of 256 bytes).
* This checks if there is any data available (RX size > 0); if not,
* waits for the IRQ handler to notify about it. Once there is data,
* 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 "i2400m-sdio.h"
...
...
@@ -78,6 +88,7 @@
#define D_SUBMODULE fw
#include "sdio-debug-levels.h"
/*
* Send a boot-mode command to the SDIO function
*
...
...
@@ -139,7 +150,7 @@ error_too_big:
/*
* Read an ack from the device's boot-mode
(polling)
* Read an ack from the device's boot-mode
*
* @i2400m:
* @_ack: pointer to where to store the read data
...
...
@@ -150,75 +161,49 @@ error_too_big:
* 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
*
* 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
,
struct
i2400m_bootrom_header
*
ack
,
size_t
ack_size
)
{
int
result
;
ssize_t
rx_size
;
u64
timeout
;
ssize_t
result
;
struct
i2400ms
*
i2400ms
=
container_of
(
i2400m
,
struct
i2400ms
,
i2400m
);
struct
sdio_func
*
func
=
i2400ms
->
func
;
struct
device
*
dev
=
&
func
->
dev
;
int
size
;
BUG_ON
(
sizeof
(
*
ack
)
>
ack_size
);
d_fnstart
(
5
,
dev
,
"(i2400m %p ack %p size %zu)
\n
"
,
i2400m
,
ack
,
ack_size
);
timeout
=
get_jiffies_64
()
+
2
*
HZ
;
sdio_claim_host
(
func
);
while
(
1
)
{
if
(
time_after64
(
get_jiffies_64
(),
timeout
))
{
rx_size
=
-
ETIMEDOUT
;
dev_err
(
dev
,
"timeout waiting for ack data
\n
"
);
goto
error_timedout
;
}
spin_lock
(
&
i2400m
->
rx_lock
);
i2400ms
->
bm_ack_size
=
-
EINPROGRESS
;
spin_unlock
(
&
i2400m
->
rx_lock
);
/* Find the RX size, check if it fits or not -- it if
* doesn't fit, fail, as we have no way to dispose of
* the extra data. */
rx_size
=
__i2400ms_rx_get_size
(
i2400ms
);
if
(
rx_size
<
0
)
goto
error_rx_get_size
;
result
=
-
ENOSPC
;
/* Check it fits */
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
;
}
result
=
wait_event_timeout
(
i2400ms
->
bm_wfa_wq
,
i2400ms
->
bm_ack_size
!=
-
EINPROGRESS
,
2
*
HZ
);
if
(
result
==
0
)
{
result
=
-
ETIMEDOUT
;
dev_err
(
dev
,
"BM: error waiting for an ack
\n
"
);
goto
error_timeout
;
}
/* Read it */
result
=
sdio_memcpy_fromio
(
func
,
i2400m
->
bm_ack_buf
,
I2400MS_DATA_ADDR
,
rx_size
);
if
(
result
==
-
ETIMEDOUT
||
result
==
-
ETIME
)
continue
;
if
(
result
<
0
)
{
dev_err
(
dev
,
"BM SDIO receive (%zu B) failed: %d
\n
"
,
rx_size
,
result
);
goto
error_read
;
}
else
break
;
spin_lock
(
&
i2400m
->
rx_lock
);
result
=
i2400ms
->
bm_ack_size
;
BUG_ON
(
result
==
-
EINPROGRESS
);
if
(
result
<
0
)
/* so we exit when rx_release() is called */
dev_err
(
dev
,
"BM: %s failed: %zd
\n
"
,
__func__
,
result
);
else
{
size
=
min
(
ack_size
,
i2400ms
->
bm_ack_size
);
memcpy
(
ack
,
i2400m
->
bm_ack_buf
,
size
);
}
rx_size
=
min
((
ssize_t
)
ack_size
,
rx_size
);
memcpy
(
ack
,
i2400m
->
bm_ack_buf
,
rx_size
);
error_read:
error_too_small:
error_rx_get_size:
error_timedout:
sdio_release_host
(
func
);
d_fnend
(
5
,
dev
,
"(i2400m %p ack %p size %zu) = %ld
\n
"
,
i2400m
,
ack
,
ack_size
,
(
long
)
rx_size
);
return
rx_size
;
i2400ms
->
bm_ack_size
=
-
EINPROGRESS
;
spin_unlock
(
&
i2400m
->
rx_lock
);
error_timeout:
d_fnend
(
5
,
dev
,
"(i2400m %p ack %p size %zu) = %zd
\n
"
,
i2400m
,
ack
,
ack_size
,
result
);
return
result
;
}
drivers/net/wimax/i2400m/sdio-rx.c
View file @
3ee40c37
...
...
@@ -69,6 +69,13 @@
#define D_SUBMODULE rx
#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
...
...
@@ -131,25 +138,35 @@ void i2400ms_rx(struct i2400ms *i2400ms)
ret
=
rx_size
;
goto
error_get_size
;
}
ret
=
-
ENOMEM
;
skb
=
alloc_skb
(
rx_size
,
GFP_ATOMIC
);
if
(
NULL
==
skb
)
{
dev_err
(
dev
,
"RX: unable to alloc skb
\n
"
);
goto
error_alloc_skb
;
}
ret
=
sdio_memcpy_fromio
(
func
,
skb
->
data
,
I2400MS_DATA_ADDR
,
rx_size
);
if
(
ret
<
0
)
{
dev_err
(
dev
,
"RX: SDIO data read failed: %d
\n
"
,
ret
);
goto
error_memcpy_fromio
;
}
/* Check if device has reset */
if
(
!
memcmp
(
skb
->
data
,
i2400m_NBOOT_BARKER
,
sizeof
(
i2400m_NBOOT_BARKER
))
||
!
memcmp
(
skb
->
data
,
i2400m_SBOOT_BARKER
,
sizeof
(
i2400m_SBOOT_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
))
||
!
memcmp
(
skb
->
data
,
i2400m_SBOOT_BARKER
,
sizeof
(
i2400m_SBOOT_BARKER
))))
{
ret
=
i2400m_dev_reset_handle
(
i2400m
);
dev_err
(
dev
,
"RX: SDIO reboot barker
\n
"
);
kfree_skb
(
skb
);
}
else
{
skb_put
(
skb
,
rx_size
);
...
...
@@ -179,7 +196,6 @@ void i2400ms_irq(struct sdio_func *func)
{
int
ret
;
struct
i2400ms
*
i2400ms
=
sdio_get_drvdata
(
func
);
struct
i2400m
*
i2400m
=
&
i2400ms
->
i2400m
;
struct
device
*
dev
=
&
func
->
dev
;
int
val
;
...
...
@@ -194,10 +210,7 @@ void i2400ms_irq(struct sdio_func *func)
goto
error_no_irq
;
}
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:
d_fnend
(
6
,
dev
,
"(i2400ms %p) = void
\n
"
,
i2400ms
);
return
;
...
...
@@ -214,8 +227,15 @@ int i2400ms_rx_setup(struct i2400ms *i2400ms)
int
result
;
struct
sdio_func
*
func
=
i2400ms
->
func
;
struct
device
*
dev
=
&
func
->
dev
;
struct
i2400m
*
i2400m
=
&
i2400ms
->
i2400m
;
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
);
result
=
sdio_claim_irq
(
func
,
i2400ms_irq
);
if
(
result
<
0
)
{
...
...
@@ -245,8 +265,13 @@ void i2400ms_rx_release(struct i2400ms *i2400ms)
int
result
;
struct
sdio_func
*
func
=
i2400ms
->
func
;
struct
device
*
dev
=
&
func
->
dev
;
struct
i2400m
*
i2400m
=
&
i2400ms
->
i2400m
;
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_writeb
(
func
,
0
,
I2400MS_INTR_ENABLE_ADDR
,
&
result
);
sdio_release_irq
(
func
);
...
...
drivers/net/wimax/i2400m/sdio.c
View file @
3ee40c37
...
...
@@ -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
*
...
...
@@ -148,19 +156,14 @@ int i2400ms_bus_dev_start(struct i2400m *i2400m)
d_fnstart
(
3
,
dev
,
"(i2400m %p)
\n
"
,
i2400m
);
msleep
(
200
);
result
=
i2400ms_rx_setup
(
i2400ms
);
if
(
result
<
0
)
goto
error_rx_setup
;
result
=
i2400ms_tx_setup
(
i2400ms
);
if
(
result
<
0
)
goto
error_tx_setup
;
d_fnend
(
3
,
dev
,
"(i2400m %p) = %d
\n
"
,
i2400m
,
result
);
return
result
;
i2400ms_tx_release
(
i2400ms
);
error_tx_setup:
i2400ms_rx_release
(
i2400ms
);
error_rx_setup:
i2400ms_tx_release
(
i2400ms
);
d_fnend
(
3
,
dev
,
"(i2400m %p) = void
\n
"
,
i2400m
);
return
result
;
}
...
...
@@ -174,7 +177,6 @@ void i2400ms_bus_dev_stop(struct i2400m *i2400m)
struct
device
*
dev
=
&
func
->
dev
;
d_fnstart
(
3
,
dev
,
"(i2400m %p)
\n
"
,
i2400m
);
i2400ms_rx_release
(
i2400ms
);
i2400ms_tx_release
(
i2400ms
);
d_fnend
(
3
,
dev
,
"(i2400m %p) = void
\n
"
,
i2400m
);
}
...
...
@@ -255,7 +257,7 @@ error_kzalloc:
static
int
i2400ms_bus_reset
(
struct
i2400m
*
i2400m
,
enum
i2400m_reset_type
rt
)
{
int
result
;
int
result
=
0
;
struct
i2400ms
*
i2400ms
=
container_of
(
i2400m
,
struct
i2400ms
,
i2400m
);
struct
device
*
dev
=
i2400m_dev
(
i2400m
);
...
...
@@ -280,8 +282,25 @@ int i2400ms_bus_reset(struct i2400m *i2400m, enum i2400m_reset_type rt)
sizeof
(
i2400m_COLD_BOOT_BARKER
));
else
if
(
rt
==
I2400M_RT_BUS
)
{
do_bus_reset:
dev_err
(
dev
,
"FIXME: SDIO bus reset not implemented
\n
"
);
result
=
rt
==
I2400M_RT_WARM
?
-
ENODEV
:
-
ENOSYS
;
/* call netif_tx_disable() before sending IOE disable,
* 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
BUG
();
if
(
result
<
0
&&
rt
!=
I2400M_RT_BUS
)
{
...
...
@@ -404,10 +423,14 @@ int i2400ms_probe(struct sdio_func *func,
i2400m
->
bus_dev_stop
=
i2400ms_bus_dev_stop
;
i2400m
->
bus_tx_kick
=
i2400ms_bus_tx_kick
;
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_wait_for_ack
=
i2400ms_bus_bm_wait_for_ack
;
i2400m
->
bus_fw_names
=
i2400ms_bus_fw_names
;
i2400m
->
bus_bm_mac_addr_impaired
=
1
;
i2400m
->
bus_bm_pokes_table
=
&
i2400ms_pokes
[
0
];
sdio_claim_host
(
func
);
result
=
sdio_set_block_size
(
func
,
I2400MS_BLK_SIZE
);
...
...
@@ -423,6 +446,10 @@ int i2400ms_probe(struct sdio_func *func,
goto
error_func_enable
;
}
result
=
i2400ms_rx_setup
(
i2400ms
);
if
(
result
<
0
)
goto
error_rx_setup
;
result
=
i2400m_setup
(
i2400m
,
I2400M_BRI_NO_REBOOT
);
if
(
result
<
0
)
{
dev_err
(
dev
,
"cannot setup device: %d
\n
"
,
result
);
...
...
@@ -440,6 +467,8 @@ int i2400ms_probe(struct sdio_func *func,
error_debugfs_add:
i2400m_release
(
i2400m
);
error_setup:
i2400ms_rx_release
(
i2400ms
);
error_rx_setup:
sdio_claim_host
(
func
);
sdio_disable_func
(
func
);
sdio_release_host
(
func
);
...
...
@@ -462,6 +491,7 @@ void i2400ms_remove(struct sdio_func *func)
d_fnstart
(
3
,
dev
,
"SDIO func %p
\n
"
,
func
);
debugfs_remove_recursive
(
i2400ms
->
debugfs_dentry
);
i2400ms_rx_release
(
i2400ms
);
i2400m_release
(
i2400m
);
sdio_set_drvdata
(
func
,
NULL
);
sdio_claim_host
(
func
);
...
...
drivers/net/wimax/i2400m/tx.c
View file @
3ee40c37
...
...
@@ -277,6 +277,48 @@ enum {
#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
*
...
...
@@ -338,7 +380,7 @@ void *i2400m_tx_fifo_push(struct i2400m *i2400m, size_t size, size_t padding)
return
NULL
;
}
/* 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
(
i2400m
->
tx_out
%
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)
* (I2400M_PL_PAD for the payloads, I2400M_TX_PLD_SIZE for the
* 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:
*
* 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
void
i2400m_tx_skip_tail
(
struct
i2400m
*
i2400m
)
{
struct
device
*
dev
=
i2400m_dev
(
i2400m
);
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
;
if
(
unlikely
(
tail_room
==
0
))
return
;
BUG_ON
(
tail_room
<
sizeof
(
*
msg
));
msg
->
size
=
tail_room
|
I2400M_TX_SKIP
;
d_printf
(
2
,
dev
,
"skip tail: skipping %zu bytes @%zu
\n
"
,
...
...
@@ -474,10 +528,18 @@ void i2400m_tx_close(struct i2400m *i2400m)
struct
i2400m_msg_hdr
*
tx_msg_moved
;
size_t
aligned_size
,
padding
,
hdr_size
;
void
*
pad_buf
;
unsigned
num_pls
;
if
(
tx_msg
->
size
&
I2400M_TX_SKIP
)
/* a skipper? nothing to do */
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
*
* Find the current header size, align it to 16 and if we need
...
...
@@ -491,7 +553,7 @@ void i2400m_tx_close(struct i2400m *i2400m)
*/
hdr_size
=
sizeof
(
*
tx_msg
)
+
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_moved
=
(
void
*
)
tx_msg
+
tx_msg
->
offset
;
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,
d_fnstart
(
3
,
dev
,
"(i2400m %p skb %p [%zu bytes] pt %u)
\n
"
,
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
);
/* If there is no current TX message, create one; if the
* current one is out of payload slots or we have a singleton,
...
...
@@ -591,6 +653,8 @@ try_new:
i2400m_tx_close
(
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
)
{
d_printf
(
2
,
dev
,
"TX: message too big, going new
\n
"
);
i2400m_tx_close
(
i2400m
);
...
...
@@ -773,7 +837,6 @@ void i2400m_tx_msg_sent(struct i2400m *i2400m)
n
=
i2400m
->
tx_out
/
I2400M_TX_BUF_SIZE
;
i2400m
->
tx_out
%=
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
);
d_fnend
(
3
,
dev
,
"(i2400m %p) = void
\n
"
,
i2400m
);
}
...
...
drivers/net/wimax/i2400m/usb.c
View file @
3ee40c37
...
...
@@ -254,8 +254,10 @@ do_bus_reset:
dev_err
(
dev
,
"USB reset failed (%d), giving up!
\n
"
,
result
);
}
}
else
}
else
{
result
=
-
EINVAL
;
/* shut gcc up in certain arches */
BUG
();
}
if
(
result
<
0
&&
result
!=
-
EINVAL
/* device is gone */
&&
rt
!=
I2400M_RT_BUS
)
{
...
...
@@ -399,6 +401,7 @@ int i2400mu_probe(struct usb_interface *iface,
i2400m
->
bus_dev_stop
=
i2400mu_bus_dev_stop
;
i2400m
->
bus_tx_kick
=
i2400mu_bus_tx_kick
;
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_wait_for_ack
=
i2400mu_bus_bm_wait_for_ack
;
i2400m
->
bus_fw_names
=
i2400mu_bus_fw_names
;
...
...
include/linux/wimax/i2400m.h
View file @
3ee40c37
...
...
@@ -266,7 +266,7 @@ enum i2400m_ro_type {
/* Misc constants */
enum
{
I2400M_PL_
PAD
=
16
,
/* Payload data size alignment */
I2400M_PL_
ALIGN
=
16
,
/* Payload data size alignment */
I2400M_PL_SIZE_MAX
=
0x3EFF
,
I2400M_MAX_PLS_IN_MSG
=
60
,
/* 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,
else
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
);
}
...
...
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