|
@@ -154,7 +154,6 @@ static void net80211_netdev_irq ( struct net_device *netdev, int enable );
|
154
|
154
|
* @defgroup net80211_linklayer 802.11 link-layer protocol functions
|
155
|
155
|
* @{
|
156
|
156
|
*/
|
157
|
|
-static u16 net80211_duration ( struct net80211_device *dev, int bytes );
|
158
|
157
|
static int net80211_ll_push ( struct net_device *netdev,
|
159
|
158
|
struct io_buffer *iobuf, const void *ll_dest,
|
160
|
159
|
const void *ll_source, uint16_t net_proto );
|
|
@@ -171,6 +170,7 @@ static int net80211_ll_mc_hash ( unsigned int af, const void *net_addr,
|
171
|
170
|
*/
|
172
|
171
|
static void net80211_add_channels ( struct net80211_device *dev, int start,
|
173
|
172
|
int len, int txpower );
|
|
173
|
+static void net80211_filter_hw_channels ( struct net80211_device *dev );
|
174
|
174
|
static void net80211_set_rtscts_rate ( struct net80211_device *dev );
|
175
|
175
|
static int net80211_process_capab ( struct net80211_device *dev,
|
176
|
176
|
u16 capab );
|
|
@@ -430,10 +430,9 @@ static inline int net80211_rate_is_erp ( u16 rate )
|
430
|
430
|
*
|
431
|
431
|
* No other frame types are currently supported by gPXE.
|
432
|
432
|
*/
|
433
|
|
-static u16 net80211_duration ( struct net80211_device *dev, int bytes )
|
|
433
|
+u16 net80211_duration ( struct net80211_device *dev, int bytes, u16 rate )
|
434
|
434
|
{
|
435
|
435
|
struct net80211_channel *chan = &dev->channels[dev->channel];
|
436
|
|
- u16 rate = dev->rates[dev->rate];
|
437
|
436
|
u32 kbps = rate * 100;
|
438
|
437
|
|
439
|
438
|
if ( chan->band == NET80211_BAND_5GHZ || net80211_rate_is_erp ( rate ) ) {
|
|
@@ -496,7 +495,7 @@ static int net80211_ll_push ( struct net_device *netdev,
|
496
|
495
|
|
497
|
496
|
/* We don't send fragmented frames, so duration is the time
|
498
|
497
|
for an SIFS + 10-byte ACK. */
|
499
|
|
- hdr->duration = net80211_duration ( dev, 10 );
|
|
498
|
+ hdr->duration = net80211_duration ( dev, 10, dev->rates[dev->rate] );
|
500
|
499
|
|
501
|
500
|
memcpy ( hdr->addr1, dev->bssid, ETH_ALEN );
|
502
|
501
|
memcpy ( hdr->addr2, ll_source, ETH_ALEN );
|
|
@@ -712,7 +711,7 @@ int net80211_tx_mgmt ( struct net80211_device *dev, u16 fc, u8 dest[6],
|
712
|
711
|
|
713
|
712
|
hdr->fc = IEEE80211_THIS_VERSION | IEEE80211_TYPE_MGMT |
|
714
|
713
|
( fc & ~IEEE80211_FC_PROTECTED );
|
715
|
|
- hdr->duration = net80211_duration ( dev, 10 );
|
|
714
|
+ hdr->duration = net80211_duration ( dev, 10, dev->rates[dev->rate] );
|
716
|
715
|
hdr->seq = IEEE80211_MAKESEQ ( ++dev->last_tx_seqnr, 0 );
|
717
|
716
|
|
718
|
717
|
memcpy ( hdr->addr1, dest, ETH_ALEN ); /* DA = RA */
|
|
@@ -908,6 +907,7 @@ static void net80211_add_channels ( struct net80211_device *dev, int start,
|
908
|
907
|
for ( i = dev->nr_channels; len-- && i < NET80211_MAX_CHANNELS; i++ ) {
|
909
|
908
|
dev->channels[i].channel_nr = chan;
|
910
|
909
|
dev->channels[i].maxpower = txpower;
|
|
910
|
+ dev->channels[i].hw_value = 0;
|
911
|
911
|
|
912
|
912
|
if ( chan >= 1 && chan <= 14 ) {
|
913
|
913
|
dev->channels[i].band = NET80211_BAND_2GHZ;
|
|
@@ -926,6 +926,65 @@ static void net80211_add_channels ( struct net80211_device *dev, int start,
|
926
|
926
|
dev->nr_channels = i;
|
927
|
927
|
}
|
928
|
928
|
|
|
929
|
+/**
|
|
930
|
+ * Filter 802.11 device channels for hardware capabilities
|
|
931
|
+ *
|
|
932
|
+ * @v dev 802.11 device
|
|
933
|
+ *
|
|
934
|
+ * Hardware may support fewer channels than regulatory restrictions
|
|
935
|
+ * allow; this function filters out channels in dev->channels that are
|
|
936
|
+ * not supported by the hardware list in dev->hwinfo. It also copies
|
|
937
|
+ * over the net80211_channel::hw_value and limits maximum TX power
|
|
938
|
+ * appropriately.
|
|
939
|
+ *
|
|
940
|
+ * Channels are matched based on center frequency, ignoring band and
|
|
941
|
+ * channel number.
|
|
942
|
+ *
|
|
943
|
+ * If the driver specifies no supported channels, the effect will be
|
|
944
|
+ * as though all were supported.
|
|
945
|
+ */
|
|
946
|
+static void net80211_filter_hw_channels ( struct net80211_device *dev )
|
|
947
|
+{
|
|
948
|
+ int delta = 0, i = 0;
|
|
949
|
+ int old_freq = dev->channels[dev->channel].center_freq;
|
|
950
|
+ struct net80211_channel *chan, *hwchan;
|
|
951
|
+
|
|
952
|
+ if ( ! dev->hw->nr_channels )
|
|
953
|
+ return;
|
|
954
|
+
|
|
955
|
+ dev->channel = 0;
|
|
956
|
+ for ( chan = dev->channels; chan < dev->channels + dev->nr_channels;
|
|
957
|
+ chan++, i++ ) {
|
|
958
|
+ int ok = 0;
|
|
959
|
+ for ( hwchan = dev->hw->channels;
|
|
960
|
+ hwchan < dev->hw->channels + dev->hw->nr_channels;
|
|
961
|
+ hwchan++ ) {
|
|
962
|
+ if ( hwchan->center_freq == chan->center_freq ) {
|
|
963
|
+ ok = 1;
|
|
964
|
+ break;
|
|
965
|
+ }
|
|
966
|
+ }
|
|
967
|
+
|
|
968
|
+ if ( ! ok )
|
|
969
|
+ delta++;
|
|
970
|
+ else {
|
|
971
|
+ chan->hw_value = hwchan->hw_value;
|
|
972
|
+ if ( hwchan->maxpower != 0 &&
|
|
973
|
+ chan->maxpower > hwchan->maxpower )
|
|
974
|
+ chan->maxpower = hwchan->maxpower;
|
|
975
|
+ if ( old_freq == chan->center_freq )
|
|
976
|
+ dev->channel = i - delta;
|
|
977
|
+ if ( delta )
|
|
978
|
+ chan[-delta] = *chan;
|
|
979
|
+ }
|
|
980
|
+ }
|
|
981
|
+
|
|
982
|
+ dev->nr_channels -= delta;
|
|
983
|
+
|
|
984
|
+ if ( dev->channels[dev->channel].center_freq != old_freq )
|
|
985
|
+ dev->op->config ( dev, NET80211_CFG_CHANNEL );
|
|
986
|
+}
|
|
987
|
+
|
929
|
988
|
/**
|
930
|
989
|
* Update 802.11 device state to reflect received capabilities field
|
931
|
990
|
*
|
|
@@ -981,6 +1040,7 @@ static int net80211_process_ie ( struct net80211_device *dev,
|
981
|
1040
|
int have_rates = 0, i;
|
982
|
1041
|
int ds_channel = 0;
|
983
|
1042
|
int changed = 0;
|
|
1043
|
+ int band = dev->channels[dev->channel].band;
|
984
|
1044
|
|
985
|
1045
|
if ( ( void * ) ie >= ie_end )
|
986
|
1046
|
return 0;
|
|
@@ -1042,6 +1102,7 @@ static int net80211_process_ie ( struct net80211_device *dev,
|
1042
|
1102
|
t->band.max_txpower );
|
1043
|
1103
|
}
|
1044
|
1104
|
}
|
|
1105
|
+ net80211_filter_hw_channels ( dev );
|
1045
|
1106
|
break;
|
1046
|
1107
|
|
1047
|
1108
|
case IEEE80211_IE_ERP_INFO:
|
|
@@ -1067,9 +1128,8 @@ static int net80211_process_ie ( struct net80211_device *dev,
|
1067
|
1128
|
dev->rate = 0;
|
1068
|
1129
|
for ( i = 0; i < dev->nr_rates; i++ ) {
|
1069
|
1130
|
int ok = 0;
|
1070
|
|
- for ( j = 0; j < dev->hw->nr_supported_rates; j++ ) {
|
1071
|
|
- if ( dev->hw->supported_rates[j] ==
|
1072
|
|
- dev->rates[i] ) {
|
|
1131
|
+ for ( j = 0; j < dev->hw->nr_rates[band]; j++ ) {
|
|
1132
|
+ if ( dev->hw->rates[band][j] == dev->rates[i] ){
|
1073
|
1133
|
ok = 1;
|
1074
|
1134
|
break;
|
1075
|
1135
|
}
|
|
@@ -1597,7 +1657,7 @@ static void net80211_step_associate ( struct process *proc )
|
1597
|
1657
|
int band = dev->hw->bands;
|
1598
|
1658
|
|
1599
|
1659
|
if ( active )
|
1600
|
|
- band &= ~NET80211_BAND_5GHZ;
|
|
1660
|
+ band &= ~NET80211_BAND_BIT_5GHZ;
|
1601
|
1661
|
|
1602
|
1662
|
rc = net80211_prepare_probe ( dev, band, active );
|
1603
|
1663
|
if ( rc )
|
|
@@ -1916,7 +1976,7 @@ int net80211_prepare_probe ( struct net80211_device *dev, int band,
|
1916
|
1976
|
{
|
1917
|
1977
|
assert ( dev->netdev->state & NETDEV_OPEN );
|
1918
|
1978
|
|
1919
|
|
- if ( active && band != NET80211_BAND_2GHZ ) {
|
|
1979
|
+ if ( active && ( band & NET80211_BAND_BIT_5GHZ ) ) {
|
1920
|
1980
|
DBGC ( dev, "802.11 %p cannot perform active scanning on "
|
1921
|
1981
|
"5GHz band\n", dev );
|
1922
|
1982
|
return -EINVAL_ACTIVE_SCAN;
|
|
@@ -1935,22 +1995,24 @@ int net80211_prepare_probe ( struct net80211_device *dev, int band,
|
1935
|
1995
|
if ( active )
|
1936
|
1996
|
net80211_add_channels ( dev, 1, 11, NET80211_REG_TXPOWER );
|
1937
|
1997
|
else {
|
1938
|
|
- if ( band & NET80211_BAND_2GHZ )
|
|
1998
|
+ if ( band & NET80211_BAND_BIT_2GHZ )
|
1939
|
1999
|
net80211_add_channels ( dev, 1, 14,
|
1940
|
2000
|
NET80211_REG_TXPOWER );
|
1941
|
|
- if ( band & NET80211_BAND_5GHZ )
|
|
2001
|
+ if ( band & NET80211_BAND_BIT_5GHZ )
|
1942
|
2002
|
net80211_add_channels ( dev, 36, 8,
|
1943
|
2003
|
NET80211_REG_TXPOWER );
|
1944
|
2004
|
}
|
1945
|
2005
|
|
|
2006
|
+ net80211_filter_hw_channels ( dev );
|
|
2007
|
+
|
1946
|
2008
|
/* Use channel 1 for now */
|
1947
|
2009
|
dev->channel = 0;
|
1948
|
2010
|
dev->op->config ( dev, NET80211_CFG_CHANNEL );
|
1949
|
2011
|
|
1950
|
|
- /* Always do active probes at 1Mbps */
|
|
2012
|
+ /* Always do active probes at lowest (presumably first) speed */
|
1951
|
2013
|
dev->rate = 0;
|
1952
|
2014
|
dev->nr_rates = 1;
|
1953
|
|
- dev->rates[0] = 10;
|
|
2015
|
+ dev->rates[0] = dev->hw->rates[dev->channels[0].band][0];
|
1954
|
2016
|
dev->op->config ( dev, NET80211_CFG_RATE );
|
1955
|
2017
|
|
1956
|
2018
|
return 0;
|