2 * This file contains the handling of command.
3 * It prepares command and sends it to firmware when it is ready.
6 #include <net/iw_handler.h>
15 static void cleanup_cmdnode(struct cmd_ctrl_node
*ptempnode
);
16 struct cmd_ctrl_node
*lbs_get_cmd_ctrl_node(struct lbs_private
*priv
);
17 void lbs_set_cmd_ctrl_node(struct lbs_private
*priv
,
18 struct cmd_ctrl_node
*ptempnode
,
19 u16 wait_option
, void *pdata_buf
);
22 static u16 commands_allowed_in_ps
[] = {
27 * @brief This function checks if the commans is allowed
30 * @param command the command ID
31 * @return TRUE or FALSE
33 static u8
is_command_allowed_in_ps(__le16 command
)
37 for (i
= 0; i
< ARRAY_SIZE(commands_allowed_in_ps
); i
++) {
38 if (command
== cpu_to_le16(commands_allowed_in_ps
[i
]))
45 static int lbs_cmd_hw_spec(struct lbs_private
*priv
, struct cmd_ds_command
*cmd
)
47 struct cmd_ds_get_hw_spec
*hwspec
= &cmd
->params
.hwspec
;
49 lbs_deb_enter(LBS_DEB_CMD
);
51 cmd
->command
= cpu_to_le16(CMD_GET_HW_SPEC
);
52 cmd
->size
= cpu_to_le16(sizeof(struct cmd_ds_get_hw_spec
) + S_DS_GEN
);
53 memcpy(hwspec
->permanentaddr
, priv
->current_addr
, ETH_ALEN
);
55 lbs_deb_leave(LBS_DEB_CMD
);
59 static int lbs_cmd_802_11_ps_mode(struct lbs_private
*priv
,
60 struct cmd_ds_command
*cmd
,
63 struct cmd_ds_802_11_ps_mode
*psm
= &cmd
->params
.psmode
;
65 lbs_deb_enter(LBS_DEB_CMD
);
67 cmd
->command
= cpu_to_le16(CMD_802_11_PS_MODE
);
68 cmd
->size
= cpu_to_le16(sizeof(struct cmd_ds_802_11_ps_mode
) +
70 psm
->action
= cpu_to_le16(cmd_action
);
71 psm
->multipledtim
= 0;
73 case CMD_SUBCMD_ENTER_PS
:
74 lbs_deb_cmd("PS command:" "SubCode- Enter PS\n");
76 psm
->locallisteninterval
= 0;
77 psm
->nullpktinterval
= 0;
79 cpu_to_le16(MRVDRV_DEFAULT_MULTIPLE_DTIM
);
82 case CMD_SUBCMD_EXIT_PS
:
83 lbs_deb_cmd("PS command:" "SubCode- Exit PS\n");
86 case CMD_SUBCMD_SLEEP_CONFIRMED
:
87 lbs_deb_cmd("PS command: SubCode- sleep confirm\n");
94 lbs_deb_leave(LBS_DEB_CMD
);
98 static int lbs_cmd_802_11_inactivity_timeout(struct lbs_private
*priv
,
99 struct cmd_ds_command
*cmd
,
100 u16 cmd_action
, void *pdata_buf
)
102 u16
*timeout
= pdata_buf
;
104 lbs_deb_enter(LBS_DEB_CMD
);
106 cmd
->command
= cpu_to_le16(CMD_802_11_INACTIVITY_TIMEOUT
);
108 cpu_to_le16(sizeof(struct cmd_ds_802_11_inactivity_timeout
)
111 cmd
->params
.inactivity_timeout
.action
= cpu_to_le16(cmd_action
);
114 cmd
->params
.inactivity_timeout
.timeout
= cpu_to_le16(*timeout
);
116 cmd
->params
.inactivity_timeout
.timeout
= 0;
118 lbs_deb_leave(LBS_DEB_CMD
);
122 static int lbs_cmd_802_11_sleep_params(struct lbs_private
*priv
,
123 struct cmd_ds_command
*cmd
,
126 struct cmd_ds_802_11_sleep_params
*sp
= &cmd
->params
.sleep_params
;
128 lbs_deb_enter(LBS_DEB_CMD
);
130 cmd
->size
= cpu_to_le16((sizeof(struct cmd_ds_802_11_sleep_params
)) +
132 cmd
->command
= cpu_to_le16(CMD_802_11_SLEEP_PARAMS
);
134 if (cmd_action
== CMD_ACT_GET
) {
135 memset(&priv
->sp
, 0, sizeof(struct sleep_params
));
136 memset(sp
, 0, sizeof(struct cmd_ds_802_11_sleep_params
));
137 sp
->action
= cpu_to_le16(cmd_action
);
138 } else if (cmd_action
== CMD_ACT_SET
) {
139 sp
->action
= cpu_to_le16(cmd_action
);
140 sp
->error
= cpu_to_le16(priv
->sp
.sp_error
);
141 sp
->offset
= cpu_to_le16(priv
->sp
.sp_offset
);
142 sp
->stabletime
= cpu_to_le16(priv
->sp
.sp_stabletime
);
143 sp
->calcontrol
= (u8
) priv
->sp
.sp_calcontrol
;
144 sp
->externalsleepclk
= (u8
) priv
->sp
.sp_extsleepclk
;
145 sp
->reserved
= cpu_to_le16(priv
->sp
.sp_reserved
);
148 lbs_deb_leave(LBS_DEB_CMD
);
152 static int lbs_cmd_802_11_set_wep(struct lbs_private
*priv
,
153 struct cmd_ds_command
*cmd
,
157 struct cmd_ds_802_11_set_wep
*wep
= &cmd
->params
.wep
;
159 struct assoc_request
* assoc_req
= pdata_buf
;
161 lbs_deb_enter(LBS_DEB_CMD
);
163 cmd
->command
= cpu_to_le16(CMD_802_11_SET_WEP
);
164 cmd
->size
= cpu_to_le16(sizeof(*wep
) + S_DS_GEN
);
166 if (cmd_act
== CMD_ACT_ADD
) {
170 lbs_deb_cmd("Invalid association request!");
175 wep
->action
= cpu_to_le16(CMD_ACT_ADD
);
177 /* default tx key index */
178 wep
->keyindex
= cpu_to_le16((u16
)(assoc_req
->wep_tx_keyidx
&
179 (u32
)CMD_WEP_KEY_INDEX_MASK
));
181 /* Copy key types and material to host command structure */
182 for (i
= 0; i
< 4; i
++) {
183 struct enc_key
* pkey
= &assoc_req
->wep_keys
[i
];
187 wep
->keytype
[i
] = CMD_TYPE_WEP_40_BIT
;
188 memmove(&wep
->keymaterial
[i
], pkey
->key
,
190 lbs_deb_cmd("SET_WEP: add key %d (40 bit)\n", i
);
192 case KEY_LEN_WEP_104
:
193 wep
->keytype
[i
] = CMD_TYPE_WEP_104_BIT
;
194 memmove(&wep
->keymaterial
[i
], pkey
->key
,
196 lbs_deb_cmd("SET_WEP: add key %d (104 bit)\n", i
);
201 lbs_deb_cmd("SET_WEP: invalid key %d, length %d\n",
208 } else if (cmd_act
== CMD_ACT_REMOVE
) {
209 /* ACT_REMOVE clears _all_ WEP keys */
210 wep
->action
= cpu_to_le16(CMD_ACT_REMOVE
);
212 /* default tx key index */
213 wep
->keyindex
= cpu_to_le16((u16
)(priv
->wep_tx_keyidx
&
214 (u32
)CMD_WEP_KEY_INDEX_MASK
));
215 lbs_deb_cmd("SET_WEP: remove key %d\n", priv
->wep_tx_keyidx
);
221 lbs_deb_leave_args(LBS_DEB_CMD
, "ret %d", ret
);
225 static int lbs_cmd_802_11_enable_rsn(struct lbs_private
*priv
,
226 struct cmd_ds_command
*cmd
,
230 struct cmd_ds_802_11_enable_rsn
*penableRSN
= &cmd
->params
.enbrsn
;
231 u32
* enable
= pdata_buf
;
233 lbs_deb_enter(LBS_DEB_CMD
);
235 cmd
->command
= cpu_to_le16(CMD_802_11_ENABLE_RSN
);
236 cmd
->size
= cpu_to_le16(sizeof(*penableRSN
) + S_DS_GEN
);
237 penableRSN
->action
= cpu_to_le16(cmd_action
);
239 if (cmd_action
== CMD_ACT_SET
) {
241 penableRSN
->enable
= cpu_to_le16(CMD_ENABLE_RSN
);
243 penableRSN
->enable
= cpu_to_le16(CMD_DISABLE_RSN
);
244 lbs_deb_cmd("ENABLE_RSN: %d\n", *enable
);
247 lbs_deb_leave(LBS_DEB_CMD
);
252 static ssize_t
lbs_tlv_size(const u8
*tlv
, u16 size
)
255 struct mrvlietypesheader
*tlv_h
;
258 tlv_h
= (struct mrvlietypesheader
*) tlv
;
261 length
= le16_to_cpu(tlv_h
->len
) +
262 sizeof(struct mrvlietypesheader
);
270 static void lbs_cmd_802_11_subscribe_event(struct lbs_private
*priv
,
271 struct cmd_ds_command
*cmd
, u16 cmd_action
,
274 struct cmd_ds_802_11_subscribe_event
*events
=
275 (struct cmd_ds_802_11_subscribe_event
*) pdata_buf
;
277 /* pdata_buf points to a struct cmd_ds_802_11_subscribe_event and room
278 * for various Marvell TLVs */
280 lbs_deb_enter(LBS_DEB_CMD
);
282 cmd
->size
= cpu_to_le16(sizeof(*events
)
283 - sizeof(events
->tlv
)
285 cmd
->params
.subscribe_event
.action
= cpu_to_le16(cmd_action
);
286 if (cmd_action
== CMD_ACT_GET
) {
287 cmd
->params
.subscribe_event
.events
= 0;
289 ssize_t sz
= lbs_tlv_size(events
->tlv
, sizeof(events
->tlv
));
290 cmd
->size
= cpu_to_le16(le16_to_cpu(cmd
->size
) + sz
);
291 cmd
->params
.subscribe_event
.events
= events
->events
;
292 memcpy(cmd
->params
.subscribe_event
.tlv
, events
->tlv
, sz
);
295 lbs_deb_leave(LBS_DEB_CMD
);
298 static void set_one_wpa_key(struct MrvlIEtype_keyParamSet
* pkeyparamset
,
299 struct enc_key
* pkey
)
301 lbs_deb_enter(LBS_DEB_CMD
);
303 if (pkey
->flags
& KEY_INFO_WPA_ENABLED
) {
304 pkeyparamset
->keyinfo
|= cpu_to_le16(KEY_INFO_WPA_ENABLED
);
306 if (pkey
->flags
& KEY_INFO_WPA_UNICAST
) {
307 pkeyparamset
->keyinfo
|= cpu_to_le16(KEY_INFO_WPA_UNICAST
);
309 if (pkey
->flags
& KEY_INFO_WPA_MCAST
) {
310 pkeyparamset
->keyinfo
|= cpu_to_le16(KEY_INFO_WPA_MCAST
);
313 pkeyparamset
->type
= cpu_to_le16(TLV_TYPE_KEY_MATERIAL
);
314 pkeyparamset
->keytypeid
= cpu_to_le16(pkey
->type
);
315 pkeyparamset
->keylen
= cpu_to_le16(pkey
->len
);
316 memcpy(pkeyparamset
->key
, pkey
->key
, pkey
->len
);
317 pkeyparamset
->length
= cpu_to_le16( sizeof(pkeyparamset
->keytypeid
)
318 + sizeof(pkeyparamset
->keyinfo
)
319 + sizeof(pkeyparamset
->keylen
)
320 + sizeof(pkeyparamset
->key
));
321 lbs_deb_leave(LBS_DEB_CMD
);
324 static int lbs_cmd_802_11_key_material(struct lbs_private
*priv
,
325 struct cmd_ds_command
*cmd
,
327 u32 cmd_oid
, void *pdata_buf
)
329 struct cmd_ds_802_11_key_material
*pkeymaterial
=
330 &cmd
->params
.keymaterial
;
331 struct assoc_request
* assoc_req
= pdata_buf
;
335 lbs_deb_enter(LBS_DEB_CMD
);
337 cmd
->command
= cpu_to_le16(CMD_802_11_KEY_MATERIAL
);
338 pkeymaterial
->action
= cpu_to_le16(cmd_action
);
340 if (cmd_action
== CMD_ACT_GET
) {
341 cmd
->size
= cpu_to_le16(S_DS_GEN
+ sizeof (pkeymaterial
->action
));
346 memset(&pkeymaterial
->keyParamSet
, 0, sizeof(pkeymaterial
->keyParamSet
));
348 if (test_bit(ASSOC_FLAG_WPA_UCAST_KEY
, &assoc_req
->flags
)) {
349 set_one_wpa_key(&pkeymaterial
->keyParamSet
[index
],
350 &assoc_req
->wpa_unicast_key
);
354 if (test_bit(ASSOC_FLAG_WPA_MCAST_KEY
, &assoc_req
->flags
)) {
355 set_one_wpa_key(&pkeymaterial
->keyParamSet
[index
],
356 &assoc_req
->wpa_mcast_key
);
360 cmd
->size
= cpu_to_le16( S_DS_GEN
361 + sizeof (pkeymaterial
->action
)
362 + (index
* sizeof(struct MrvlIEtype_keyParamSet
)));
367 lbs_deb_leave_args(LBS_DEB_CMD
, "ret %d", ret
);
371 static int lbs_cmd_802_11_reset(struct lbs_private
*priv
,
372 struct cmd_ds_command
*cmd
, int cmd_action
)
374 struct cmd_ds_802_11_reset
*reset
= &cmd
->params
.reset
;
376 lbs_deb_enter(LBS_DEB_CMD
);
378 cmd
->command
= cpu_to_le16(CMD_802_11_RESET
);
379 cmd
->size
= cpu_to_le16(sizeof(struct cmd_ds_802_11_reset
) + S_DS_GEN
);
380 reset
->action
= cpu_to_le16(cmd_action
);
382 lbs_deb_leave(LBS_DEB_CMD
);
386 static int lbs_cmd_802_11_get_log(struct lbs_private
*priv
,
387 struct cmd_ds_command
*cmd
)
389 lbs_deb_enter(LBS_DEB_CMD
);
390 cmd
->command
= cpu_to_le16(CMD_802_11_GET_LOG
);
392 cpu_to_le16(sizeof(struct cmd_ds_802_11_get_log
) + S_DS_GEN
);
394 lbs_deb_leave(LBS_DEB_CMD
);
398 static int lbs_cmd_802_11_get_stat(struct lbs_private
*priv
,
399 struct cmd_ds_command
*cmd
)
401 lbs_deb_enter(LBS_DEB_CMD
);
402 cmd
->command
= cpu_to_le16(CMD_802_11_GET_STAT
);
404 cpu_to_le16(sizeof(struct cmd_ds_802_11_get_stat
) + S_DS_GEN
);
406 lbs_deb_leave(LBS_DEB_CMD
);
410 static int lbs_cmd_802_11_snmp_mib(struct lbs_private
*priv
,
411 struct cmd_ds_command
*cmd
,
413 int cmd_oid
, void *pdata_buf
)
415 struct cmd_ds_802_11_snmp_mib
*pSNMPMIB
= &cmd
->params
.smib
;
418 lbs_deb_enter(LBS_DEB_CMD
);
420 lbs_deb_cmd("SNMP_CMD: cmd_oid = 0x%x\n", cmd_oid
);
422 cmd
->command
= cpu_to_le16(CMD_802_11_SNMP_MIB
);
423 cmd
->size
= cpu_to_le16(sizeof(*pSNMPMIB
) + S_DS_GEN
);
426 case OID_802_11_INFRASTRUCTURE_MODE
:
428 u8 mode
= (u8
) (size_t) pdata_buf
;
429 pSNMPMIB
->querytype
= cpu_to_le16(CMD_ACT_SET
);
430 pSNMPMIB
->oid
= cpu_to_le16((u16
) DESIRED_BSSTYPE_I
);
431 pSNMPMIB
->bufsize
= cpu_to_le16(sizeof(u8
));
432 if (mode
== IW_MODE_ADHOC
) {
433 ucTemp
= SNMP_MIB_VALUE_ADHOC
;
435 /* Infra and Auto modes */
436 ucTemp
= SNMP_MIB_VALUE_INFRA
;
439 memmove(pSNMPMIB
->value
, &ucTemp
, sizeof(u8
));
444 case OID_802_11D_ENABLE
:
448 pSNMPMIB
->oid
= cpu_to_le16((u16
) DOT11D_I
);
450 if (cmd_action
== CMD_ACT_SET
) {
451 pSNMPMIB
->querytype
= cpu_to_le16(CMD_ACT_SET
);
452 pSNMPMIB
->bufsize
= cpu_to_le16(sizeof(u16
));
453 ulTemp
= *(u32
*)pdata_buf
;
454 *((__le16
*)(pSNMPMIB
->value
)) =
455 cpu_to_le16((u16
) ulTemp
);
460 case OID_802_11_FRAGMENTATION_THRESHOLD
:
464 pSNMPMIB
->oid
= cpu_to_le16((u16
) FRAGTHRESH_I
);
466 if (cmd_action
== CMD_ACT_GET
) {
467 pSNMPMIB
->querytype
= cpu_to_le16(CMD_ACT_GET
);
468 } else if (cmd_action
== CMD_ACT_SET
) {
469 pSNMPMIB
->querytype
= cpu_to_le16(CMD_ACT_SET
);
470 pSNMPMIB
->bufsize
= cpu_to_le16(sizeof(u16
));
471 ulTemp
= *((u32
*) pdata_buf
);
472 *((__le16
*)(pSNMPMIB
->value
)) =
473 cpu_to_le16((u16
) ulTemp
);
480 case OID_802_11_RTS_THRESHOLD
:
484 pSNMPMIB
->oid
= cpu_to_le16(RTSTHRESH_I
);
486 if (cmd_action
== CMD_ACT_GET
) {
487 pSNMPMIB
->querytype
= cpu_to_le16(CMD_ACT_GET
);
488 } else if (cmd_action
== CMD_ACT_SET
) {
489 pSNMPMIB
->querytype
= cpu_to_le16(CMD_ACT_SET
);
490 pSNMPMIB
->bufsize
= cpu_to_le16(sizeof(u16
));
491 ulTemp
= *((u32
*)pdata_buf
);
492 *(__le16
*)(pSNMPMIB
->value
) =
493 cpu_to_le16((u16
) ulTemp
);
498 case OID_802_11_TX_RETRYCOUNT
:
499 pSNMPMIB
->oid
= cpu_to_le16((u16
) SHORT_RETRYLIM_I
);
501 if (cmd_action
== CMD_ACT_GET
) {
502 pSNMPMIB
->querytype
= cpu_to_le16(CMD_ACT_GET
);
503 } else if (cmd_action
== CMD_ACT_SET
) {
504 pSNMPMIB
->querytype
= cpu_to_le16(CMD_ACT_SET
);
505 pSNMPMIB
->bufsize
= cpu_to_le16(sizeof(u16
));
506 *((__le16
*)(pSNMPMIB
->value
)) =
507 cpu_to_le16((u16
) priv
->txretrycount
);
516 "SNMP_CMD: command=0x%x, size=0x%x, seqnum=0x%x, result=0x%x\n",
517 le16_to_cpu(cmd
->command
), le16_to_cpu(cmd
->size
),
518 le16_to_cpu(cmd
->seqnum
), le16_to_cpu(cmd
->result
));
521 "SNMP_CMD: action 0x%x, oid 0x%x, oidsize 0x%x, value 0x%x\n",
522 le16_to_cpu(pSNMPMIB
->querytype
), le16_to_cpu(pSNMPMIB
->oid
),
523 le16_to_cpu(pSNMPMIB
->bufsize
),
524 le16_to_cpu(*(__le16
*) pSNMPMIB
->value
));
526 lbs_deb_leave(LBS_DEB_CMD
);
530 static int lbs_cmd_802_11_radio_control(struct lbs_private
*priv
,
531 struct cmd_ds_command
*cmd
,
534 struct cmd_ds_802_11_radio_control
*pradiocontrol
= &cmd
->params
.radio
;
536 lbs_deb_enter(LBS_DEB_CMD
);
539 cpu_to_le16((sizeof(struct cmd_ds_802_11_radio_control
)) +
541 cmd
->command
= cpu_to_le16(CMD_802_11_RADIO_CONTROL
);
543 pradiocontrol
->action
= cpu_to_le16(cmd_action
);
545 switch (priv
->preamble
) {
546 case CMD_TYPE_SHORT_PREAMBLE
:
547 pradiocontrol
->control
= cpu_to_le16(SET_SHORT_PREAMBLE
);
550 case CMD_TYPE_LONG_PREAMBLE
:
551 pradiocontrol
->control
= cpu_to_le16(SET_LONG_PREAMBLE
);
554 case CMD_TYPE_AUTO_PREAMBLE
:
556 pradiocontrol
->control
= cpu_to_le16(SET_AUTO_PREAMBLE
);
561 pradiocontrol
->control
|= cpu_to_le16(TURN_ON_RF
);
563 pradiocontrol
->control
&= cpu_to_le16(~TURN_ON_RF
);
565 lbs_deb_leave(LBS_DEB_CMD
);
569 static int lbs_cmd_802_11_rf_tx_power(struct lbs_private
*priv
,
570 struct cmd_ds_command
*cmd
,
571 u16 cmd_action
, void *pdata_buf
)
574 struct cmd_ds_802_11_rf_tx_power
*prtp
= &cmd
->params
.txp
;
576 lbs_deb_enter(LBS_DEB_CMD
);
579 cpu_to_le16((sizeof(struct cmd_ds_802_11_rf_tx_power
)) + S_DS_GEN
);
580 cmd
->command
= cpu_to_le16(CMD_802_11_RF_TX_POWER
);
581 prtp
->action
= cpu_to_le16(cmd_action
);
583 lbs_deb_cmd("RF_TX_POWER_CMD: size:%d cmd:0x%x Act:%d\n",
584 le16_to_cpu(cmd
->size
), le16_to_cpu(cmd
->command
),
585 le16_to_cpu(prtp
->action
));
587 switch (cmd_action
) {
588 case CMD_ACT_TX_POWER_OPT_GET
:
589 prtp
->action
= cpu_to_le16(CMD_ACT_GET
);
590 prtp
->currentlevel
= 0;
593 case CMD_ACT_TX_POWER_OPT_SET_HIGH
:
594 prtp
->action
= cpu_to_le16(CMD_ACT_SET
);
595 prtp
->currentlevel
= cpu_to_le16(CMD_ACT_TX_POWER_INDEX_HIGH
);
598 case CMD_ACT_TX_POWER_OPT_SET_MID
:
599 prtp
->action
= cpu_to_le16(CMD_ACT_SET
);
600 prtp
->currentlevel
= cpu_to_le16(CMD_ACT_TX_POWER_INDEX_MID
);
603 case CMD_ACT_TX_POWER_OPT_SET_LOW
:
604 prtp
->action
= cpu_to_le16(CMD_ACT_SET
);
605 prtp
->currentlevel
= cpu_to_le16(*((u16
*) pdata_buf
));
609 lbs_deb_leave(LBS_DEB_CMD
);
613 static int lbs_cmd_802_11_monitor_mode(struct lbs_private
*priv
,
614 struct cmd_ds_command
*cmd
,
615 u16 cmd_action
, void *pdata_buf
)
617 struct cmd_ds_802_11_monitor_mode
*monitor
= &cmd
->params
.monitor
;
619 cmd
->command
= cpu_to_le16(CMD_802_11_MONITOR_MODE
);
621 cpu_to_le16(sizeof(struct cmd_ds_802_11_monitor_mode
) +
624 monitor
->action
= cpu_to_le16(cmd_action
);
625 if (cmd_action
== CMD_ACT_SET
) {
627 cpu_to_le16((u16
) (*(u32
*) pdata_buf
));
633 static int lbs_cmd_802_11_rate_adapt_rateset(struct lbs_private
*priv
,
634 struct cmd_ds_command
*cmd
,
637 struct cmd_ds_802_11_rate_adapt_rateset
638 *rateadapt
= &cmd
->params
.rateset
;
640 lbs_deb_enter(LBS_DEB_CMD
);
642 cpu_to_le16(sizeof(struct cmd_ds_802_11_rate_adapt_rateset
)
644 cmd
->command
= cpu_to_le16(CMD_802_11_RATE_ADAPT_RATESET
);
646 rateadapt
->action
= cpu_to_le16(cmd_action
);
647 rateadapt
->enablehwauto
= cpu_to_le16(priv
->enablehwauto
);
648 rateadapt
->bitmap
= cpu_to_le16(priv
->ratebitmap
);
650 lbs_deb_leave(LBS_DEB_CMD
);
654 static int lbs_cmd_802_11_data_rate(struct lbs_private
*priv
,
655 struct cmd_ds_command
*cmd
,
658 struct cmd_ds_802_11_data_rate
*pdatarate
= &cmd
->params
.drate
;
660 lbs_deb_enter(LBS_DEB_CMD
);
662 cmd
->size
= cpu_to_le16(sizeof(struct cmd_ds_802_11_data_rate
) +
664 cmd
->command
= cpu_to_le16(CMD_802_11_DATA_RATE
);
665 memset(pdatarate
, 0, sizeof(struct cmd_ds_802_11_data_rate
));
666 pdatarate
->action
= cpu_to_le16(cmd_action
);
668 if (cmd_action
== CMD_ACT_SET_TX_FIX_RATE
) {
669 pdatarate
->rates
[0] = lbs_data_rate_to_fw_index(priv
->cur_rate
);
670 lbs_deb_cmd("DATA_RATE: set fixed 0x%02X\n",
672 } else if (cmd_action
== CMD_ACT_SET_TX_AUTO
) {
673 lbs_deb_cmd("DATA_RATE: setting auto\n");
676 lbs_deb_leave(LBS_DEB_CMD
);
680 static int lbs_cmd_mac_multicast_adr(struct lbs_private
*priv
,
681 struct cmd_ds_command
*cmd
,
684 struct cmd_ds_mac_multicast_adr
*pMCastAdr
= &cmd
->params
.madr
;
686 lbs_deb_enter(LBS_DEB_CMD
);
687 cmd
->size
= cpu_to_le16(sizeof(struct cmd_ds_mac_multicast_adr
) +
689 cmd
->command
= cpu_to_le16(CMD_MAC_MULTICAST_ADR
);
691 lbs_deb_cmd("MULTICAST_ADR: setting %d addresses\n", pMCastAdr
->nr_of_adrs
);
692 pMCastAdr
->action
= cpu_to_le16(cmd_action
);
693 pMCastAdr
->nr_of_adrs
=
694 cpu_to_le16((u16
) priv
->nr_of_multicastmacaddr
);
695 memcpy(pMCastAdr
->maclist
, priv
->multicastlist
,
696 priv
->nr_of_multicastmacaddr
* ETH_ALEN
);
698 lbs_deb_leave(LBS_DEB_CMD
);
702 static int lbs_cmd_802_11_rf_channel(struct lbs_private
*priv
,
703 struct cmd_ds_command
*cmd
,
704 int option
, void *pdata_buf
)
706 struct cmd_ds_802_11_rf_channel
*rfchan
= &cmd
->params
.rfchannel
;
708 lbs_deb_enter(LBS_DEB_CMD
);
709 cmd
->command
= cpu_to_le16(CMD_802_11_RF_CHANNEL
);
710 cmd
->size
= cpu_to_le16(sizeof(struct cmd_ds_802_11_rf_channel
) +
713 if (option
== CMD_OPT_802_11_RF_CHANNEL_SET
) {
714 rfchan
->currentchannel
= cpu_to_le16(*((u16
*) pdata_buf
));
717 rfchan
->action
= cpu_to_le16(option
);
719 lbs_deb_leave(LBS_DEB_CMD
);
723 static int lbs_cmd_802_11_rssi(struct lbs_private
*priv
,
724 struct cmd_ds_command
*cmd
)
727 lbs_deb_enter(LBS_DEB_CMD
);
728 cmd
->command
= cpu_to_le16(CMD_802_11_RSSI
);
729 cmd
->size
= cpu_to_le16(sizeof(struct cmd_ds_802_11_rssi
) + S_DS_GEN
);
730 cmd
->params
.rssi
.N
= cpu_to_le16(DEFAULT_BCN_AVG_FACTOR
);
732 /* reset Beacon SNR/NF/RSSI values */
733 priv
->SNR
[TYPE_BEACON
][TYPE_NOAVG
] = 0;
734 priv
->SNR
[TYPE_BEACON
][TYPE_AVG
] = 0;
735 priv
->NF
[TYPE_BEACON
][TYPE_NOAVG
] = 0;
736 priv
->NF
[TYPE_BEACON
][TYPE_AVG
] = 0;
737 priv
->RSSI
[TYPE_BEACON
][TYPE_NOAVG
] = 0;
738 priv
->RSSI
[TYPE_BEACON
][TYPE_AVG
] = 0;
740 lbs_deb_leave(LBS_DEB_CMD
);
744 static int lbs_cmd_reg_access(struct lbs_private
*priv
,
745 struct cmd_ds_command
*cmdptr
,
746 u8 cmd_action
, void *pdata_buf
)
748 struct lbs_offset_value
*offval
;
750 lbs_deb_enter(LBS_DEB_CMD
);
752 offval
= (struct lbs_offset_value
*)pdata_buf
;
754 switch (le16_to_cpu(cmdptr
->command
)) {
755 case CMD_MAC_REG_ACCESS
:
757 struct cmd_ds_mac_reg_access
*macreg
;
760 cpu_to_le16(sizeof (struct cmd_ds_mac_reg_access
)
763 (struct cmd_ds_mac_reg_access
*)&cmdptr
->params
.
766 macreg
->action
= cpu_to_le16(cmd_action
);
767 macreg
->offset
= cpu_to_le16((u16
) offval
->offset
);
768 macreg
->value
= cpu_to_le32(offval
->value
);
773 case CMD_BBP_REG_ACCESS
:
775 struct cmd_ds_bbp_reg_access
*bbpreg
;
779 (struct cmd_ds_bbp_reg_access
)
782 (struct cmd_ds_bbp_reg_access
*)&cmdptr
->params
.
785 bbpreg
->action
= cpu_to_le16(cmd_action
);
786 bbpreg
->offset
= cpu_to_le16((u16
) offval
->offset
);
787 bbpreg
->value
= (u8
) offval
->value
;
792 case CMD_RF_REG_ACCESS
:
794 struct cmd_ds_rf_reg_access
*rfreg
;
798 (struct cmd_ds_rf_reg_access
) +
801 (struct cmd_ds_rf_reg_access
*)&cmdptr
->params
.
804 rfreg
->action
= cpu_to_le16(cmd_action
);
805 rfreg
->offset
= cpu_to_le16((u16
) offval
->offset
);
806 rfreg
->value
= (u8
) offval
->value
;
815 lbs_deb_leave(LBS_DEB_CMD
);
819 static int lbs_cmd_802_11_mac_address(struct lbs_private
*priv
,
820 struct cmd_ds_command
*cmd
,
824 lbs_deb_enter(LBS_DEB_CMD
);
825 cmd
->command
= cpu_to_le16(CMD_802_11_MAC_ADDRESS
);
826 cmd
->size
= cpu_to_le16(sizeof(struct cmd_ds_802_11_mac_address
) +
830 cmd
->params
.macadd
.action
= cpu_to_le16(cmd_action
);
832 if (cmd_action
== CMD_ACT_SET
) {
833 memcpy(cmd
->params
.macadd
.macadd
,
834 priv
->current_addr
, ETH_ALEN
);
835 lbs_deb_hex(LBS_DEB_CMD
, "SET_CMD: MAC addr", priv
->current_addr
, 6);
838 lbs_deb_leave(LBS_DEB_CMD
);
842 static int lbs_cmd_802_11_eeprom_access(struct lbs_private
*priv
,
843 struct cmd_ds_command
*cmd
,
844 int cmd_action
, void *pdata_buf
)
846 struct lbs_ioctl_regrdwr
*ea
= pdata_buf
;
848 lbs_deb_enter(LBS_DEB_CMD
);
850 cmd
->command
= cpu_to_le16(CMD_802_11_EEPROM_ACCESS
);
851 cmd
->size
= cpu_to_le16(sizeof(struct cmd_ds_802_11_eeprom_access
) +
855 cmd
->params
.rdeeprom
.action
= cpu_to_le16(ea
->action
);
856 cmd
->params
.rdeeprom
.offset
= cpu_to_le16(ea
->offset
);
857 cmd
->params
.rdeeprom
.bytecount
= cpu_to_le16(ea
->NOB
);
858 cmd
->params
.rdeeprom
.value
= 0;
860 lbs_deb_leave(LBS_DEB_CMD
);
864 static int lbs_cmd_bt_access(struct lbs_private
*priv
,
865 struct cmd_ds_command
*cmd
,
866 u16 cmd_action
, void *pdata_buf
)
868 struct cmd_ds_bt_access
*bt_access
= &cmd
->params
.bt
;
869 lbs_deb_enter_args(LBS_DEB_CMD
, "action %d", cmd_action
);
871 cmd
->command
= cpu_to_le16(CMD_BT_ACCESS
);
872 cmd
->size
= cpu_to_le16(sizeof(struct cmd_ds_bt_access
) + S_DS_GEN
);
874 bt_access
->action
= cpu_to_le16(cmd_action
);
876 switch (cmd_action
) {
877 case CMD_ACT_BT_ACCESS_ADD
:
878 memcpy(bt_access
->addr1
, pdata_buf
, 2 * ETH_ALEN
);
879 lbs_deb_hex(LBS_DEB_MESH
, "BT_ADD: blinded MAC addr", bt_access
->addr1
, 6);
881 case CMD_ACT_BT_ACCESS_DEL
:
882 memcpy(bt_access
->addr1
, pdata_buf
, 1 * ETH_ALEN
);
883 lbs_deb_hex(LBS_DEB_MESH
, "BT_DEL: blinded MAC addr", bt_access
->addr1
, 6);
885 case CMD_ACT_BT_ACCESS_LIST
:
886 bt_access
->id
= cpu_to_le32(*(u32
*) pdata_buf
);
888 case CMD_ACT_BT_ACCESS_RESET
:
890 case CMD_ACT_BT_ACCESS_SET_INVERT
:
891 bt_access
->id
= cpu_to_le32(*(u32
*) pdata_buf
);
893 case CMD_ACT_BT_ACCESS_GET_INVERT
:
898 lbs_deb_leave(LBS_DEB_CMD
);
902 static int lbs_cmd_fwt_access(struct lbs_private
*priv
,
903 struct cmd_ds_command
*cmd
,
904 u16 cmd_action
, void *pdata_buf
)
906 struct cmd_ds_fwt_access
*fwt_access
= &cmd
->params
.fwt
;
907 lbs_deb_enter_args(LBS_DEB_CMD
, "action %d", cmd_action
);
909 cmd
->command
= cpu_to_le16(CMD_FWT_ACCESS
);
910 cmd
->size
= cpu_to_le16(sizeof(struct cmd_ds_fwt_access
) + S_DS_GEN
);
914 memcpy(fwt_access
, pdata_buf
, sizeof(*fwt_access
));
916 memset(fwt_access
, 0, sizeof(*fwt_access
));
918 fwt_access
->action
= cpu_to_le16(cmd_action
);
920 lbs_deb_leave(LBS_DEB_CMD
);
924 static int lbs_cmd_mesh_access(struct lbs_private
*priv
,
925 struct cmd_ds_command
*cmd
,
926 u16 cmd_action
, void *pdata_buf
)
928 struct cmd_ds_mesh_access
*mesh_access
= &cmd
->params
.mesh
;
929 lbs_deb_enter_args(LBS_DEB_CMD
, "action %d", cmd_action
);
931 cmd
->command
= cpu_to_le16(CMD_MESH_ACCESS
);
932 cmd
->size
= cpu_to_le16(sizeof(struct cmd_ds_mesh_access
) + S_DS_GEN
);
936 memcpy(mesh_access
, pdata_buf
, sizeof(*mesh_access
));
938 memset(mesh_access
, 0, sizeof(*mesh_access
));
940 mesh_access
->action
= cpu_to_le16(cmd_action
);
942 lbs_deb_leave(LBS_DEB_CMD
);
946 static int lbs_cmd_bcn_ctrl(struct lbs_private
* priv
,
947 struct cmd_ds_command
*cmd
,
950 struct cmd_ds_802_11_beacon_control
951 *bcn_ctrl
= &cmd
->params
.bcn_ctrl
;
953 lbs_deb_enter(LBS_DEB_CMD
);
955 cpu_to_le16(sizeof(struct cmd_ds_802_11_beacon_control
)
957 cmd
->command
= cpu_to_le16(CMD_802_11_BEACON_CTRL
);
959 bcn_ctrl
->action
= cpu_to_le16(cmd_action
);
960 bcn_ctrl
->beacon_enable
= cpu_to_le16(priv
->beacon_enable
);
961 bcn_ctrl
->beacon_period
= cpu_to_le16(priv
->beacon_period
);
963 lbs_deb_leave(LBS_DEB_CMD
);
968 * Note: NEVER use lbs_queue_cmd() with addtail==0 other than for
969 * the command timer, because it does not account for queued commands.
971 void lbs_queue_cmd(struct lbs_private
*priv
,
972 struct cmd_ctrl_node
*cmdnode
,
976 struct cmd_ds_command
*cmdptr
;
978 lbs_deb_enter(LBS_DEB_HOST
);
981 lbs_deb_host("QUEUE_CMD: cmdnode is NULL\n");
985 cmdptr
= (struct cmd_ds_command
*)cmdnode
->bufvirtualaddr
;
987 lbs_deb_host("QUEUE_CMD: cmdptr is NULL\n");
991 /* Exit_PS command needs to be queued in the header always. */
992 if (le16_to_cpu(cmdptr
->command
) == CMD_802_11_PS_MODE
) {
993 struct cmd_ds_802_11_ps_mode
*psm
= &cmdptr
->params
.psmode
;
994 if (psm
->action
== cpu_to_le16(CMD_SUBCMD_EXIT_PS
)) {
995 if (priv
->psstate
!= PS_STATE_FULL_POWER
)
1000 spin_lock_irqsave(&priv
->driver_lock
, flags
);
1003 list_add_tail(&cmdnode
->list
, &priv
->cmdpendingq
);
1005 list_add(&cmdnode
->list
, &priv
->cmdpendingq
);
1007 spin_unlock_irqrestore(&priv
->driver_lock
, flags
);
1009 lbs_deb_host("QUEUE_CMD: inserted command 0x%04x into cmdpendingq\n",
1010 le16_to_cpu(((struct cmd_ds_gen
*)cmdnode
->bufvirtualaddr
)->command
));
1013 lbs_deb_leave(LBS_DEB_HOST
);
1017 * TODO: Fix the issue when DownloadcommandToStation is being called the
1018 * second time when the command times out. All the cmdptr->xxx are in little
1019 * endian and therefore all the comparissions will fail.
1020 * For now - we are not performing the endian conversion the second time - but
1021 * for PS and DEEP_SLEEP we need to worry
1023 static int DownloadcommandToStation(struct lbs_private
*priv
,
1024 struct cmd_ctrl_node
*cmdnode
)
1026 unsigned long flags
;
1027 struct cmd_ds_command
*cmdptr
;
1032 lbs_deb_enter(LBS_DEB_HOST
);
1034 if (!priv
|| !cmdnode
) {
1035 lbs_deb_host("DNLD_CMD: priv or cmdmode is NULL\n");
1039 cmdptr
= (struct cmd_ds_command
*)cmdnode
->bufvirtualaddr
;
1041 spin_lock_irqsave(&priv
->driver_lock
, flags
);
1042 if (!cmdptr
|| !cmdptr
->size
) {
1043 lbs_deb_host("DNLD_CMD: cmdptr is NULL or zero\n");
1044 __lbs_cleanup_and_insert_cmd(priv
, cmdnode
);
1045 spin_unlock_irqrestore(&priv
->driver_lock
, flags
);
1049 priv
->cur_cmd
= cmdnode
;
1050 priv
->cur_cmd_retcode
= 0;
1051 spin_unlock_irqrestore(&priv
->driver_lock
, flags
);
1053 cmdsize
= le16_to_cpu(cmdptr
->size
);
1054 command
= le16_to_cpu(cmdptr
->command
);
1056 lbs_deb_host("DNLD_CMD: command 0x%04x, size %d, jiffies %lu\n",
1057 command
, cmdsize
, jiffies
);
1058 lbs_deb_hex(LBS_DEB_HOST
, "DNLD_CMD", cmdnode
->bufvirtualaddr
, cmdsize
);
1060 cmdnode
->cmdwaitqwoken
= 0;
1062 ret
= priv
->hw_host_to_card(priv
, MVMS_CMD
, (u8
*) cmdptr
, cmdsize
);
1065 lbs_deb_host("DNLD_CMD: hw_host_to_card failed\n");
1066 spin_lock_irqsave(&priv
->driver_lock
, flags
);
1067 priv
->cur_cmd_retcode
= ret
;
1068 __lbs_cleanup_and_insert_cmd(priv
, priv
->cur_cmd
);
1069 priv
->cur_cmd
= NULL
;
1070 spin_unlock_irqrestore(&priv
->driver_lock
, flags
);
1074 lbs_deb_cmd("DNLD_CMD: sent command 0x%04x, jiffies %lu\n", command
, jiffies
);
1076 /* Setup the timer after transmit command */
1077 if (command
== CMD_802_11_SCAN
|| command
== CMD_802_11_AUTHENTICATE
1078 || command
== CMD_802_11_ASSOCIATE
)
1079 mod_timer(&priv
->command_timer
, jiffies
+ (10*HZ
));
1081 mod_timer(&priv
->command_timer
, jiffies
+ (5*HZ
));
1086 lbs_deb_leave_args(LBS_DEB_HOST
, "ret %d", ret
);
1090 static int lbs_cmd_mac_control(struct lbs_private
*priv
,
1091 struct cmd_ds_command
*cmd
)
1093 struct cmd_ds_mac_control
*mac
= &cmd
->params
.macctrl
;
1095 lbs_deb_enter(LBS_DEB_CMD
);
1097 cmd
->command
= cpu_to_le16(CMD_MAC_CONTROL
);
1098 cmd
->size
= cpu_to_le16(sizeof(struct cmd_ds_mac_control
) + S_DS_GEN
);
1099 mac
->action
= cpu_to_le16(priv
->currentpacketfilter
);
1101 lbs_deb_cmd("MAC_CONTROL: action 0x%x, size %d\n",
1102 le16_to_cpu(mac
->action
), le16_to_cpu(cmd
->size
));
1104 lbs_deb_leave(LBS_DEB_CMD
);
1109 * This function inserts command node to cmdfreeq
1110 * after cleans it. Requires priv->driver_lock held.
1112 void __lbs_cleanup_and_insert_cmd(struct lbs_private
*priv
,
1113 struct cmd_ctrl_node
*ptempcmd
)
1119 cleanup_cmdnode(ptempcmd
);
1120 list_add_tail(&ptempcmd
->list
, &priv
->cmdfreeq
);
1123 static void lbs_cleanup_and_insert_cmd(struct lbs_private
*priv
,
1124 struct cmd_ctrl_node
*ptempcmd
)
1126 unsigned long flags
;
1128 spin_lock_irqsave(&priv
->driver_lock
, flags
);
1129 __lbs_cleanup_and_insert_cmd(priv
, ptempcmd
);
1130 spin_unlock_irqrestore(&priv
->driver_lock
, flags
);
1133 int lbs_set_radio_control(struct lbs_private
*priv
)
1137 lbs_deb_enter(LBS_DEB_CMD
);
1139 ret
= lbs_prepare_and_send_command(priv
,
1140 CMD_802_11_RADIO_CONTROL
,
1142 CMD_OPTION_WAITFORRSP
, 0, NULL
);
1144 lbs_deb_cmd("RADIO_SET: radio %d, preamble %d\n",
1145 priv
->radioon
, priv
->preamble
);
1147 lbs_deb_leave_args(LBS_DEB_CMD
, "ret %d", ret
);
1151 int lbs_set_mac_packet_filter(struct lbs_private
*priv
)
1155 lbs_deb_enter(LBS_DEB_CMD
);
1157 /* Send MAC control command to station */
1158 ret
= lbs_prepare_and_send_command(priv
,
1159 CMD_MAC_CONTROL
, 0, 0, 0, NULL
);
1161 lbs_deb_leave_args(LBS_DEB_CMD
, "ret %d", ret
);
1166 * @brief This function prepare the command before send to firmware.
1168 * @param priv A pointer to struct lbs_private structure
1169 * @param cmd_no command number
1170 * @param cmd_action command action: GET or SET
1171 * @param wait_option wait option: wait response or not
1172 * @param cmd_oid cmd oid: treated as sub command
1173 * @param pdata_buf A pointer to informaion buffer
1176 int lbs_prepare_and_send_command(struct lbs_private
*priv
,
1179 u16 wait_option
, u32 cmd_oid
, void *pdata_buf
)
1182 struct cmd_ctrl_node
*cmdnode
;
1183 struct cmd_ds_command
*cmdptr
;
1184 unsigned long flags
;
1186 lbs_deb_enter(LBS_DEB_HOST
);
1189 lbs_deb_host("PREP_CMD: priv is NULL\n");
1194 if (priv
->surpriseremoved
) {
1195 lbs_deb_host("PREP_CMD: card removed\n");
1200 cmdnode
= lbs_get_cmd_ctrl_node(priv
);
1202 if (cmdnode
== NULL
) {
1203 lbs_deb_host("PREP_CMD: cmdnode is NULL\n");
1205 /* Wake up main thread to execute next command */
1206 wake_up_interruptible(&priv
->waitq
);
1211 lbs_set_cmd_ctrl_node(priv
, cmdnode
, wait_option
, pdata_buf
);
1213 cmdptr
= (struct cmd_ds_command
*)cmdnode
->bufvirtualaddr
;
1215 lbs_deb_host("PREP_CMD: command 0x%04x\n", cmd_no
);
1218 lbs_deb_host("PREP_CMD: cmdptr is NULL\n");
1219 lbs_cleanup_and_insert_cmd(priv
, cmdnode
);
1224 /* Set sequence number, command and INT option */
1226 cmdptr
->seqnum
= cpu_to_le16(priv
->seqnum
);
1228 cmdptr
->command
= cpu_to_le16(cmd_no
);
1232 case CMD_GET_HW_SPEC
:
1233 ret
= lbs_cmd_hw_spec(priv
, cmdptr
);
1235 case CMD_802_11_PS_MODE
:
1236 ret
= lbs_cmd_802_11_ps_mode(priv
, cmdptr
, cmd_action
);
1239 case CMD_802_11_SCAN
:
1240 ret
= lbs_cmd_80211_scan(priv
, cmdptr
, pdata_buf
);
1243 case CMD_MAC_CONTROL
:
1244 ret
= lbs_cmd_mac_control(priv
, cmdptr
);
1247 case CMD_802_11_ASSOCIATE
:
1248 case CMD_802_11_REASSOCIATE
:
1249 ret
= lbs_cmd_80211_associate(priv
, cmdptr
, pdata_buf
);
1252 case CMD_802_11_DEAUTHENTICATE
:
1253 ret
= lbs_cmd_80211_deauthenticate(priv
, cmdptr
);
1256 case CMD_802_11_SET_WEP
:
1257 ret
= lbs_cmd_802_11_set_wep(priv
, cmdptr
, cmd_action
, pdata_buf
);
1260 case CMD_802_11_AD_HOC_START
:
1261 ret
= lbs_cmd_80211_ad_hoc_start(priv
, cmdptr
, pdata_buf
);
1266 case CMD_802_11_RESET
:
1267 ret
= lbs_cmd_802_11_reset(priv
, cmdptr
, cmd_action
);
1270 case CMD_802_11_GET_LOG
:
1271 ret
= lbs_cmd_802_11_get_log(priv
, cmdptr
);
1274 case CMD_802_11_AUTHENTICATE
:
1275 ret
= lbs_cmd_80211_authenticate(priv
, cmdptr
, pdata_buf
);
1278 case CMD_802_11_GET_STAT
:
1279 ret
= lbs_cmd_802_11_get_stat(priv
, cmdptr
);
1282 case CMD_802_11_SNMP_MIB
:
1283 ret
= lbs_cmd_802_11_snmp_mib(priv
, cmdptr
,
1284 cmd_action
, cmd_oid
, pdata_buf
);
1287 case CMD_MAC_REG_ACCESS
:
1288 case CMD_BBP_REG_ACCESS
:
1289 case CMD_RF_REG_ACCESS
:
1290 ret
= lbs_cmd_reg_access(priv
, cmdptr
, cmd_action
, pdata_buf
);
1293 case CMD_802_11_RF_CHANNEL
:
1294 ret
= lbs_cmd_802_11_rf_channel(priv
, cmdptr
,
1295 cmd_action
, pdata_buf
);
1298 case CMD_802_11_RF_TX_POWER
:
1299 ret
= lbs_cmd_802_11_rf_tx_power(priv
, cmdptr
,
1300 cmd_action
, pdata_buf
);
1303 case CMD_802_11_RADIO_CONTROL
:
1304 ret
= lbs_cmd_802_11_radio_control(priv
, cmdptr
, cmd_action
);
1307 case CMD_802_11_DATA_RATE
:
1308 ret
= lbs_cmd_802_11_data_rate(priv
, cmdptr
, cmd_action
);
1310 case CMD_802_11_RATE_ADAPT_RATESET
:
1311 ret
= lbs_cmd_802_11_rate_adapt_rateset(priv
,
1312 cmdptr
, cmd_action
);
1315 case CMD_MAC_MULTICAST_ADR
:
1316 ret
= lbs_cmd_mac_multicast_adr(priv
, cmdptr
, cmd_action
);
1319 case CMD_802_11_MONITOR_MODE
:
1320 ret
= lbs_cmd_802_11_monitor_mode(priv
, cmdptr
,
1321 cmd_action
, pdata_buf
);
1324 case CMD_802_11_AD_HOC_JOIN
:
1325 ret
= lbs_cmd_80211_ad_hoc_join(priv
, cmdptr
, pdata_buf
);
1328 case CMD_802_11_RSSI
:
1329 ret
= lbs_cmd_802_11_rssi(priv
, cmdptr
);
1332 case CMD_802_11_AD_HOC_STOP
:
1333 ret
= lbs_cmd_80211_ad_hoc_stop(priv
, cmdptr
);
1336 case CMD_802_11_ENABLE_RSN
:
1337 ret
= lbs_cmd_802_11_enable_rsn(priv
, cmdptr
, cmd_action
,
1341 case CMD_802_11_KEY_MATERIAL
:
1342 ret
= lbs_cmd_802_11_key_material(priv
, cmdptr
, cmd_action
,
1343 cmd_oid
, pdata_buf
);
1346 case CMD_802_11_PAIRWISE_TSC
:
1348 case CMD_802_11_GROUP_TSC
:
1351 case CMD_802_11_MAC_ADDRESS
:
1352 ret
= lbs_cmd_802_11_mac_address(priv
, cmdptr
, cmd_action
);
1355 case CMD_802_11_EEPROM_ACCESS
:
1356 ret
= lbs_cmd_802_11_eeprom_access(priv
, cmdptr
,
1357 cmd_action
, pdata_buf
);
1360 case CMD_802_11_SET_AFC
:
1361 case CMD_802_11_GET_AFC
:
1363 cmdptr
->command
= cpu_to_le16(cmd_no
);
1364 cmdptr
->size
= cpu_to_le16(sizeof(struct cmd_ds_802_11_afc
) +
1367 memmove(&cmdptr
->params
.afc
,
1368 pdata_buf
, sizeof(struct cmd_ds_802_11_afc
));
1373 case CMD_802_11D_DOMAIN_INFO
:
1374 ret
= lbs_cmd_802_11d_domain_info(priv
, cmdptr
,
1375 cmd_no
, cmd_action
);
1378 case CMD_802_11_SLEEP_PARAMS
:
1379 ret
= lbs_cmd_802_11_sleep_params(priv
, cmdptr
, cmd_action
);
1381 case CMD_802_11_INACTIVITY_TIMEOUT
:
1382 ret
= lbs_cmd_802_11_inactivity_timeout(priv
, cmdptr
,
1383 cmd_action
, pdata_buf
);
1384 lbs_set_cmd_ctrl_node(priv
, cmdnode
, 0, pdata_buf
);
1387 case CMD_802_11_TPC_CFG
:
1388 cmdptr
->command
= cpu_to_le16(CMD_802_11_TPC_CFG
);
1390 cpu_to_le16(sizeof(struct cmd_ds_802_11_tpc_cfg
) +
1393 memmove(&cmdptr
->params
.tpccfg
,
1394 pdata_buf
, sizeof(struct cmd_ds_802_11_tpc_cfg
));
1398 case CMD_802_11_LED_GPIO_CTRL
:
1400 struct mrvlietypes_ledgpio
*gpio
=
1401 (struct mrvlietypes_ledgpio
*)
1402 cmdptr
->params
.ledgpio
.data
;
1404 memmove(&cmdptr
->params
.ledgpio
,
1406 sizeof(struct cmd_ds_802_11_led_ctrl
));
1409 cpu_to_le16(CMD_802_11_LED_GPIO_CTRL
);
1411 #define ACTION_NUMLED_TLVTYPE_LEN_FIELDS_LEN 8
1413 cpu_to_le16(le16_to_cpu(gpio
->header
.len
)
1415 + ACTION_NUMLED_TLVTYPE_LEN_FIELDS_LEN
);
1416 gpio
->header
.len
= gpio
->header
.len
;
1421 case CMD_802_11_SUBSCRIBE_EVENT
:
1422 lbs_cmd_802_11_subscribe_event(priv
, cmdptr
,
1423 cmd_action
, pdata_buf
);
1425 case CMD_802_11_PWR_CFG
:
1426 cmdptr
->command
= cpu_to_le16(CMD_802_11_PWR_CFG
);
1428 cpu_to_le16(sizeof(struct cmd_ds_802_11_pwr_cfg
) +
1430 memmove(&cmdptr
->params
.pwrcfg
, pdata_buf
,
1431 sizeof(struct cmd_ds_802_11_pwr_cfg
));
1436 ret
= lbs_cmd_bt_access(priv
, cmdptr
, cmd_action
, pdata_buf
);
1439 case CMD_FWT_ACCESS
:
1440 ret
= lbs_cmd_fwt_access(priv
, cmdptr
, cmd_action
, pdata_buf
);
1443 case CMD_MESH_ACCESS
:
1444 ret
= lbs_cmd_mesh_access(priv
, cmdptr
, cmd_action
, pdata_buf
);
1448 cmdptr
->command
= cpu_to_le16(CMD_GET_TSF
);
1449 cmdptr
->size
= cpu_to_le16(sizeof(struct cmd_ds_get_tsf
) +
1453 case CMD_802_11_BEACON_CTRL
:
1454 ret
= lbs_cmd_bcn_ctrl(priv
, cmdptr
, cmd_action
);
1457 lbs_deb_host("PREP_CMD: unknown command 0x%04x\n", cmd_no
);
1462 /* return error, since the command preparation failed */
1464 lbs_deb_host("PREP_CMD: command preparation failed\n");
1465 lbs_cleanup_and_insert_cmd(priv
, cmdnode
);
1470 cmdnode
->cmdwaitqwoken
= 0;
1472 lbs_queue_cmd(priv
, cmdnode
, 1);
1473 wake_up_interruptible(&priv
->waitq
);
1475 if (wait_option
& CMD_OPTION_WAITFORRSP
) {
1476 lbs_deb_host("PREP_CMD: wait for response\n");
1478 wait_event_interruptible(cmdnode
->cmdwait_q
,
1479 cmdnode
->cmdwaitqwoken
);
1482 spin_lock_irqsave(&priv
->driver_lock
, flags
);
1483 if (priv
->cur_cmd_retcode
) {
1484 lbs_deb_host("PREP_CMD: command failed with return code %d\n",
1485 priv
->cur_cmd_retcode
);
1486 priv
->cur_cmd_retcode
= 0;
1489 spin_unlock_irqrestore(&priv
->driver_lock
, flags
);
1492 lbs_deb_leave_args(LBS_DEB_HOST
, "ret %d", ret
);
1495 EXPORT_SYMBOL_GPL(lbs_prepare_and_send_command
);
1498 * @brief This function allocates the command buffer and link
1499 * it to command free queue.
1501 * @param priv A pointer to struct lbs_private structure
1504 int lbs_allocate_cmd_buffer(struct lbs_private
*priv
)
1509 struct cmd_ctrl_node
*tempcmd_array
;
1510 u8
*ptempvirtualaddr
;
1512 lbs_deb_enter(LBS_DEB_HOST
);
1514 /* Allocate and initialize cmdCtrlNode */
1515 ulbufsize
= sizeof(struct cmd_ctrl_node
) * MRVDRV_NUM_OF_CMD_BUFFER
;
1517 if (!(tempcmd_array
= kzalloc(ulbufsize
, GFP_KERNEL
))) {
1518 lbs_deb_host("ALLOC_CMD_BUF: tempcmd_array is NULL\n");
1522 priv
->cmd_array
= tempcmd_array
;
1524 /* Allocate and initialize command buffers */
1525 ulbufsize
= MRVDRV_SIZE_OF_CMD_BUFFER
;
1526 for (i
= 0; i
< MRVDRV_NUM_OF_CMD_BUFFER
; i
++) {
1527 if (!(ptempvirtualaddr
= kzalloc(ulbufsize
, GFP_KERNEL
))) {
1528 lbs_deb_host("ALLOC_CMD_BUF: ptempvirtualaddr is NULL\n");
1533 /* Update command buffer virtual */
1534 tempcmd_array
[i
].bufvirtualaddr
= ptempvirtualaddr
;
1537 for (i
= 0; i
< MRVDRV_NUM_OF_CMD_BUFFER
; i
++) {
1538 init_waitqueue_head(&tempcmd_array
[i
].cmdwait_q
);
1539 lbs_cleanup_and_insert_cmd(priv
, &tempcmd_array
[i
]);
1545 lbs_deb_leave_args(LBS_DEB_HOST
, "ret %d", ret
);
1550 * @brief This function frees the command buffer.
1552 * @param priv A pointer to struct lbs_private structure
1555 int lbs_free_cmd_buffer(struct lbs_private
*priv
)
1557 u32 ulbufsize
; /* Someone needs to die for this. Slowly and painfully */
1559 struct cmd_ctrl_node
*tempcmd_array
;
1561 lbs_deb_enter(LBS_DEB_HOST
);
1563 /* need to check if cmd array is allocated or not */
1564 if (priv
->cmd_array
== NULL
) {
1565 lbs_deb_host("FREE_CMD_BUF: cmd_array is NULL\n");
1569 tempcmd_array
= priv
->cmd_array
;
1571 /* Release shared memory buffers */
1572 ulbufsize
= MRVDRV_SIZE_OF_CMD_BUFFER
;
1573 for (i
= 0; i
< MRVDRV_NUM_OF_CMD_BUFFER
; i
++) {
1574 if (tempcmd_array
[i
].bufvirtualaddr
) {
1575 kfree(tempcmd_array
[i
].bufvirtualaddr
);
1576 tempcmd_array
[i
].bufvirtualaddr
= NULL
;
1580 /* Release cmd_ctrl_node */
1581 if (priv
->cmd_array
) {
1582 kfree(priv
->cmd_array
);
1583 priv
->cmd_array
= NULL
;
1587 lbs_deb_leave(LBS_DEB_HOST
);
1592 * @brief This function gets a free command node if available in
1593 * command free queue.
1595 * @param priv A pointer to struct lbs_private structure
1596 * @return cmd_ctrl_node A pointer to cmd_ctrl_node structure or NULL
1598 struct cmd_ctrl_node
*lbs_get_cmd_ctrl_node(struct lbs_private
*priv
)
1600 struct cmd_ctrl_node
*tempnode
;
1601 unsigned long flags
;
1603 lbs_deb_enter(LBS_DEB_HOST
);
1608 spin_lock_irqsave(&priv
->driver_lock
, flags
);
1610 if (!list_empty(&priv
->cmdfreeq
)) {
1611 tempnode
= list_first_entry(&priv
->cmdfreeq
,
1612 struct cmd_ctrl_node
, list
);
1613 list_del(&tempnode
->list
);
1615 lbs_deb_host("GET_CMD_NODE: cmd_ctrl_node is not available\n");
1619 spin_unlock_irqrestore(&priv
->driver_lock
, flags
);
1622 cleanup_cmdnode(tempnode
);
1624 lbs_deb_leave(LBS_DEB_HOST
);
1629 * @brief This function cleans command node.
1631 * @param ptempnode A pointer to cmdCtrlNode structure
1634 static void cleanup_cmdnode(struct cmd_ctrl_node
*ptempnode
)
1636 lbs_deb_enter(LBS_DEB_HOST
);
1640 ptempnode
->cmdwaitqwoken
= 1;
1641 wake_up_interruptible(&ptempnode
->cmdwait_q
);
1642 ptempnode
->wait_option
= 0;
1643 ptempnode
->pdata_buf
= NULL
;
1644 ptempnode
->callback
= NULL
;
1645 ptempnode
->callback_arg
= 0;
1647 if (ptempnode
->bufvirtualaddr
!= NULL
)
1648 memset(ptempnode
->bufvirtualaddr
, 0, MRVDRV_SIZE_OF_CMD_BUFFER
);
1650 lbs_deb_leave(LBS_DEB_HOST
);
1654 * @brief This function initializes the command node.
1656 * @param priv A pointer to struct lbs_private structure
1657 * @param ptempnode A pointer to cmd_ctrl_node structure
1658 * @param wait_option wait option: wait response or not
1659 * @param pdata_buf A pointer to informaion buffer
1662 void lbs_set_cmd_ctrl_node(struct lbs_private
*priv
,
1663 struct cmd_ctrl_node
*ptempnode
,
1664 u16 wait_option
, void *pdata_buf
)
1666 lbs_deb_enter(LBS_DEB_HOST
);
1671 ptempnode
->wait_option
= wait_option
;
1672 ptempnode
->pdata_buf
= pdata_buf
;
1673 ptempnode
->callback
= NULL
;
1674 ptempnode
->callback_arg
= 0;
1676 lbs_deb_leave(LBS_DEB_HOST
);
1680 * @brief This function executes next command in command
1681 * pending queue. It will put fimware back to PS mode
1684 * @param priv A pointer to struct lbs_private structure
1687 int lbs_execute_next_command(struct lbs_private
*priv
)
1689 struct cmd_ctrl_node
*cmdnode
= NULL
;
1690 struct cmd_ds_command
*cmdptr
;
1691 unsigned long flags
;
1694 // Debug group is LBS_DEB_THREAD and not LBS_DEB_HOST, because the
1695 // only caller to us is lbs_thread() and we get even when a
1696 // data packet is received
1697 lbs_deb_enter(LBS_DEB_THREAD
);
1699 spin_lock_irqsave(&priv
->driver_lock
, flags
);
1701 if (priv
->cur_cmd
) {
1702 lbs_pr_alert( "EXEC_NEXT_CMD: already processing command!\n");
1703 spin_unlock_irqrestore(&priv
->driver_lock
, flags
);
1708 if (!list_empty(&priv
->cmdpendingq
)) {
1709 cmdnode
= list_first_entry(&priv
->cmdpendingq
,
1710 struct cmd_ctrl_node
, list
);
1713 spin_unlock_irqrestore(&priv
->driver_lock
, flags
);
1716 cmdptr
= (struct cmd_ds_command
*)cmdnode
->bufvirtualaddr
;
1718 if (is_command_allowed_in_ps(cmdptr
->command
)) {
1719 if ((priv
->psstate
== PS_STATE_SLEEP
) ||
1720 (priv
->psstate
== PS_STATE_PRE_SLEEP
)) {
1722 "EXEC_NEXT_CMD: cannot send cmd 0x%04x in psstate %d\n",
1723 le16_to_cpu(cmdptr
->command
),
1728 lbs_deb_host("EXEC_NEXT_CMD: OK to send command "
1729 "0x%04x in psstate %d\n",
1730 le16_to_cpu(cmdptr
->command
),
1732 } else if (priv
->psstate
!= PS_STATE_FULL_POWER
) {
1734 * 1. Non-PS command:
1735 * Queue it. set needtowakeup to TRUE if current state
1736 * is SLEEP, otherwise call lbs_ps_wakeup to send Exit_PS.
1737 * 2. PS command but not Exit_PS:
1739 * 3. PS command Exit_PS:
1740 * Set needtowakeup to TRUE if current state is SLEEP,
1741 * otherwise send this command down to firmware
1744 if (cmdptr
->command
!=
1745 cpu_to_le16(CMD_802_11_PS_MODE
)) {
1746 /* Prepare to send Exit PS,
1747 * this non PS command will be sent later */
1748 if ((priv
->psstate
== PS_STATE_SLEEP
)
1749 || (priv
->psstate
== PS_STATE_PRE_SLEEP
)
1751 /* w/ new scheme, it will not reach here.
1752 since it is blocked in main_thread. */
1753 priv
->needtowakeup
= 1;
1755 lbs_ps_wakeup(priv
, 0);
1761 * PS command. Ignore it if it is not Exit_PS.
1762 * otherwise send it down immediately.
1764 struct cmd_ds_802_11_ps_mode
*psm
=
1765 &cmdptr
->params
.psmode
;
1768 "EXEC_NEXT_CMD: PS cmd, action 0x%02x\n",
1771 cpu_to_le16(CMD_SUBCMD_EXIT_PS
)) {
1773 "EXEC_NEXT_CMD: ignore ENTER_PS cmd\n");
1774 list_del(&cmdnode
->list
);
1775 lbs_cleanup_and_insert_cmd(priv
, cmdnode
);
1781 if ((priv
->psstate
== PS_STATE_SLEEP
) ||
1782 (priv
->psstate
== PS_STATE_PRE_SLEEP
)) {
1784 "EXEC_NEXT_CMD: ignore EXIT_PS cmd in sleep\n");
1785 list_del(&cmdnode
->list
);
1786 lbs_cleanup_and_insert_cmd(priv
, cmdnode
);
1787 priv
->needtowakeup
= 1;
1794 "EXEC_NEXT_CMD: sending EXIT_PS\n");
1797 list_del(&cmdnode
->list
);
1798 lbs_deb_host("EXEC_NEXT_CMD: sending command 0x%04x\n",
1799 le16_to_cpu(cmdptr
->command
));
1800 DownloadcommandToStation(priv
, cmdnode
);
1803 * check if in power save mode, if yes, put the device back
1806 if ((priv
->psmode
!= LBS802_11POWERMODECAM
) &&
1807 (priv
->psstate
== PS_STATE_FULL_POWER
) &&
1808 ((priv
->connect_status
== LBS_CONNECTED
) ||
1809 (priv
->mesh_connect_status
== LBS_CONNECTED
))) {
1810 if (priv
->secinfo
.WPAenabled
||
1811 priv
->secinfo
.WPA2enabled
) {
1812 /* check for valid WPA group keys */
1813 if (priv
->wpa_mcast_key
.len
||
1814 priv
->wpa_unicast_key
.len
) {
1816 "EXEC_NEXT_CMD: WPA enabled and GTK_SET"
1817 " go back to PS_SLEEP");
1818 lbs_ps_sleep(priv
, 0);
1822 "EXEC_NEXT_CMD: cmdpendingq empty, "
1823 "go back to PS_SLEEP");
1824 lbs_ps_sleep(priv
, 0);
1831 lbs_deb_leave(LBS_DEB_THREAD
);
1835 void lbs_send_iwevcustom_event(struct lbs_private
*priv
, s8
*str
)
1837 union iwreq_data iwrq
;
1840 lbs_deb_enter(LBS_DEB_WEXT
);
1842 memset(&iwrq
, 0, sizeof(union iwreq_data
));
1843 memset(buf
, 0, sizeof(buf
));
1845 snprintf(buf
, sizeof(buf
) - 1, "%s", str
);
1847 iwrq
.data
.length
= strlen(buf
) + 1 + IW_EV_LCP_LEN
;
1849 /* Send Event to upper layer */
1850 lbs_deb_wext("event indication string %s\n", (char *)buf
);
1851 lbs_deb_wext("event indication length %d\n", iwrq
.data
.length
);
1852 lbs_deb_wext("sending wireless event IWEVCUSTOM for %s\n", str
);
1854 wireless_send_event(priv
->dev
, IWEVCUSTOM
, &iwrq
, buf
);
1856 lbs_deb_leave(LBS_DEB_WEXT
);
1859 static int sendconfirmsleep(struct lbs_private
*priv
, u8
*cmdptr
, u16 size
)
1861 unsigned long flags
;
1864 lbs_deb_enter(LBS_DEB_HOST
);
1866 lbs_deb_host("SEND_SLEEPC_CMD: before download, cmd size %d\n",
1869 lbs_deb_hex(LBS_DEB_HOST
, "sleep confirm command", cmdptr
, size
);
1871 ret
= priv
->hw_host_to_card(priv
, MVMS_CMD
, cmdptr
, size
);
1872 priv
->dnld_sent
= DNLD_RES_RECEIVED
;
1874 spin_lock_irqsave(&priv
->driver_lock
, flags
);
1875 if (priv
->intcounter
|| priv
->currenttxskb
)
1876 lbs_deb_host("SEND_SLEEPC_CMD: intcounter %d, currenttxskb %p\n",
1877 priv
->intcounter
, priv
->currenttxskb
);
1878 spin_unlock_irqrestore(&priv
->driver_lock
, flags
);
1882 "SEND_SLEEPC_CMD: Host to Card failed for Confirm Sleep\n");
1884 spin_lock_irqsave(&priv
->driver_lock
, flags
);
1885 if (!priv
->intcounter
) {
1886 priv
->psstate
= PS_STATE_SLEEP
;
1888 lbs_deb_host("SEND_SLEEPC_CMD: after sent, intcounter %d\n",
1891 spin_unlock_irqrestore(&priv
->driver_lock
, flags
);
1893 lbs_deb_host("SEND_SLEEPC_CMD: sent confirm sleep\n");
1896 lbs_deb_leave_args(LBS_DEB_HOST
, "ret %d", ret
);
1900 void lbs_ps_sleep(struct lbs_private
*priv
, int wait_option
)
1902 lbs_deb_enter(LBS_DEB_HOST
);
1905 * PS is currently supported only in Infrastructure mode
1906 * Remove this check if it is to be supported in IBSS mode also
1909 lbs_prepare_and_send_command(priv
, CMD_802_11_PS_MODE
,
1910 CMD_SUBCMD_ENTER_PS
, wait_option
, 0, NULL
);
1912 lbs_deb_leave(LBS_DEB_HOST
);
1916 * @brief This function sends Exit_PS command to firmware.
1918 * @param priv A pointer to struct lbs_private structure
1919 * @param wait_option wait response or not
1922 void lbs_ps_wakeup(struct lbs_private
*priv
, int wait_option
)
1926 lbs_deb_enter(LBS_DEB_HOST
);
1928 Localpsmode
= cpu_to_le32(LBS802_11POWERMODECAM
);
1930 lbs_prepare_and_send_command(priv
, CMD_802_11_PS_MODE
,
1932 wait_option
, 0, &Localpsmode
);
1934 lbs_deb_leave(LBS_DEB_HOST
);
1938 * @brief This function checks condition and prepares to
1939 * send sleep confirm command to firmware if ok.
1941 * @param priv A pointer to struct lbs_private structure
1942 * @param psmode Power Saving mode
1945 void lbs_ps_confirm_sleep(struct lbs_private
*priv
, u16 psmode
)
1947 unsigned long flags
=0;
1950 lbs_deb_enter(LBS_DEB_HOST
);
1952 if (priv
->dnld_sent
) {
1954 lbs_deb_host("dnld_sent was set");
1957 spin_lock_irqsave(&priv
->driver_lock
, flags
);
1958 if (priv
->cur_cmd
) {
1960 lbs_deb_host("cur_cmd was set");
1962 if (priv
->intcounter
> 0) {
1964 lbs_deb_host("intcounter %d", priv
->intcounter
);
1966 spin_unlock_irqrestore(&priv
->driver_lock
, flags
);
1969 lbs_deb_host("sending lbs_ps_confirm_sleep\n");
1970 sendconfirmsleep(priv
, (u8
*) & priv
->lbs_ps_confirm_sleep
,
1971 sizeof(struct PS_CMD_ConfirmSleep
));
1973 lbs_deb_host("sleep confirm has been delayed\n");
1976 lbs_deb_leave(LBS_DEB_HOST
);
1981 * @brief Simple way to call firmware functions
1983 * @param priv A pointer to struct lbs_private structure
1984 * @param psmode one of the many CMD_802_11_xxxx
1985 * @param cmd pointer to the parameters structure for above command
1986 * (this should not include the command, size, sequence
1987 * and result fields from struct cmd_ds_gen)
1988 * @param cmd_size size structure pointed to by cmd
1989 * @param rsp pointer to an area where the result should be placed
1990 * @param rsp_size pointer to the size of the rsp area. If the firmware
1991 * returns fewer bytes, then this *rsp_size will be
1992 * changed to the actual size.
1993 * @return -1 in case of a higher level error, otherwise
1994 * the result code from the firmware
1997 int lbs_cmd(struct lbs_private
*priv
, uint16_t command
, void *cmd
, int cmd_size
,
1998 int (*callback
)(struct lbs_private
*, unsigned long, struct cmd_ds_command
*),
1999 unsigned long callback_arg
)
2001 struct cmd_ctrl_node
*cmdnode
;
2002 struct cmd_ds_gen
*cmdptr
;
2003 unsigned long flags
;
2006 lbs_deb_enter(LBS_DEB_HOST
);
2009 lbs_deb_host("PREP_CMD: priv is NULL\n");
2014 if (priv
->surpriseremoved
) {
2015 lbs_deb_host("PREP_CMD: card removed\n");
2020 cmdnode
= lbs_get_cmd_ctrl_node(priv
);
2022 if (cmdnode
== NULL
) {
2023 lbs_deb_host("PREP_CMD: cmdnode is NULL\n");
2025 /* Wake up main thread to execute next command */
2026 wake_up_interruptible(&priv
->waitq
);
2031 cmdptr
= (struct cmd_ds_gen
*)cmdnode
->bufvirtualaddr
;
2032 cmdnode
->wait_option
= CMD_OPTION_WAITFORRSP
;
2033 cmdnode
->callback
= callback
;
2034 cmdnode
->callback_arg
= callback_arg
;
2036 /* Set sequence number, clean result, move to buffer */
2038 cmdptr
->command
= cpu_to_le16(command
);
2039 cmdptr
->size
= cpu_to_le16(cmd_size
+ S_DS_GEN
);
2040 cmdptr
->seqnum
= cpu_to_le16(priv
->seqnum
);
2042 memcpy(cmdptr
->cmdresp
, cmd
, cmd_size
);
2044 lbs_deb_host("PREP_CMD: command 0x%04x\n", command
);
2046 /* here was the big old switch() statement, which is now obsolete,
2047 * because the caller of lbs_cmd() sets up all of *cmd for us. */
2049 cmdnode
->cmdwaitqwoken
= 0;
2050 lbs_queue_cmd(priv
, cmdnode
, 1);
2051 wake_up_interruptible(&priv
->waitq
);
2054 wait_event_interruptible(cmdnode
->cmdwait_q
, cmdnode
->cmdwaitqwoken
);
2056 spin_lock_irqsave(&priv
->driver_lock
, flags
);
2057 if (priv
->cur_cmd_retcode
) {
2058 lbs_deb_host("PREP_CMD: command failed with return code %d\n",
2059 priv
->cur_cmd_retcode
);
2060 priv
->cur_cmd_retcode
= 0;
2063 spin_unlock_irqrestore(&priv
->driver_lock
, flags
);
2066 lbs_deb_leave_args(LBS_DEB_HOST
, "ret %d", ret
);
2069 EXPORT_SYMBOL_GPL(lbs_cmd
);