[802.11] Add high-level support for CTS protection
[people/oremanj/gpxe.git] / src / net / net80211.c
index 13ef3c2..f378410 100644 (file)
@@ -130,6 +130,7 @@ net80211_marshal_request_info ( struct net80211_device *dev,
                                struct ieee80211_ie *ie );
 
 static void net80211_step_associate ( struct process *proc );
+static void net80211_set_rtscts_rate ( struct net80211_device *dev );
 static void net80211_set_rate_intelligently ( struct net80211_device *dev );
 static void net80211_handle_auth ( struct net80211_device *dev,
                                   struct io_buffer *iob );
@@ -961,6 +962,8 @@ static int net80211_process_ie ( struct net80211_device *dev,
 
                dev->nr_rates -= delta;
 
+               net80211_set_rtscts_rate ( dev );
+
                if ( dev->rates[dev->rate] != old_rate )
                        changed |= NET80211_CFG_RATE;
        }
@@ -1411,6 +1414,41 @@ void net80211_autoassociate ( struct net80211_device *dev )
        dev->associating = NULL;
 }
 
+/**
+ * Pick TX rate for RTS/CTS packets based on data rate
+ *
+ * @v dev      802.11 device
+ *
+ * The RTS/CTS rate is the fastest TX rate marked as "basic" that is
+ * not faster than the data rate.
+ */
+static void net80211_set_rtscts_rate ( struct net80211_device *dev )
+{
+       u16 datarate = NET80211_RATE_VALUE ( dev->rates[dev->rate] );
+       u16 rtsrate = 0;
+       int rts_idx = -1;
+       int i;
+
+       for ( i = 0; i < dev->nr_rates; i++ ) {
+               u16 rate = NET80211_RATE_VALUE ( dev->rates[i] );
+
+               if ( ! ( dev->basic_rates & ( 1 << i ) ) || rate > datarate )
+                       continue;
+
+               if ( rate > rtsrate ) {
+                       rtsrate = rate;
+                       rts_idx = i;
+               }
+       }
+
+       /* If this is in initialization, we might not have any basic
+          rates; just use the first data rate in that case. */
+       if ( rts_idx < 0 )
+               rts_idx = 0;
+
+       dev->rtscts_rate = rts_idx;
+}
+
 /**
  * Pick TX rate from the rate list we have
  *