Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
i2400m.h
Go to the documentation of this file.
1 /*
2  * Intel Wireless WiMAX Connection 2400m
3  * Declarations for bus-generic internal APIs
4  *
5  *
6  * Copyright (C) 2007-2008 Intel Corporation. All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * * Redistributions of source code must retain the above copyright
13  * notice, this list of conditions and the following disclaimer.
14  * * Redistributions in binary form must reproduce the above copyright
15  * notice, this list of conditions and the following disclaimer in
16  * the documentation and/or other materials provided with the
17  * distribution.
18  * * Neither the name of Intel Corporation nor the names of its
19  * contributors may be used to endorse or promote products derived
20  * from this software without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
25  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
26  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
27  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
28  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
30  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
32  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33  *
34  *
35  * Intel Corporation <[email protected]>
36  * Inaky Perez-Gonzalez <[email protected]>
37  * Yanir Lubetkin <[email protected]>
38  * - Initial implementation
39  *
40  *
41  * GENERAL DRIVER ARCHITECTURE
42  *
43  * The i2400m driver is split in the following two major parts:
44  *
45  * - bus specific driver
46  * - bus generic driver (this part)
47  *
48  * The bus specific driver sets up stuff specific to the bus the
49  * device is connected to (USB, PCI, tam-tam...non-authoritative
50  * nor binding list) which is basically the device-model management
51  * (probe/disconnect, etc), moving data from device to kernel and
52  * back, doing the power saving details and reseting the device.
53  *
54  * For details on each bus-specific driver, see it's include file,
55  * i2400m-BUSNAME.h
56  *
57  * The bus-generic functionality break up is:
58  *
59  * - Firmware upload: fw.c - takes care of uploading firmware to the
60  * device. bus-specific driver just needs to provides a way to
61  * execute boot-mode commands and to reset the device.
62  *
63  * - RX handling: rx.c - receives data from the bus-specific code and
64  * feeds it to the network or WiMAX stack or uses it to modify
65  * the driver state. bus-specific driver only has to receive
66  * frames and pass them to this module.
67  *
68  * - TX handling: tx.c - manages the TX FIFO queue and provides means
69  * for the bus-specific TX code to pull data from the FIFO
70  * queue. bus-specific code just pulls frames from this module
71  * to sends them to the device.
72  *
73  * - netdev glue: netdev.c - interface with Linux networking
74  * stack. Pass around data frames, and configure when the
75  * device is up and running or shutdown (through ifconfig up /
76  * down). Bus-generic only.
77  *
78  * - control ops: control.c - implements various commands for
79  * controlling the device. bus-generic only.
80  *
81  * - device model glue: driver.c - implements helpers for the
82  * device-model glue done by the bus-specific layer
83  * (setup/release the driver resources), turning the device on
84  * and off, handling the device reboots/resets and a few simple
85  * WiMAX stack ops.
86  *
87  * Code is also broken up in linux-glue / device-glue.
88  *
89  * Linux glue contains functions that deal mostly with gluing with the
90  * rest of the Linux kernel.
91  *
92  * Device-glue are functions that deal mostly with the way the device
93  * does things and talk the device's language.
94  *
95  * device-glue code is licensed BSD so other open source OSes can take
96  * it to implement their drivers.
97  *
98  *
99  * APIs AND HEADER FILES
100  *
101  * This bus generic code exports three APIs:
102  *
103  * - HDI (host-device interface) definitions common to all busses
104  * (include/linux/wimax/i2400m.h); these can be also used by user
105  * space code.
106  * - internal API for the bus-generic code
107  * - external API for the bus-specific drivers
108  *
109  *
110  * LIFE CYCLE:
111  *
112  * When the bus-specific driver probes, it allocates a network device
113  * with enough space for it's data structue, that must contain a
114  * &struct i2400m at the top.
115  *
116  * On probe, it needs to fill the i2400m members marked as [fill], as
117  * well as i2400m->wimax_dev.net_dev and call i2400m_setup(). The
118  * i2400m driver will only register with the WiMAX and network stacks;
119  * the only access done to the device is to read the MAC address so we
120  * can register a network device.
121  *
122  * The high-level call flow is:
123  *
124  * bus_probe()
125  * i2400m_setup()
126  * i2400m->bus_setup()
127  * boot rom initialization / read mac addr
128  * network / WiMAX stacks registration
129  * i2400m_dev_start()
130  * i2400m->bus_dev_start()
131  * i2400m_dev_initialize()
132  *
133  * The reverse applies for a disconnect() call:
134  *
135  * bus_disconnect()
136  * i2400m_release()
137  * i2400m_dev_stop()
138  * i2400m_dev_shutdown()
139  * i2400m->bus_dev_stop()
140  * network / WiMAX stack unregistration
141  * i2400m->bus_release()
142  *
143  * At this point, control and data communications are possible.
144  *
145  * While the device is up, it might reset. The bus-specific driver has
146  * to catch that situation and call i2400m_dev_reset_handle() to deal
147  * with it (reset the internal driver structures and go back to square
148  * one).
149  */
150 
151 #ifndef __I2400M_H__
152 #define __I2400M_H__
153 
154 #include <linux/usb.h>
155 #include <linux/netdevice.h>
156 #include <linux/completion.h>
157 #include <linux/rwsem.h>
158 #include <linux/atomic.h>
159 #include <net/wimax.h>
160 #include <linux/wimax/i2400m.h>
161 #include <asm/byteorder.h>
162 
163 enum {
164 /* netdev interface */
165  /*
166  * Out of NWG spec (R1_v1.2.2), 3.3.3 ASN Bearer Plane MTU Size
167  *
168  * The MTU is 1400 or less
169  */
171 };
172 
173 /* Misc constants */
174 enum {
175  /* Size of the Boot Mode Command buffer */
178 };
179 
180 enum {
181  /* Maximum number of bus reset can be retried */
183 };
184 
199 };
200 
201 #define I2400M_FW_POKE(a, d) { \
202  .address = cpu_to_le32(a), \
203  .data = cpu_to_le32(d) \
204 }
205 
206 
219  I2400M_RT_WARM, /* first measure */
220  I2400M_RT_COLD, /* second measure */
221  I2400M_RT_BUS, /* call in artillery */
222 };
223 
224 struct i2400m_reset_ctx;
225 struct i2400m_roq;
226 struct i2400m_barker_db;
227 
566 struct i2400m {
567  struct wimax_dev wimax_dev; /* FIRST! See doc */
568 
569  unsigned updown:1; /* Network device is up or down */
570  unsigned boot_mode:1; /* is the device in boot mode? */
571  unsigned sboot:1; /* signed or unsigned fw boot */
572  unsigned ready:1; /* Device comm infrastructure ready */
573  unsigned rx_reorder:1; /* RX reorder is enabled */
574  u8 trace_msg_from_user; /* echo rx msgs to 'trace' pipe */
575  /* typed u8 so /sys/kernel/debug/u8 can tweak */
577  wait_queue_head_t state_wq; /* Woken up when on state updates */
578 
582  unsigned bus_bm_retries;
583 
584  int (*bus_setup)(struct i2400m *);
585  int (*bus_dev_start)(struct i2400m *);
586  void (*bus_dev_stop)(struct i2400m *);
587  void (*bus_release)(struct i2400m *);
588  void (*bus_tx_kick)(struct i2400m *);
589  int (*bus_reset)(struct i2400m *, enum i2400m_reset_type);
591  const struct i2400m_bootrom_header *,
592  size_t, int flags);
594  struct i2400m_bootrom_header *, size_t);
595  const char **bus_fw_names;
598 
599  spinlock_t tx_lock; /* protect TX state */
600  void *tx_buf;
601  size_t tx_in, tx_out;
604  /* TX stats */
607 
608  /* RX stuff */
609  /* protect RX state and rx_roq_refcount */
613  struct i2400m_roq *rx_roq; /* access is refcounted */
614  struct kref rx_roq_refcount; /* refcount access to rx_roq */
616  struct list_head rx_reports; /* under rx_lock! */
618 
619  struct mutex msg_mutex; /* serialize command execution */
621  struct sk_buff *ack_skb; /* protected by rx_lock */
622 
623  void *bm_ack_buf; /* for receiving acks over USB */
624  void *bm_cmd_buf; /* for issuing commands over USB */
625 
627 
628  struct mutex init_mutex; /* protect bringup seq */
629  struct i2400m_reset_ctx *reset_ctx; /* protected by init_mutex */
630 
633 
635  const char *reset_reason;
636 
638 
640  const char *fw_name; /* name of the current firmware image */
641  unsigned long fw_version; /* version of the firmware interface */
642  const struct i2400m_bcf_hdr **fw_hdrs;
643  struct i2400m_fw *fw_cached; /* protected by rx_lock */
644  struct i2400m_barker_db *barker;
645 
647 
648  /* counting bus reset retries in this boot */
650 
651  /* if the device is expected to be alive */
652  unsigned alive;
653 
654  /* 0 if we are ready for error recovery; 1 if not ready */
656 
657 };
658 
659 
660 /*
661  * Bus-generic internal APIs
662  * -------------------------
663  */
664 
665 static inline
666 struct i2400m *wimax_dev_to_i2400m(struct wimax_dev *wimax_dev)
667 {
668  return container_of(wimax_dev, struct i2400m, wimax_dev);
669 }
670 
671 static inline
672 struct i2400m *net_dev_to_i2400m(struct net_device *net_dev)
673 {
674  return wimax_dev_to_i2400m(netdev_priv(net_dev));
675 }
676 
677 /*
678  * Boot mode support
679  */
680 
689 };
690 
708  I2400M_BRI_SOFT = 1 << 1,
711 };
712 
713 extern void i2400m_bm_cmd_prepare(struct i2400m_bootrom_header *);
714 extern int i2400m_dev_bootstrap(struct i2400m *, enum i2400m_bri);
715 extern int i2400m_read_mac_addr(struct i2400m *);
716 extern int i2400m_bootrom_init(struct i2400m *, enum i2400m_bri);
717 extern int i2400m_is_boot_barker(struct i2400m *, const void *, size_t);
718 static inline
719 int i2400m_is_d2h_barker(const void *buf)
720 {
721  const __le32 *barker = buf;
722  return le32_to_cpu(*barker) == I2400M_D2H_MSG_BARKER;
723 }
724 extern void i2400m_unknown_barker(struct i2400m *, const void *, size_t);
725 
726 /* Make/grok boot-rom header commands */
727 
728 static inline
729 __le32 i2400m_brh_command(enum i2400m_brh_opcode opcode, unsigned use_checksum,
730  unsigned direct_access)
731 {
732  return cpu_to_le32(
734  | (direct_access ? I2400M_BRH_DIRECT_ACCESS : 0)
735  | I2400M_BRH_RESPONSE_REQUIRED /* response always required */
736  | (use_checksum ? I2400M_BRH_USE_CHECKSUM : 0)
737  | (opcode & I2400M_BRH_OPCODE_MASK));
738 }
739 
740 static inline
741 void i2400m_brh_set_opcode(struct i2400m_bootrom_header *hdr,
742  enum i2400m_brh_opcode opcode)
743 {
744  hdr->command = cpu_to_le32(
746  | (opcode & I2400M_BRH_OPCODE_MASK));
747 }
748 
749 static inline
750 unsigned i2400m_brh_get_opcode(const struct i2400m_bootrom_header *hdr)
751 {
753 }
754 
755 static inline
756 unsigned i2400m_brh_get_response(const struct i2400m_bootrom_header *hdr)
757 {
760 }
761 
762 static inline
763 unsigned i2400m_brh_get_use_checksum(const struct i2400m_bootrom_header *hdr)
764 {
766 }
767 
768 static inline
769 unsigned i2400m_brh_get_response_required(
770  const struct i2400m_bootrom_header *hdr)
771 {
773 }
774 
775 static inline
776 unsigned i2400m_brh_get_direct_access(const struct i2400m_bootrom_header *hdr)
777 {
779 }
780 
781 static inline
782 unsigned i2400m_brh_get_signature(const struct i2400m_bootrom_header *hdr)
783 {
786 }
787 
788 
789 /*
790  * Driver / device setup and internal functions
791  */
792 extern void i2400m_init(struct i2400m *);
793 extern int i2400m_reset(struct i2400m *, enum i2400m_reset_type);
794 extern void i2400m_netdev_setup(struct net_device *net_dev);
795 extern int i2400m_sysfs_setup(struct device_driver *);
796 extern void i2400m_sysfs_release(struct device_driver *);
797 extern int i2400m_tx_setup(struct i2400m *);
798 extern void i2400m_wake_tx_work(struct work_struct *);
799 extern void i2400m_tx_release(struct i2400m *);
800 
801 extern int i2400m_rx_setup(struct i2400m *);
802 extern void i2400m_rx_release(struct i2400m *);
803 
804 extern void i2400m_fw_cache(struct i2400m *);
805 extern void i2400m_fw_uncache(struct i2400m *);
806 
807 extern void i2400m_net_rx(struct i2400m *, struct sk_buff *, unsigned,
808  const void *, int);
809 extern void i2400m_net_erx(struct i2400m *, struct sk_buff *,
810  enum i2400m_cs);
811 extern void i2400m_net_wake_stop(struct i2400m *);
812 enum i2400m_pt;
813 extern int i2400m_tx(struct i2400m *, const void *, size_t, enum i2400m_pt);
814 
815 #ifdef CONFIG_DEBUG_FS
816 extern int i2400m_debugfs_add(struct i2400m *);
817 extern void i2400m_debugfs_rm(struct i2400m *);
818 #else
819 static inline int i2400m_debugfs_add(struct i2400m *i2400m)
820 {
821  return 0;
822 }
823 static inline void i2400m_debugfs_rm(struct i2400m *i2400m) {}
824 #endif
825 
826 /* Initialize/shutdown the device */
827 extern int i2400m_dev_initialize(struct i2400m *);
828 extern void i2400m_dev_shutdown(struct i2400m *);
829 
831 
832 
833 /* HDI message's payload description handling */
834 
835 static inline
836 size_t i2400m_pld_size(const struct i2400m_pld *pld)
837 {
838  return I2400M_PLD_SIZE_MASK & le32_to_cpu(pld->val);
839 }
840 
841 static inline
842 enum i2400m_pt i2400m_pld_type(const struct i2400m_pld *pld)
843 {
844  return (I2400M_PLD_TYPE_MASK & le32_to_cpu(pld->val))
846 }
847 
848 static inline
849 void i2400m_pld_set(struct i2400m_pld *pld, size_t size,
850  enum i2400m_pt type)
851 {
852  pld->val = cpu_to_le32(
854  | (size & I2400M_PLD_SIZE_MASK));
855 }
856 
857 
858 /*
859  * API for the bus-specific drivers
860  * --------------------------------
861  */
862 
863 static inline
864 struct i2400m *i2400m_get(struct i2400m *i2400m)
865 {
866  dev_hold(i2400m->wimax_dev.net_dev);
867  return i2400m;
868 }
869 
870 static inline
871 void i2400m_put(struct i2400m *i2400m)
872 {
873  dev_put(i2400m->wimax_dev.net_dev);
874 }
875 
876 extern int i2400m_dev_reset_handle(struct i2400m *, const char *);
877 extern int i2400m_pre_reset(struct i2400m *);
878 extern int i2400m_post_reset(struct i2400m *);
879 extern void i2400m_error_recovery(struct i2400m *);
880 
881 /*
882  * _setup()/_release() are called by the probe/disconnect functions of
883  * the bus-specific drivers.
884  */
885 extern int i2400m_setup(struct i2400m *, enum i2400m_bri bm_flags);
886 extern void i2400m_release(struct i2400m *);
887 
888 extern int i2400m_rx(struct i2400m *, struct sk_buff *);
889 extern struct i2400m_msg_hdr *i2400m_tx_msg_get(struct i2400m *, size_t *);
890 extern void i2400m_tx_msg_sent(struct i2400m *);
891 
892 
893 /*
894  * Utility functions
895  */
896 
897 static inline
898 struct device *i2400m_dev(struct i2400m *i2400m)
899 {
900  return i2400m->wimax_dev.net_dev->dev.parent;
901 }
902 
903 extern int i2400m_msg_check_status(const struct i2400m_l3l4_hdr *,
904  char *, size_t);
905 extern int i2400m_msg_size_check(struct i2400m *,
906  const struct i2400m_l3l4_hdr *, size_t);
907 extern struct sk_buff *i2400m_msg_to_dev(struct i2400m *, const void *, size_t);
908 extern void i2400m_msg_to_dev_cancel_wait(struct i2400m *, int);
909 extern void i2400m_report_hook(struct i2400m *,
910  const struct i2400m_l3l4_hdr *, size_t);
911 extern void i2400m_report_hook_work(struct work_struct *);
912 extern int i2400m_cmd_enter_powersave(struct i2400m *);
913 extern int i2400m_cmd_exit_idle(struct i2400m *);
914 extern struct sk_buff *i2400m_get_device_info(struct i2400m *);
915 extern int i2400m_firmware_check(struct i2400m *);
916 extern int i2400m_set_idle_timeout(struct i2400m *, unsigned);
917 
918 static inline
919 struct usb_endpoint_descriptor *usb_get_epd(struct usb_interface *iface, int ep)
920 {
921  return &iface->cur_altsetting->endpoint[ep].desc;
922 }
923 
924 extern int i2400m_op_rfkill_sw_toggle(struct wimax_dev *,
925  enum wimax_rf_state);
927  struct i2400m *, const struct i2400m_tlv_rf_switches_status *);
928 
929 /*
930  * Helpers for firmware backwards compatibility
931  *
932  * As we aim to support at least the firmware version that was
933  * released with the previous kernel/driver release, some code will be
934  * conditionally executed depending on the firmware version. On each
935  * release, the code to support fw releases past the last two ones
936  * will be purged.
937  *
938  * By making it depend on this macros, it is easier to keep it a tab
939  * on what has to go and what not.
940  */
941 static inline
942 unsigned i2400m_le_v1_3(struct i2400m *i2400m)
943 {
944  /* running fw is lower or v1.3 */
945  return i2400m->fw_version <= 0x00090001;
946 }
947 
948 static inline
949 unsigned i2400m_ge_v1_4(struct i2400m *i2400m)
950 {
951  /* running fw is higher or v1.4 */
952  return i2400m->fw_version >= 0x00090002;
953 }
954 
955 
956 /*
957  * Do a millisecond-sleep for allowing wireshark to dump all the data
958  * packets. Used only for debugging.
959  */
960 static inline
961 void __i2400m_msleep(unsigned ms)
962 {
963 #if 1
964 #else
965  msleep(ms);
966 #endif
967 }
968 
969 
970 /* module initialization helpers */
971 extern int i2400m_barker_db_init(const char *);
972 extern void i2400m_barker_db_exit(void);
973 
974 
975 
976 #endif /* #ifndef __I2400M_H__ */