device.h: audit and cleanup users in main include dir
[linux-2.6.git] / include / net / mac80211.h
index acf9eaf..f0605df 100644 (file)
@@ -16,7 +16,6 @@
 #include <linux/kernel.h>
 #include <linux/if_ether.h>
 #include <linux/skbuff.h>
-#include <linux/device.h>
 #include <linux/ieee80211.h>
 #include <net/cfg80211.h>
 #include <asm/unaligned.h>
@@ -87,6 +86,8 @@
  *
  */
 
+struct device;
+
 /**
  * enum ieee80211_max_queues - maximum number of queues
  *
@@ -166,6 +167,7 @@ struct ieee80211_low_level_stats {
  *     that it is only ever disabled for station mode.
  * @BSS_CHANGED_IDLE: Idle changed for this BSS/interface.
  * @BSS_CHANGED_SSID: SSID changed for this BSS (AP mode)
+ * @BSS_CHANGED_AP_PROBE_RESP: Probe Response changed for this BSS (AP mode)
  */
 enum ieee80211_bss_change {
        BSS_CHANGED_ASSOC               = 1<<0,
@@ -184,6 +186,7 @@ enum ieee80211_bss_change {
        BSS_CHANGED_QOS                 = 1<<13,
        BSS_CHANGED_IDLE                = 1<<14,
        BSS_CHANGED_SSID                = 1<<15,
+       BSS_CHANGED_AP_PROBE_RESP       = 1<<16,
 
        /* when adding here, make sure to change ieee80211_reconfig */
 };
@@ -339,9 +342,9 @@ struct ieee80211_bss_conf {
  *     used to indicate that a frame was already retried due to PS
  * @IEEE80211_TX_INTFL_DONT_ENCRYPT: completely internal to mac80211,
  *     used to indicate frame should not be encrypted
- * @IEEE80211_TX_CTL_PSPOLL_RESPONSE: (internal?)
- *     This frame is a response to a PS-poll frame and should be sent
- *     although the station is in powersave mode.
+ * @IEEE80211_TX_CTL_POLL_RESPONSE: This frame is a response to a poll
+ *     frame (PS-Poll or uAPSD) and should be sent although the station
+ *     is in powersave mode.
  * @IEEE80211_TX_CTL_MORE_FRAMES: More frames will be passed to the
  *     transmit function after the current frame, this can be used
  *     by drivers to kick the DMA queue only if unset or when the
@@ -349,8 +352,6 @@ struct ieee80211_bss_conf {
  * @IEEE80211_TX_INTFL_RETRANSMISSION: This frame is being retransmitted
  *     after TX status because the destination was asleep, it must not
  *     be modified again (no seqno assignment, crypto, etc.)
- * @IEEE80211_TX_INTFL_HAS_RADIOTAP: This frame was injected and still
- *     has a radiotap header at skb->data.
  * @IEEE80211_TX_INTFL_NL80211_FRAME_TX: Frame was requested through nl80211
  *     MLME command (internal to mac80211 to figure out whether to send TX
  *     status to user space)
@@ -367,6 +368,17 @@ struct ieee80211_bss_conf {
  * @IEEE80211_TX_CTL_NO_CCK_RATE: This frame will be sent at non CCK rate.
  *     This flag is actually used for management frame especially for P2P
  *     frames not being sent at CCK rate in 2GHz band.
+ * @IEEE80211_TX_STATUS_EOSP: This packet marks the end of service period,
+ *     when its status is reported the service period ends. For frames in
+ *     an SP that mac80211 transmits, it is already set; for driver frames
+ *     the driver may set this flag. It is also used to do the same for
+ *     PS-Poll responses.
+ * @IEEE80211_TX_CTL_USE_MINRATE: This frame will be sent at lowest rate.
+ *     This flag is used to send nullfunc frame at minimum rate when
+ *     the nullfunc is used for connection monitoring purpose.
+ * @IEEE80211_TX_CTL_DONTFRAG: Don't fragment this packet even if it
+ *     would be fragmented by size (this is optional, only used for
+ *     monitor injection).
  *
  * Note: If you have to add new flags to the enumeration, then don't
  *      forget to update %IEEE80211_TX_TEMPORARY_FLAGS when necessary.
@@ -388,16 +400,19 @@ enum mac80211_tx_control_flags {
        IEEE80211_TX_INTFL_NEED_TXPROCESSING    = BIT(14),
        IEEE80211_TX_INTFL_RETRIED              = BIT(15),
        IEEE80211_TX_INTFL_DONT_ENCRYPT         = BIT(16),
-       IEEE80211_TX_CTL_PSPOLL_RESPONSE        = BIT(17),
+       IEEE80211_TX_CTL_POLL_RESPONSE          = BIT(17),
        IEEE80211_TX_CTL_MORE_FRAMES            = BIT(18),
        IEEE80211_TX_INTFL_RETRANSMISSION       = BIT(19),
-       IEEE80211_TX_INTFL_HAS_RADIOTAP         = BIT(20),
+       /* hole at 20, use later */
        IEEE80211_TX_INTFL_NL80211_FRAME_TX     = BIT(21),
        IEEE80211_TX_CTL_LDPC                   = BIT(22),
        IEEE80211_TX_CTL_STBC                   = BIT(23) | BIT(24),
        IEEE80211_TX_CTL_TX_OFFCHAN             = BIT(25),
        IEEE80211_TX_INTFL_TKIP_MIC_FAILURE     = BIT(26),
        IEEE80211_TX_CTL_NO_CCK_RATE            = BIT(27),
+       IEEE80211_TX_STATUS_EOSP                = BIT(28),
+       IEEE80211_TX_CTL_USE_MINRATE            = BIT(29),
+       IEEE80211_TX_CTL_DONTFRAG               = BIT(30),
 };
 
 #define IEEE80211_TX_CTL_STBC_SHIFT            23
@@ -411,9 +426,9 @@ enum mac80211_tx_control_flags {
        IEEE80211_TX_CTL_SEND_AFTER_DTIM | IEEE80211_TX_CTL_AMPDU |           \
        IEEE80211_TX_STAT_TX_FILTERED | IEEE80211_TX_STAT_ACK |               \
        IEEE80211_TX_STAT_AMPDU | IEEE80211_TX_STAT_AMPDU_NO_BACK |           \
-       IEEE80211_TX_CTL_RATE_CTRL_PROBE | IEEE80211_TX_CTL_PSPOLL_RESPONSE | \
+       IEEE80211_TX_CTL_RATE_CTRL_PROBE | IEEE80211_TX_CTL_POLL_RESPONSE |   \
        IEEE80211_TX_CTL_MORE_FRAMES | IEEE80211_TX_CTL_LDPC |                \
-       IEEE80211_TX_CTL_STBC)
+       IEEE80211_TX_CTL_STBC | IEEE80211_TX_STATUS_EOSP)
 
 /**
  * enum mac80211_rate_control_flags - per-rate flags set by the
@@ -506,7 +521,7 @@ struct ieee80211_tx_rate {
  * @flags: transmit info flags, defined above
  * @band: the band to transmit on (use for checking for races)
  * @antenna_sel_tx: antenna to use, 0 for automatic diversity
- * @pad: padding, ignore
+ * @ack_frame_id: internal frame ID for TX status, used internally
  * @control: union for control data
  * @status: union for status data
  * @driver_data: array of driver_data pointers
@@ -523,8 +538,7 @@ struct ieee80211_tx_info {
 
        u8 antenna_sel_tx;
 
-       /* 2 byte hole */
-       u8 pad[2];
+       u16 ack_frame_id;
 
        union {
                struct {
@@ -889,6 +903,10 @@ static inline bool ieee80211_vif_is_mesh(struct ieee80211_vif *vif)
  * @IEEE80211_KEY_FLAG_SW_MGMT: This flag should be set by the driver for a
  *     CCMP key if it requires CCMP encryption of management frames (MFP) to
  *     be done in software.
+ * @IEEE80211_KEY_FLAG_PUT_IV_SPACE: This flag should be set by the driver
+ *     for a CCMP key if space should be prepared for the IV, but the IV
+ *     itself should not be generated. Do not set together with
+ *     @IEEE80211_KEY_FLAG_GENERATE_IV on the same key.
  */
 enum ieee80211_key_flags {
        IEEE80211_KEY_FLAG_WMM_STA      = 1<<0,
@@ -896,6 +914,7 @@ enum ieee80211_key_flags {
        IEEE80211_KEY_FLAG_GENERATE_MMIC= 1<<2,
        IEEE80211_KEY_FLAG_PAIRWISE     = 1<<3,
        IEEE80211_KEY_FLAG_SW_MGMT      = 1<<4,
+       IEEE80211_KEY_FLAG_PUT_IV_SPACE = 1<<5,
 };
 
 /**
@@ -1292,6 +1311,16 @@ ieee80211_get_alt_retry_rate(const struct ieee80211_hw *hw,
 }
 
 /**
+ * ieee80211_free_txskb - free TX skb
+ * @hw: the hardware
+ * @skb: the skb
+ *
+ * Free a transmit skb. Use this funtion when some failure
+ * to transmit happened and thus status cannot be reported.
+ */
+void ieee80211_free_txskb(struct ieee80211_hw *hw, struct sk_buff *skb);
+
+/**
  * DOC: Hardware crypto acceleration
  *
  * mac80211 is capable of taking advantage of many hardware
@@ -1411,7 +1440,7 @@ ieee80211_get_alt_retry_rate(const struct ieee80211_hw *hw,
  * DOC: Beacon filter support
  *
  * Some hardware have beacon filter support to reduce host cpu wakeups
- * which will reduce system power consumption. It usuallly works so that
+ * which will reduce system power consumption. It usually works so that
  * the firmware creates a checksum of the beacon but omits all constantly
  * changing elements (TSF, TIM etc). Whenever the checksum changes the
  * beacon is forwarded to the host, otherwise it will be just dropped. That
@@ -1533,6 +1562,95 @@ ieee80211_get_alt_retry_rate(const struct ieee80211_hw *hw,
  */
 
 /**
+ * DOC: AP support for powersaving clients
+ *
+ * In order to implement AP and P2P GO modes, mac80211 has support for
+ * client powersaving, both "legacy" PS (PS-Poll/null data) and uAPSD.
+ * There currently is no support for sAPSD.
+ *
+ * There is one assumption that mac80211 makes, namely that a client
+ * will not poll with PS-Poll and trigger with uAPSD at the same time.
+ * Both are supported, and both can be used by the same client, but
+ * they can't be used concurrently by the same client. This simplifies
+ * the driver code.
+ *
+ * The first thing to keep in mind is that there is a flag for complete
+ * driver implementation: %IEEE80211_HW_AP_LINK_PS. If this flag is set,
+ * mac80211 expects the driver to handle most of the state machine for
+ * powersaving clients and will ignore the PM bit in incoming frames.
+ * Drivers then use ieee80211_sta_ps_transition() to inform mac80211 of
+ * stations' powersave transitions. In this mode, mac80211 also doesn't
+ * handle PS-Poll/uAPSD.
+ *
+ * In the mode without %IEEE80211_HW_AP_LINK_PS, mac80211 will check the
+ * PM bit in incoming frames for client powersave transitions. When a
+ * station goes to sleep, we will stop transmitting to it. There is,
+ * however, a race condition: a station might go to sleep while there is
+ * data buffered on hardware queues. If the device has support for this
+ * it will reject frames, and the driver should give the frames back to
+ * mac80211 with the %IEEE80211_TX_STAT_TX_FILTERED flag set which will
+ * cause mac80211 to retry the frame when the station wakes up. The
+ * driver is also notified of powersave transitions by calling its
+ * @sta_notify callback.
+ *
+ * When the station is asleep, it has three choices: it can wake up,
+ * it can PS-Poll, or it can possibly start a uAPSD service period.
+ * Waking up is implemented by simply transmitting all buffered (and
+ * filtered) frames to the station. This is the easiest case. When
+ * the station sends a PS-Poll or a uAPSD trigger frame, mac80211
+ * will inform the driver of this with the @allow_buffered_frames
+ * callback; this callback is optional. mac80211 will then transmit
+ * the frames as usual and set the %IEEE80211_TX_CTL_POLL_RESPONSE
+ * on each frame. The last frame in the service period (or the only
+ * response to a PS-Poll) also has %IEEE80211_TX_STATUS_EOSP set to
+ * indicate that it ends the service period; as this frame must have
+ * TX status report it also sets %IEEE80211_TX_CTL_REQ_TX_STATUS.
+ * When TX status is reported for this frame, the service period is
+ * marked has having ended and a new one can be started by the peer.
+ *
+ * Another race condition can happen on some devices like iwlwifi
+ * when there are frames queued for the station and it wakes up
+ * or polls; the frames that are already queued could end up being
+ * transmitted first instead, causing reordering and/or wrong
+ * processing of the EOSP. The cause is that allowing frames to be
+ * transmitted to a certain station is out-of-band communication to
+ * the device. To allow this problem to be solved, the driver can
+ * call ieee80211_sta_block_awake() if frames are buffered when it
+ * is notified that the station went to sleep. When all these frames
+ * have been filtered (see above), it must call the function again
+ * to indicate that the station is no longer blocked.
+ *
+ * If the driver buffers frames in the driver for aggregation in any
+ * way, it must use the ieee80211_sta_set_buffered() call when it is
+ * notified of the station going to sleep to inform mac80211 of any
+ * TIDs that have frames buffered. Note that when a station wakes up
+ * this information is reset (hence the requirement to call it when
+ * informed of the station going to sleep). Then, when a service
+ * period starts for any reason, @release_buffered_frames is called
+ * with the number of frames to be released and which TIDs they are
+ * to come from. In this case, the driver is responsible for setting
+ * the EOSP (for uAPSD) and MORE_DATA bits in the released frames,
+ * to help the @more_data paramter is passed to tell the driver if
+ * there is more data on other TIDs -- the TIDs to release frames
+ * from are ignored since mac80211 doesn't know how many frames the
+ * buffers for those TIDs contain.
+ *
+ * If the driver also implement GO mode, where absence periods may
+ * shorten service periods (or abort PS-Poll responses), it must
+ * filter those response frames except in the case of frames that
+ * are buffered in the driver -- those must remain buffered to avoid
+ * reordering. Because it is possible that no frames are released
+ * in this case, the driver must call ieee80211_sta_eosp_irqsafe()
+ * to indicate to mac80211 that the service period ended anyway.
+ *
+ * Finally, if frames from multiple TIDs are released from mac80211
+ * but the driver might reorder them, it must clear & set the flags
+ * appropriately (only the last frame may have %IEEE80211_TX_STATUS_EOSP)
+ * and also take care of the EOSP and MORE_DATA bits in the frame.
+ * The driver may also use ieee80211_sta_eosp_irqsafe() in this case.
+ */
+
+/**
  * enum ieee80211_filter_flags - hardware filter flags
  *
  * These flags determine what the filter in hardware should be
@@ -1622,6 +1740,17 @@ enum ieee80211_tx_sync_type {
 };
 
 /**
+ * enum ieee80211_frame_release_type - frame release reason
+ * @IEEE80211_FRAME_RELEASE_PSPOLL: frame released for PS-Poll
+ * @IEEE80211_FRAME_RELEASE_UAPSD: frame(s) released due to
+ *     frame received on trigger-enabled AC
+ */
+enum ieee80211_frame_release_type {
+       IEEE80211_FRAME_RELEASE_PSPOLL,
+       IEEE80211_FRAME_RELEASE_UAPSD,
+};
+
+/**
  * struct ieee80211_ops - callbacks from mac80211 to the driver
  *
  * This structure contains various callbacks that the driver may
@@ -1632,11 +1761,21 @@ enum ieee80211_tx_sync_type {
  *     skb contains the buffer starting from the IEEE 802.11 header.
  *     The low-level driver should send the frame out based on
  *     configuration in the TX control data. This handler should,
- *     preferably, never fail and stop queues appropriately, more
- *     importantly, however, it must never fail for A-MPDU-queues.
- *     This function should return NETDEV_TX_OK except in very
- *     limited cases.
- *     Must be implemented and atomic.
+ *     preferably, never fail and stop queues appropriately.
+ *     This must be implemented if @tx_frags is not.
+ *     Must be atomic.
+ *
+ * @tx_frags: Called to transmit multiple fragments of a single MSDU.
+ *     This handler must consume all fragments, sending out some of
+ *     them only is useless and it can't ask for some of them to be
+ *     queued again. If the frame is not fragmented the queue has a
+ *     single SKB only. To avoid issues with the networking stack
+ *     when TX status is reported the frames should be removed from
+ *     the skb queue.
+ *     If this is used, the tx_info @vif and @sta pointers will be
+ *     invalid -- you must not use them in that case.
+ *     This must be implemented if @tx isn't.
+ *     Must be atomic.
  *
  * @start: Called before the first netdevice attached to the hardware
  *     is enabled. This should turn on the hardware and must turn on
@@ -1931,9 +2070,50 @@ enum ieee80211_tx_sync_type {
  *     The callback can sleep.
  * @rssi_callback: Notify driver when the average RSSI goes above/below
  *     thresholds that were registered previously. The callback can sleep.
+ *
+ * @release_buffered_frames: Release buffered frames according to the given
+ *     parameters. In the case where the driver buffers some frames for
+ *     sleeping stations mac80211 will use this callback to tell the driver
+ *     to release some frames, either for PS-poll or uAPSD.
+ *     Note that if the @more_data paramter is %false the driver must check
+ *     if there are more frames on the given TIDs, and if there are more than
+ *     the frames being released then it must still set the more-data bit in
+ *     the frame. If the @more_data parameter is %true, then of course the
+ *     more-data bit must always be set.
+ *     The @tids parameter tells the driver which TIDs to release frames
+ *     from, for PS-poll it will always have only a single bit set.
+ *     In the case this is used for a PS-poll initiated release, the
+ *     @num_frames parameter will always be 1 so code can be shared. In
+ *     this case the driver must also set %IEEE80211_TX_STATUS_EOSP flag
+ *     on the TX status (and must report TX status) so that the PS-poll
+ *     period is properly ended. This is used to avoid sending multiple
+ *     responses for a retried PS-poll frame.
+ *     In the case this is used for uAPSD, the @num_frames parameter may be
+ *     bigger than one, but the driver may send fewer frames (it must send
+ *     at least one, however). In this case it is also responsible for
+ *     setting the EOSP flag in the QoS header of the frames. Also, when the
+ *     service period ends, the driver must set %IEEE80211_TX_STATUS_EOSP
+ *     on the last frame in the SP. Alternatively, it may call the function
+ *     ieee80211_sta_eosp_irqsafe() to inform mac80211 of the end of the SP.
+ *     This callback must be atomic.
+ * @allow_buffered_frames: Prepare device to allow the given number of frames
+ *     to go out to the given station. The frames will be sent by mac80211
+ *     via the usual TX path after this call. The TX information for frames
+ *     released will also have the %IEEE80211_TX_CTL_POLL_RESPONSE flag set
+ *     and the last one will also have %IEEE80211_TX_STATUS_EOSP set. In case
+ *     frames from multiple TIDs are released and the driver might reorder
+ *     them between the TIDs, it must set the %IEEE80211_TX_STATUS_EOSP flag
+ *     on the last frame and clear it on all others and also handle the EOSP
+ *     bit in the QoS header correctly. Alternatively, it can also call the
+ *     ieee80211_sta_eosp_irqsafe() function.
+ *     The @tids parameter is a bitmap and tells the driver which TIDs the
+ *     frames will be on; it will at most have two bits set.
+ *     This callback must be atomic.
  */
 struct ieee80211_ops {
        void (*tx)(struct ieee80211_hw *hw, struct sk_buff *skb);
+       void (*tx_frags)(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+                        struct ieee80211_sta *sta, struct sk_buff_head *skbs);
        int (*start)(struct ieee80211_hw *hw);
        void (*stop)(struct ieee80211_hw *hw);
 #ifdef CONFIG_PM
@@ -2003,7 +2183,8 @@ struct ieee80211_ops {
                          struct ieee80211_sta *sta);
        void (*sta_notify)(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
                        enum sta_notify_cmd, struct ieee80211_sta *sta);
-       int (*conf_tx)(struct ieee80211_hw *hw, u16 queue,
+       int (*conf_tx)(struct ieee80211_hw *hw,
+                      struct ieee80211_vif *vif, u16 queue,
                       const struct ieee80211_tx_queue_params *params);
        u64 (*get_tsf)(struct ieee80211_hw *hw, struct ieee80211_vif *vif);
        void (*set_tsf)(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
@@ -2045,6 +2226,17 @@ struct ieee80211_ops {
                                const struct cfg80211_bitrate_mask *mask);
        void (*rssi_callback)(struct ieee80211_hw *hw,
                              enum ieee80211_rssi_event rssi_event);
+
+       void (*allow_buffered_frames)(struct ieee80211_hw *hw,
+                                     struct ieee80211_sta *sta,
+                                     u16 tids, int num_frames,
+                                     enum ieee80211_frame_release_type reason,
+                                     bool more_data);
+       void (*release_buffered_frames)(struct ieee80211_hw *hw,
+                                       struct ieee80211_sta *sta,
+                                       u16 tids, int num_frames,
+                                       enum ieee80211_frame_release_type reason,
+                                       bool more_data);
 };
 
 /**
@@ -2359,7 +2551,7 @@ static inline int ieee80211_sta_ps_transition_ni(struct ieee80211_sta *sta,
  * The TX headroom reserved by mac80211 for its own tx_status functions.
  * This is enough for the radiotap header.
  */
-#define IEEE80211_TX_STATUS_HEADROOM   13
+#define IEEE80211_TX_STATUS_HEADROOM   14
 
 /**
  * ieee80211_sta_set_buffered - inform mac80211 about driver-buffered frames
@@ -2498,6 +2690,19 @@ static inline struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw,
 }
 
 /**
+ * ieee80211_proberesp_get - retrieve a Probe Response template
+ * @hw: pointer obtained from ieee80211_alloc_hw().
+ * @vif: &struct ieee80211_vif pointer from the add_interface callback.
+ *
+ * Creates a Probe Response template which can, for example, be uploaded to
+ * hardware. The destination address should be set by the caller.
+ *
+ * Can only be called in AP mode.
+ */
+struct sk_buff *ieee80211_proberesp_get(struct ieee80211_hw *hw,
+                                       struct ieee80211_vif *vif);
+
+/**
  * ieee80211_pspoll_get - retrieve a PS Poll template
  * @hw: pointer obtained from ieee80211_alloc_hw().
  * @vif: &struct ieee80211_vif pointer from the add_interface callback.
@@ -3048,6 +3253,24 @@ void ieee80211_sta_block_awake(struct ieee80211_hw *hw,
                               struct ieee80211_sta *pubsta, bool block);
 
 /**
+ * ieee80211_sta_eosp - notify mac80211 about end of SP
+ * @pubsta: the station
+ *
+ * When a device transmits frames in a way that it can't tell
+ * mac80211 in the TX status about the EOSP, it must clear the
+ * %IEEE80211_TX_STATUS_EOSP bit and call this function instead.
+ * This applies for PS-Poll as well as uAPSD.
+ *
+ * Note that there is no non-_irqsafe version right now as
+ * it wasn't needed, but just like _tx_status() and _rx()
+ * must not be mixed in irqsafe/non-irqsafe versions, this
+ * function must not be mixed with those either. Use the
+ * all irqsafe, or all non-irqsafe, don't mix! If you need
+ * the non-irqsafe version of this, you need to add it.
+ */
+void ieee80211_sta_eosp_irqsafe(struct ieee80211_sta *pubsta);
+
+/**
  * ieee80211_iter_keys - iterate keys programmed into the device
  * @hw: pointer obtained from ieee80211_alloc_hw()
  * @vif: virtual interface to iterate, may be %NULL for all
@@ -3280,9 +3503,12 @@ void ieee80211_send_bar(struct ieee80211_vif *vif, u8 *ra, u16 tid, u16 ssn);
  *
  * @IEEE80211_RC_HT_CHANGED: The HT parameters of the operating channel have
  *     changed, rate control algorithm can update its internal state if needed.
+ * @IEEE80211_RC_SMPS_CHANGED: The SMPS state of the station changed, the rate
+ *     control algorithm needs to adjust accordingly.
  */
 enum rate_control_changed {
-       IEEE80211_RC_HT_CHANGED = BIT(0)
+       IEEE80211_RC_HT_CHANGED         = BIT(0),
+       IEEE80211_RC_SMPS_CHANGED       = BIT(1),
 };
 
 /**
@@ -3386,8 +3612,9 @@ rate_lowest_index(struct ieee80211_supported_band *sband,
                        return i;
 
        /* warn when we cannot find a rate. */
-       WARN_ON(1);
+       WARN_ON_ONCE(1);
 
+       /* and return 0 (the lowest index) */
        return 0;
 }