]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - net/wireless/util.c
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound-2.6
[karo-tx-linux.git] / net / wireless / util.c
index 8d961cc4ae98f333002a12f121613802b03d95de..76120aeda57d3ed311c338cb7e54196000cc937d 100644 (file)
@@ -144,19 +144,25 @@ void ieee80211_set_bitrate_flags(struct wiphy *wiphy)
 
 int cfg80211_validate_key_settings(struct cfg80211_registered_device *rdev,
                                   struct key_params *params, int key_idx,
-                                  const u8 *mac_addr)
+                                  bool pairwise, const u8 *mac_addr)
 {
        int i;
 
        if (key_idx > 5)
                return -EINVAL;
 
+       if (!pairwise && mac_addr && !(rdev->wiphy.flags & WIPHY_FLAG_IBSS_RSN))
+               return -EINVAL;
+
+       if (pairwise && !mac_addr)
+               return -EINVAL;
+
        /*
         * Disallow pairwise keys with non-zero index unless it's WEP
         * (because current deployments use pairwise WEP keys with
         * non-zero indizes but 802.11i clearly specifies to use zero)
         */
-       if (mac_addr && key_idx &&
+       if (pairwise && key_idx &&
            params->cipher != WLAN_CIPHER_SUITE_WEP40 &&
            params->cipher != WLAN_CIPHER_SUITE_WEP104)
                return -EINVAL;
@@ -183,7 +189,14 @@ int cfg80211_validate_key_settings(struct cfg80211_registered_device *rdev,
                        return -EINVAL;
                break;
        default:
-               return -EINVAL;
+               /*
+                * We don't know anything about this algorithm,
+                * allow using it -- but the driver must check
+                * all parameters! We still check below whether
+                * or not the driver supports this algorithm,
+                * of course.
+                */
+               break;
        }
 
        if (params->seq) {
@@ -319,7 +332,8 @@ int ieee80211_data_to_8023(struct sk_buff *skb, const u8 *addr,
                cpu_to_le16(IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) {
        case cpu_to_le16(IEEE80211_FCTL_TODS):
                if (unlikely(iftype != NL80211_IFTYPE_AP &&
-                            iftype != NL80211_IFTYPE_AP_VLAN))
+                            iftype != NL80211_IFTYPE_AP_VLAN &&
+                            iftype != NL80211_IFTYPE_P2P_GO))
                        return -1;
                break;
        case cpu_to_le16(IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS):
@@ -347,7 +361,8 @@ int ieee80211_data_to_8023(struct sk_buff *skb, const u8 *addr,
                break;
        case cpu_to_le16(IEEE80211_FCTL_FROMDS):
                if ((iftype != NL80211_IFTYPE_STATION &&
-                   iftype != NL80211_IFTYPE_MESH_POINT) ||
+                    iftype != NL80211_IFTYPE_P2P_CLIENT &&
+                    iftype != NL80211_IFTYPE_MESH_POINT) ||
                    (is_multicast_ether_addr(dst) &&
                     !compare_ether_addr(src, addr)))
                        return -1;
@@ -424,6 +439,7 @@ int ieee80211_data_from_8023(struct sk_buff *skb, const u8 *addr,
        switch (iftype) {
        case NL80211_IFTYPE_AP:
        case NL80211_IFTYPE_AP_VLAN:
+       case NL80211_IFTYPE_P2P_GO:
                fc |= cpu_to_le16(IEEE80211_FCTL_FROMDS);
                /* DA BSSID SA */
                memcpy(hdr.addr1, skb->data, ETH_ALEN);
@@ -432,6 +448,7 @@ int ieee80211_data_from_8023(struct sk_buff *skb, const u8 *addr,
                hdrlen = 24;
                break;
        case NL80211_IFTYPE_STATION:
+       case NL80211_IFTYPE_P2P_CLIENT:
                fc |= cpu_to_le16(IEEE80211_FCTL_TODS);
                /* BSSID SA DA */
                memcpy(hdr.addr1, bssid, ETH_ALEN);
@@ -666,7 +683,7 @@ void cfg80211_upload_connect_keys(struct wireless_dev *wdev)
        for (i = 0; i < 6; i++) {
                if (!wdev->connect_keys->params[i].cipher)
                        continue;
-               if (rdev->ops->add_key(wdev->wiphy, dev, i, NULL,
+               if (rdev->ops->add_key(wdev->wiphy, dev, i, false, NULL,
                                        &wdev->connect_keys->params[i])) {
                        printk(KERN_ERR "%s: failed to set key %d\n",
                                dev->name, i);
@@ -771,7 +788,9 @@ int cfg80211_change_iface(struct cfg80211_registered_device *rdev,
 
        /* if it's part of a bridge, reject changing type to station/ibss */
        if ((dev->priv_flags & IFF_BRIDGE_PORT) &&
-           (ntype == NL80211_IFTYPE_ADHOC || ntype == NL80211_IFTYPE_STATION))
+           (ntype == NL80211_IFTYPE_ADHOC ||
+            ntype == NL80211_IFTYPE_STATION ||
+            ntype == NL80211_IFTYPE_P2P_CLIENT))
                return -EBUSY;
 
        if (ntype != otype) {
@@ -782,6 +801,7 @@ int cfg80211_change_iface(struct cfg80211_registered_device *rdev,
                        cfg80211_leave_ibss(rdev, dev, false);
                        break;
                case NL80211_IFTYPE_STATION:
+               case NL80211_IFTYPE_P2P_CLIENT:
                        cfg80211_disconnect(rdev, dev,
                                            WLAN_REASON_DEAUTH_LEAVING, true);
                        break;
@@ -810,9 +830,11 @@ int cfg80211_change_iface(struct cfg80211_registered_device *rdev,
                        if (dev->ieee80211_ptr->use_4addr)
                                break;
                        /* fall through */
+               case NL80211_IFTYPE_P2P_CLIENT:
                case NL80211_IFTYPE_ADHOC:
                        dev->priv_flags |= IFF_DONT_BRIDGE;
                        break;
+               case NL80211_IFTYPE_P2P_GO:
                case NL80211_IFTYPE_AP:
                case NL80211_IFTYPE_AP_VLAN:
                case NL80211_IFTYPE_WDS: