Linux Kernel
3.7.1
|
#include <i2400m.h>
struct i2400m - descriptor for an Intel 2400m
Members marked with [fill] must be filled out/initialized before calling i2400m_setup().
Note the /, / call pairs are very much doing almost the same, and depending on the underlying bus, some stuff has to be put in one or the other. The idea of setup/release is that they setup the minimal amount needed for loading firmware, where us dev_start/stop setup the rest needed to do full data/control traffic.
: [fill] USB imposes a 16 block size, but other busses will differ. So we have a tx_blk_size variable that the bus layer sets to tell the engine how much of that we need.
: [fill] Minimum room required while allocating TX queue's buffer space for message header. USB requires 16 bytes. Refer to bus specific driver code for details.
: [fill] Maximum payload size.
: [optional fill] Function called by the bus-generic code [i2400m_setup()] to setup the basic bus-specific communications to the the device needed to load firmware. See LIFE CYCLE above.
NOTE: Doesn't need to upload the firmware, as that is taken care of by the bus-generic code.
: [optional fill] Function called by the bus-generic code [i2400m_release()] to shutdown the basic bus-specific communications to the the device needed to load firmware. See LIFE CYCLE above.
This function does not need to reset the device, just tear down all the host resources created to handle communication with the device.
: [optional fill] Function called by the bus-generic code [i2400m_dev_start()] to do things needed to start the device. See LIFE CYCLE above.
NOTE: Doesn't need to upload the firmware, as that is taken care of by the bus-generic code.
: [optional fill] Function called by the bus-generic code [i2400m_dev_stop()] to do things needed for stopping the device. See LIFE CYCLE above.
This function does not need to reset the device, just tear down all the host resources created to handle communication with the device.
: [fill] Function called by the bus-generic code to let the bus-specific code know that there is data available in the TX FIFO for transmission to the device.
This function cannot sleep.
: [fill] Function called by the bus-generic code to reset the device in in various ways. Doesn't need to wait for the reset to finish.
If warm or cold reset fail, this function is expected to do a bus-specific reset (eg: USB reset) to get the device to a working state (even if it implies device disconecction).
Note the warm reset is used by the firmware uploader to reinitialize the device.
IMPORTANT: this is called very early in the device setup process, so it cannot rely on common infrastructure being laid out.
IMPORTANT: don't call reset on RT_BUS with i2400m->init_mutex held, as the .pre/.post reset handlers will deadlock.
: [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).
: [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 any error condition.
: [fill] Function called to wait for a boot-mode notification (that can be a response to a previously issued command or an asynchronous one). Will read until all the indicated size is read or timeout. Reading more or less data than asked for is an error condition. Return 0 if ok, < 0 errno code on error.
The caller to this function will check if the response is a barker that indicates the device going into reset mode.
: [fill] a NULL-terminated array with the names of the firmware images to try loading. This is made a list so we can support backward compatibility of firmware releases (eg: if we can't find the default v1.4, we try v1.3). In general, the name should be i2400m-fw-X-VERSION.sbcf, where X is the bus name. The list is tried in order and the first one that loads is used. The fw loader will set i2400m->fw_name to point to the active firmware image.
: [fill] Set to true if the device's MAC address provided in boot mode is kind of broken and needs to be re-read later on.
: [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 generic device for linkage into the kernel WiMAX stack. Due to the way a net_device is allocated, we need to force this to be the first field so that we can get from netdev_priv() the right pointer.
: the device is up and ready for transmitting control and data packets. This implies (communication infrastructure with the device is ready) and the device's firmware has been loaded and the device initialized.
Write to it only inside a i2400m->init_mutex protected area followed with a wmb(); rmb() before accesing (unless locked inside i2400m->init_mutex). Read access can be loose like that [just using rmb()] because the paths that use this also do other error checks later on.
: Communication infrastructure with the device is ready, data frames can start to be passed around (this is lighter than using the WiMAX state for certain hot paths).
Write to it only inside a i2400m->init_mutex protected area followed with a wmb(); rmb() before accesing (unless locked inside i2400m->init_mutex). Read access can be loose like that [just using rmb()] because the paths that use this also do other error checks later on.
: 1 if RX reordering is enabled; this can only be set at probe time.
: device's state (as reported by it)
: waitqueue that is woken up whenever the state changes
: spinlock to protect TX members
: FIFO buffer for TX; we queue data here
: FIFO index for incoming data. Note this doesn't wrap around and it is always greater than .
: FIFO index for outgoing data
: current TX message that is active in the FIFO for appending payloads.
: current sequence number for TX messages from the device to the host.
: size of the current message being transmitted by the bus-specific code.
: total number of payloads sent
: maximum number of payloads sent in a TX message
: minimum number of payloads sent in a TX message
: number of TX messages sent
: number of bytes in all TX messages sent (this is different to net_dev's statistics as it also counts control messages).
: smallest TX message sent.
: biggest TX message sent.
: spinlock to protect RX members and rx_roq_refcount.
: total number of payloads received
: maximum number of payloads received in a RX message
: minimum number of payloads received in a RX message
: number of RX messages received
: number of bytes in all RX messages received (this is different to net_dev's statistics as it also counts control messages).
: smallest RX message received.
: buggest RX message received.
: RX ReOrder queues. (fw >= v1.4) When packets are received out of order, the device will ask the driver to hold certain packets until the ones that are received out of order can be delivered. Then the driver can release them to the host. See drivers/net/i2400m/rx.c for details.
: refcount rx_roq. This refcounts any access to rx_roq thus preventing rx_roq being destroyed when rx_roq is being accessed. rx_roq_refcount is protected by rx_lock.
: reports received from the device that couldn't be processed because the driver wasn't still ready; when ready, they are pulled from here and chewed.
: Work struct used to kick a scan of the RX reports list and to process each.
: MAC address used to make ethernet packets be coming from. This is generated at i2400m_setup() time and used during the life cycle of the instance. See i2400m_fake_eth_header().
: Mutex used for serializing the device bringup sequence; this way if the device reboots in the middle, we don't try to do a bringup again while we are tearing down the one that failed.
Can't reuse because from within the bringup sequence we need to send messages to the device and thus use .
: mutex used to send control commands to the device (we only allow one at a time, per host-device interface design).
: used to wait for an ack to a control command sent to the device.
: used to store the actual ack to a control command if the reception of the command was successful. Otherwise, a ERR_PTR() errno code that indicates what failed with the ack reception.
Only valid after is woken up. Only updateable if is armed. Only touched by i2400m_msg_to_dev().
Protected by . In theory the command execution flow is sequential, but in case the device sends an out-of-phase or very delayed response, we need to avoid it trampling current execution.
: boot mode command buffer for composing firmware upload commands.
USB can't r/w to stack, vmalloc, etc...as well, we end up having to alloc/free a lot to compose commands, so we use these for stagging and not having to realloc all the time.
This assumes the code always runs serialized. Only one thread can call i2400m_bm_cmd() at the same time.
: boot mode acknoledge buffer for staging reception of responses to commands.
See .
: work queue for processing device reports. This workqueue cannot be used for processing TX or RX to the device, as from it we'll process device reports, which might require further communication with the device.
: hookup for debugfs files. These have to be in a separate directory, a child of (wimax_dev->debugfs_dentry) so they can be removed when the module unloads, as we don't keep each dentry.
: name of the firmware image that is currently being used.
: version of the firmware interface, Major.minor, encoded in the high word and low word (major << 16 | minor).
: NULL terminated array of pointers to the firmware headers. This is only available during firmware load time.
: Used to cache firmware when the system goes to suspend/standby/hibernation (as on resume we can't read it). If NULL, no firmware was cached, read it. If ~0, you can't read any firmware files (the system still didn't come out of suspend and failed to cache one), so abort; otherwise, a valid cached firmware to be used. Access to this variable is protected by the spinlock i2400m->rx_lock.
: barker type that the device uses; this is initialized by i2400m_is_boot_barker() the first time it is called. Then it won't change during the life cycle of the device and every time a boot barker is received, it is just verified for it being the same.
: used to register for PM events
: counter for the number of bus resets attempted for this boot. It's not for tracking the number of bus resets during the whole driver life cycle (from insmod to rmmod) but for the number of dev_start() executed until dev_start() returns a success (ie: a good boot means a dev_stop() followed by a successful dev_start()). dev_reset_handler() increments this counter whenever it is triggering a bus reset. It checks this counter to decide if a subsequent bus reset should be retried. dev_reset_handler() retries the bus reset until dev_start() succeeds or the counter reaches I2400M_BUS_RESET_RETRIES. The counter is cleared to 0 in dev_reset_handle() when dev_start() returns a success, ie: a successul boot is completed.
: flag to denote if the device should be alive. This flag is everything like (see doc for ) except reflecting the device state we expect rather than the actual state as denoted by . It is set 1 whenever is set 1 in dev_start(). Then the device is expected to be alive all the time (i2400m->alive remains 1) until the driver is removed. Therefore all the device reboot events detected can be still handled properly by either dev_reset_handle() or .pre_reset/.post_reset as long as the driver presents. It is set 0 along with in dev_stop().
: flag to denote if we are ready to take an error recovery. 0 for ready to take an error recovery; 1 for not ready. It is initialized to 1 while probe() since we don't tend to take any error recovery during probe(). It is decremented by 1 whenever dev_start() succeeds to indicate we are ready to take error recovery from now on. It is checked every time we wanna schedule an error recovery. If an error recovery is already in place (error_recovery was set 1), we should not schedule another one until the last one is done.
struct i2400m_poke_table* bus_bm_pokes_table |
struct i2400m_bcf_hdr** fw_hdrs |
unsigned long fw_version |
struct completion msg_completion |
struct notifier_block pm_notifier |
struct work_struct recovery_ws |
struct i2400m_reset_ctx* reset_ctx |
struct work_struct reset_ws |
spinlock_t rx_lock |
struct work_struct rx_report_ws |
struct i2400m_roq* rx_roq |
enum i2400m_system_state state |
wait_queue_head_t state_wq |
spinlock_t tx_lock |
struct work_struct wake_tx_ws |
struct workqueue_struct* work_queue |