--- linux/net/ieee80211/softmac/ieee80211softmac_module.c.orig 2006-04-17 01:04:42.000000000 +0100 +++ linux/net/ieee80211/softmac/ieee80211softmac_module.c 2006-04-17 00:44:36.000000000 +0100 @@ -26,6 +26,7 @@ #include "ieee80211softmac_priv.h" #include +#include struct net_device *alloc_ieee80211softmac(int sizeof_priv) { @@ -315,6 +316,48 @@ static int rate_cmp(const void *a_, cons return ((*a & ~IEEE80211_BASIC_RATE_MASK) - (*b & ~IEEE80211_BASIC_RATE_MASK)); } +static u8 suggest_rate_from_associnfo(struct ieee80211softmac_device *mac) +{ + struct ieee80211softmac_ratesinfo *net_rates = &mac->associnfo.supported_rates; + u8 net_max; + + if (unlikely(net_rates->count == 0)) { + dprintkl(KERN_ERROR PFX "suggest_rate: Network has no rates?\n"); + return IEEE80211_CCK_RATE_1MB; + } + + /* FIXME: we need to check that the rate is supported in mac->ratesinfo */ + net_max = net_rates->rates[net_rates->count - 1]; + return min(mac->txrates.default_rate, net_max); +} + +u8 ieee80211softmac_suggest_tx_rate(struct ieee80211softmac_device *mac, + struct ieee80211_hdr_1addr *hdr) +{ + switch (WLAN_FC_GET_TYPE(le16_to_cpu(hdr->frame_ctl))) { + case IEEE80211_FTYPE_MGMT: + /* + * If we aren't associated, or we are multicasting, then + * stick to 1MB for safety. + */ + if (!mac->associated || is_multicast_ether_addr(hdr->addr1)) + return IEEE80211_CCK_RATE_1MB; + + /* Otherwise, we can send at the speed of the AP. */ + return suggest_rate_from_associnfo(mac); + case IEEE80211_FTYPE_DATA: + if (unlikely(!mac->associated)) { + dprintkl(KERN_ERROR PFX "suggest_tx_rate: Not associated\n"); + return IEEE80211_CCK_RATE_1MB; + } + return suggest_rate_from_associnfo(mac); + default: + dprintkl(KERN_ERROR PFX "suggest_tx_rate: Unhandled ftype %x\n", ftype); + return IEEE80211_CCK_RATE_1MB; + } +} +EXPORT_SYMBOL_GPL(ieee80211softmac_suggest_tx_rate); + /* Allocate a softmac network struct and fill it from a network */ struct ieee80211softmac_network * ieee80211softmac_create_network(struct ieee80211softmac_device *mac, --- linux/net/ieee80211/softmac/ieee80211softmac_assoc.c.orig 2006-04-16 23:55:23.000000000 +0100 +++ linux/net/ieee80211/softmac/ieee80211softmac_assoc.c 2006-04-16 23:55:39.000000000 +0100 @@ -283,6 +283,7 @@ ieee80211softmac_associated(struct ieee8 struct ieee80211softmac_network *net) { mac->associnfo.associating = 0; + mac->associnfo.supported_rates = net->supported_rates; mac->associated = 1; if (mac->set_bssid_filter) mac->set_bssid_filter(mac->dev, net->bssid); --- linux/include/net/ieee80211softmac.h.orig 2006-04-16 23:37:32.000000000 +0100 +++ linux/include/net/ieee80211softmac.h 2006-04-17 00:44:47.000000000 +0100 @@ -86,6 +86,9 @@ struct ieee80211softmac_assoc_info { /* BSSID we're trying to associate to */ char bssid[ETH_ALEN]; + + /* Rates supported by the network */ + struct ieee80211softmac_ratesinfo supported_rates; /* some flags. * static_essid is valid if the essid is constant, @@ -246,6 +249,8 @@ extern void ieee80211softmac_fragment_lo * Note that the rates need to be sorted. */ extern void ieee80211softmac_set_rates(struct net_device *dev, u8 count, u8 *rates); +extern u8 ieee80211softmac_suggest_tx_rate(struct ieee80211softmac_device *mac, struct ieee80211_hdr_1addr *hdr); + /* Start the SoftMAC. Call this after you initialized the device * and it is ready to run. */