78 #include <linux/kernel.h>
79 #include <linux/slab.h>
81 #include <linux/export.h>
85 #define D_SUBMODULE control
88 static int i2400m_idle_mode_disabled;
91 "If true, the device will not enable idle mode negotiation "
92 "with the base station (when connected) to save power.");
95 static int i2400m_power_save_disabled;
98 "If true, the driver will not tell the device to enter "
99 "power saving mode when it reports it is ready for it. "
100 "False by default (so the device is told to do power "
103 static int i2400m_passive_mode;
106 "If true, the driver will not do any device setup "
107 "and leave it up to user space, who must be properly "
133 "size (got %zu vs %zd expected)\n",
134 tlv_type, size, tlv_size);
163 const void *tlv_buf,
size_t buf_size,
174 tlv_pos = (
void *) tlv_pos
176 if (tlv_pos == tlv_top) {
178 goto error_beyond_end;
180 if (tlv_pos > tlv_top) {
183 goto error_beyond_end;
185 offset = (
void *) tlv_pos - (
void *) tlv_buf;
186 avail_size = buf_size -
offset;
187 if (avail_size <
sizeof(*tlv_pos)) {
188 dev_err(dev,
"HW BUG? tlv_buf %p [%zu bytes], tlv @%zu: "
189 "short header\n", tlv_buf, buf_size, offset);
190 goto error_short_header;
194 if (avail_size <
sizeof(*tlv_pos) + length) {
195 dev_err(dev,
"HW BUG? tlv_buf %p [%zu bytes], "
196 "tlv type 0x%04x @%zu: "
197 "short data (%zu bytes vs %zu needed)\n",
198 tlv_buf, buf_size, type, offset, avail_size,
199 sizeof(*tlv_pos) + length);
200 goto error_short_header;
225 struct i2400m *i2400m,
230 struct device *dev = i2400m_dev(i2400m);
232 while ((tlv = i2400m_tlv_buffer_walk(i2400m, tlv_hdr, size, tlv))) {
233 match = i2400m_tlv_match(tlv, tlv_type, tlv_size);
237 dev_warn(dev,
"TLV type 0x%04x found with size "
238 "mismatch (%zu vs %zd needed)\n",
239 tlv_type, match, tlv_size);
265 {
"not ready for powersave", -
EACCES },
283 char *
strbuf,
size_t strbuf_size)
292 str =
"unknown status code";
295 str = ms_to_errno[
status].msg;
296 result = ms_to_errno[
status].errno;
299 snprintf(strbuf, strbuf_size,
"%s (%d)", str, status);
311 void i2400m_report_tlv_system_state(
struct i2400m *i2400m,
314 struct device *dev = i2400m_dev(i2400m);
318 d_fnstart(3, dev,
"(i2400m %p ss %p [%u])\n", i2400m, ss, i2400m_state);
320 if (i2400m->
state != i2400m_state) {
321 i2400m->
state = i2400m_state;
324 switch (i2400m_state) {
354 d_printf(1, dev,
"entering BS-negotiated idle mode\n");
362 dev_err(dev,
"HW BUG? unknown state %u: shutting down\n",
367 d_fnend(3, dev,
"(i2400m %p ss %p [%u]) = void\n",
368 i2400m, ss, i2400m_state);
387 void i2400m_report_tlv_media_status(
struct i2400m *i2400m,
390 struct device *dev = i2400m_dev(i2400m);
391 struct wimax_dev *wimax_dev = &i2400m->
wimax_dev;
395 d_fnstart(3, dev,
"(i2400m %p ms %p [%u])\n", i2400m, ms, status);
413 dev_err(dev,
"HW BUG? unknown media status %u\n",
416 d_fnend(3, dev,
"(i2400m %p ms %p [%u]) = void\n",
432 void i2400m_report_state_parse_tlv(
struct i2400m *i2400m,
436 struct device *dev = i2400m_dev(i2400m);
443 d_printf(2, dev,
"%s: system state TLV "
444 "found (0x%04x), state 0x%08x\n",
447 i2400m_report_tlv_system_state(i2400m, ss);
451 d_printf(2, dev,
"%s: RF status TLV "
452 "found (0x%04x), sw 0x%02x hw 0x%02x\n",
460 d_printf(2, dev,
"%s: Media Status TLV: %u\n",
462 i2400m_report_tlv_media_status(i2400m, ms);
480 void i2400m_report_state_hook(
struct i2400m *i2400m,
482 size_t size,
const char *tag)
484 struct device *dev = i2400m_dev(i2400m);
488 d_fnstart(4, dev,
"(i2400m %p, l3l4_hdr %p, size %zu, %s)\n",
489 i2400m, l3l4_hdr, size, tag);
492 while ((tlv = i2400m_tlv_buffer_walk(i2400m, &l3l4_hdr->
pl,
494 i2400m_report_state_parse_tlv(i2400m, tlv, tag);
495 d_fnend(4, dev,
"(i2400m %p, l3l4_hdr %p, size %zu, %s) = void\n",
496 i2400m, l3l4_hdr, size, tag);
516 struct device *dev = i2400m_dev(i2400m);
519 d_fnstart(3, dev,
"(i2400m %p l3l4_hdr %p size %zu)\n",
520 i2400m, l3l4_hdr, size);
526 i2400m_report_state_hook(i2400m,
527 l3l4_hdr, size,
"REPORT STATE");
533 if (i2400m_power_save_disabled)
534 d_printf(1, dev,
"ready for powersave, "
535 "not requesting (disabled by module "
538 d_printf(1, dev,
"ready for powersave, "
545 d_fnend(3, dev,
"(i2400m %p l3l4_hdr %p size %zu) = void\n",
546 i2400m, l3l4_hdr, size);
563 static void i2400m_msg_ack_hook(
struct i2400m *i2400m,
568 struct device *dev = i2400m_dev(i2400m);
569 unsigned ack_type, ack_status;
582 l3l4_hdr, strerr,
sizeof(strerr));
584 d_printf(1, dev,
"ready for power save: %zd\n",
603 struct device *dev = i2400m_dev(i2400m);
604 size_t expected_size;
605 d_fnstart(4, dev,
"(i2400m %p l3l4_hdr %p msg_size %zu)\n",
606 i2400m, l3l4_hdr, msg_size);
607 if (msg_size <
sizeof(*l3l4_hdr)) {
608 dev_err(dev,
"bad size for message header "
609 "(expected at least %zu, got %zu)\n",
610 (
size_t)
sizeof(*l3l4_hdr), msg_size);
615 if (msg_size < expected_size) {
616 dev_err(dev,
"bad size for message code 0x%04x (expected %zu, "
618 expected_size, msg_size);
624 "(i2400m %p l3l4_hdr %p msg_size %zu) = %d\n",
625 i2400m, l3l4_hdr, msg_size, result);
647 if (ack_skb && !IS_ERR(ack_skb))
649 i2400m->
ack_skb = ERR_PTR(code);
650 spin_unlock_irqrestore(&i2400m->
rx_lock, flags);
708 const void *
buf,
size_t buf_len)
711 struct device *dev = i2400m_dev(i2400m);
720 d_fnstart(3, dev,
"(i2400m %p buf %p len %zu)\n",
721 i2400m, buf, buf_len);
733 d_printf(1, dev,
"CMD/GET/SET 0x%04x %zu bytes\n",
735 d_dump(2, dev, buf, buf_len);
742 spin_unlock_irqrestore(&i2400m->
rx_lock, flags);
746 dev_err(dev,
"can't send message 0x%04x: %d\n",
756 ack_timeout = 5 *
HZ;
771 dev_err(dev,
"timeout waiting for reply to message 0x%04x\n",
775 goto error_wait_for_completion;
776 }
else if (result < 0) {
777 dev_err(dev,
"error waiting for reply to message 0x%04x: %d\n",
780 goto error_wait_for_completion;
788 result = PTR_ERR(ack_skb);
792 spin_unlock_irqrestore(&i2400m->
rx_lock, flags);
794 goto error_ack_status;
803 dev_err(dev,
"HW BUG? reply to message 0x%04x: %d\n",
805 goto error_bad_ack_len;
808 dev_err(dev,
"HW BUG? bad reply 0x%04x to message 0x%04x\n",
811 goto error_bad_ack_type;
813 i2400m_msg_ack_hook(i2400m, ack_l3l4_hdr, ack_len);
815 d_fnend(3, dev,
"(i2400m %p buf %p len %zu) = %p\n",
816 i2400m, buf, buf_len, ack_skb);
823 error_wait_for_completion:
827 d_fnend(3, dev,
"(i2400m %p buf %p len %zu) = %d\n",
828 i2400m, buf, buf_len, result);
829 return ERR_PTR(result);
866 struct device *dev = i2400m_dev(i2400m);
883 result = PTR_ERR(ack_skb);
884 if (IS_ERR(ack_skb)) {
885 dev_err(dev,
"Failed to issue 'Enter power save' command: %d\n",
887 goto error_msg_to_dev;
890 strerr,
sizeof(strerr));
892 d_printf(1, dev,
"Cannot enter power save mode\n");
894 dev_err(dev,
"'Enter power save' (0x%04x) command failed: "
898 d_printf(1, dev,
"device ready to power save\n");
930 struct device *dev = i2400m_dev(i2400m);
939 ack_skb = ERR_PTR(-
ENOMEM);
948 if (IS_ERR(ack_skb)) {
949 dev_err(dev,
"Failed to issue 'get device info' command: %ld\n",
951 goto error_msg_to_dev;
956 dev_err(dev,
"'get device info' (0x%04x) command failed: "
959 goto error_cmd_failed;
961 tlv = i2400m_tlv_find(i2400m, ack->
pl, ack_len -
sizeof(*ack),
964 dev_err(dev,
"GET DEVICE INFO: "
965 "detailed device info TLV not found (0x%04x)\n",
970 skb_pull(ack_skb, (
void *) tlv - (
void *) ack_skb->
data);
980 return ERR_PTR(result);
1012 struct device *dev = i2400m_dev(i2400m);
1031 if (IS_ERR(ack_skb)) {
1032 result = PTR_ERR(ack_skb);
1033 dev_err(dev,
"Failed to issue 'get lm version' command: %-d\n",
1035 goto error_msg_to_dev;
1040 dev_err(dev,
"'get lm version' (0x%04x) command failed: "
1043 goto error_cmd_failed;
1045 tlv = i2400m_tlv_find(i2400m, ack->
pl, ack_len -
sizeof(*ack),
1048 dev_err(dev,
"get lm version: TLV not found (0x%04x)\n",
1059 dev_err(dev,
"unsupported major fw version "
1060 "%u.%u.%u\n", major, minor, branch);
1061 goto error_bad_major;
1065 dev_warn(dev,
"untested minor fw version %u.%u.%u\n",
1066 major, minor, branch);
1069 dev_info(dev,
"firmware interface version %u.%u.%u\n",
1070 major, minor, branch);
1096 struct device *dev = i2400m_dev(i2400m);
1110 result = PTR_ERR(ack_skb);
1111 if (IS_ERR(ack_skb)) {
1112 dev_err(dev,
"Failed to issue 'exit idle' command: %d\n",
1114 goto error_msg_to_dev;
1117 strerr,
sizeof(strerr));
1141 static int i2400m_cmd_get_state(
struct i2400m *i2400m)
1144 struct device *dev = i2400m_dev(i2400m);
1160 if (IS_ERR(ack_skb)) {
1161 dev_err(dev,
"Failed to issue 'get state' command: %ld\n",
1163 result = PTR_ERR(ack_skb);
1164 goto error_msg_to_dev;
1169 dev_err(dev,
"'get state' (0x%04x) command failed: "
1171 goto error_cmd_failed;
1173 i2400m_report_state_hook(i2400m, ack, ack_len -
sizeof(*ack),
1194 static int i2400m_set_init_config(
struct i2400m *i2400m,
1199 struct device *dev = i2400m_dev(i2400m);
1203 unsigned argc, argsize, tlv_size;
1207 d_fnstart(3, dev,
"(i2400m %p arg %p args %zu)\n", i2400m, arg, args);
1214 for (argc = 0; argc < args; argc++) {
1215 tlv_hdr = arg[
argc];
1222 buf = kzalloc(
sizeof(*cmd) + argsize,
GFP_KERNEL);
1231 itr = buf +
sizeof(*cmd);
1232 for (argc = 0; argc < args; argc++) {
1233 tlv_hdr = arg[
argc];
1235 memcpy(itr, tlv_hdr, tlv_size);
1241 result = PTR_ERR(ack_skb);
1242 if (IS_ERR(ack_skb)) {
1243 dev_err(dev,
"Failed to issue 'init config' command: %d\n",
1246 goto error_msg_to_dev;
1249 strerr,
sizeof(strerr));
1251 dev_err(dev,
"'init config' (0x%04x) command failed: %d - %s\n",
1258 d_fnend(3, dev,
"(i2400m %p arg %p args %zu) = %d\n",
1259 i2400m, arg, args, result);
1285 struct device *dev = i2400m_dev(i2400m);
1296 if (i2400m_le_v1_3(i2400m))
1303 cmd->hdr.length =
cpu_to_le16(
sizeof(*cmd) -
sizeof(cmd->hdr));
1308 cmd->cit.hdr.length =
cpu_to_le16(
sizeof(cmd->cit.timeout));
1312 if (IS_ERR(ack_skb)) {
1313 dev_err(dev,
"Failed to issue 'set idle timeout' command: "
1314 "%ld\n", PTR_ERR(ack_skb));
1315 result = PTR_ERR(ack_skb);
1316 goto error_msg_to_dev;
1321 dev_err(dev,
"'set idle timeout' (0x%04x) command failed: "
1323 goto error_cmd_failed;
1351 struct device *dev = i2400m_dev(i2400m);
1359 d_fnstart(3, dev,
"(i2400m %p)\n", i2400m);
1360 if (i2400m_passive_mode)
1363 if (i2400m_idle_mode_disabled) {
1364 if (i2400m_le_v1_3(i2400m)) {
1365 idle_params.
hdr.type =
1368 sizeof(idle_params) -
sizeof(idle_params.
hdr));
1371 args[argc++] = &idle_params.
hdr;
1373 idle_timeout.
hdr.type =
1376 sizeof(idle_timeout) -
sizeof(idle_timeout.
hdr));
1378 args[argc++] = &idle_timeout.
hdr;
1381 if (i2400m_ge_v1_4(i2400m)) {
1386 sizeof(df) -
sizeof(df.
hdr));
1388 args[argc++] = &df.
hdr;
1396 sizeof(dlhr) -
sizeof(dlhr.
hdr));
1398 args[argc++] = &dlhr.
hdr;
1401 result = i2400m_set_init_config(i2400m, args, argc);
1411 result = i2400m_cmd_get_state(i2400m);
1414 dev_err(dev,
"failed to initialize the device: %d\n", result);
1415 d_fnend(3, dev,
"(i2400m %p) = %d\n", i2400m, result);
1432 struct device *dev = i2400m_dev(i2400m);
1434 d_fnstart(3, dev,
"(i2400m %p)\n", i2400m);
1435 d_fnend(3, dev,
"(i2400m %p) = void\n", i2400m);