diff options
Diffstat (limited to 'drivers/net/wireless')
-rw-r--r-- | drivers/net/wireless/wl12xx/main.c | 171 |
1 files changed, 93 insertions, 78 deletions
diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c index 194d7cc366de..3667acf0a031 100644 --- a/drivers/net/wireless/wl12xx/main.c +++ b/drivers/net/wireless/wl12xx/main.c | |||
@@ -1888,60 +1888,12 @@ static int wl12xx_init_vif_data(struct ieee80211_vif *vif) | |||
1888 | return 0; | 1888 | return 0; |
1889 | } | 1889 | } |
1890 | 1890 | ||
1891 | static int wl1271_op_add_interface(struct ieee80211_hw *hw, | 1891 | static bool wl12xx_init_fw(struct wl1271 *wl) |
1892 | struct ieee80211_vif *vif) | ||
1893 | { | 1892 | { |
1894 | struct wl1271 *wl = hw->priv; | ||
1895 | struct wiphy *wiphy = hw->wiphy; | ||
1896 | struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif); | ||
1897 | int retries = WL1271_BOOT_RETRIES; | 1893 | int retries = WL1271_BOOT_RETRIES; |
1898 | int ret = 0; | ||
1899 | u8 role_type; | ||
1900 | bool booted = false; | 1894 | bool booted = false; |
1901 | 1895 | struct wiphy *wiphy = wl->hw->wiphy; | |
1902 | wl1271_debug(DEBUG_MAC80211, "mac80211 add interface type %d mac %pM", | 1896 | int ret; |
1903 | ieee80211_vif_type_p2p(vif), vif->addr); | ||
1904 | |||
1905 | mutex_lock(&wl->mutex); | ||
1906 | if (wl->vif) { | ||
1907 | wl1271_debug(DEBUG_MAC80211, | ||
1908 | "multiple vifs are not supported yet"); | ||
1909 | ret = -EBUSY; | ||
1910 | goto out; | ||
1911 | } | ||
1912 | |||
1913 | /* | ||
1914 | * in some very corner case HW recovery scenarios its possible to | ||
1915 | * get here before __wl1271_op_remove_interface is complete, so | ||
1916 | * opt out if that is the case. | ||
1917 | */ | ||
1918 | if (test_bit(WL1271_FLAG_IF_INITIALIZED, &wl->flags)) { | ||
1919 | ret = -EBUSY; | ||
1920 | goto out; | ||
1921 | } | ||
1922 | |||
1923 | ret = wl12xx_init_vif_data(vif); | ||
1924 | if (ret < 0) | ||
1925 | goto out; | ||
1926 | |||
1927 | wlvif->wl = wl; | ||
1928 | role_type = wl12xx_get_role_type(wl, wlvif); | ||
1929 | if (role_type == WL12XX_INVALID_ROLE_TYPE) { | ||
1930 | ret = -EINVAL; | ||
1931 | goto out; | ||
1932 | } | ||
1933 | /* | ||
1934 | * we still need this in order to configure the fw | ||
1935 | * while uploading the nvs | ||
1936 | */ | ||
1937 | memcpy(wl->mac_addr, vif->addr, ETH_ALEN); | ||
1938 | |||
1939 | if (wl->state != WL1271_STATE_OFF) { | ||
1940 | wl1271_error("cannot start because not in off state: %d", | ||
1941 | wl->state); | ||
1942 | ret = -EBUSY; | ||
1943 | goto out; | ||
1944 | } | ||
1945 | 1897 | ||
1946 | while (retries) { | 1898 | while (retries) { |
1947 | retries--; | 1899 | retries--; |
@@ -1957,30 +1909,6 @@ static int wl1271_op_add_interface(struct ieee80211_hw *hw, | |||
1957 | if (ret < 0) | 1909 | if (ret < 0) |
1958 | goto irq_disable; | 1910 | goto irq_disable; |
1959 | 1911 | ||
1960 | if (wlvif->bss_type == BSS_TYPE_STA_BSS || | ||
1961 | wlvif->bss_type == BSS_TYPE_IBSS) { | ||
1962 | /* | ||
1963 | * The device role is a special role used for | ||
1964 | * rx and tx frames prior to association (as | ||
1965 | * the STA role can get packets only from | ||
1966 | * its associated bssid) | ||
1967 | */ | ||
1968 | ret = wl12xx_cmd_role_enable(wl, vif->addr, | ||
1969 | WL1271_ROLE_DEVICE, | ||
1970 | &wlvif->dev_role_id); | ||
1971 | if (ret < 0) | ||
1972 | goto irq_disable; | ||
1973 | } | ||
1974 | |||
1975 | ret = wl12xx_cmd_role_enable(wl, vif->addr, | ||
1976 | role_type, &wlvif->role_id); | ||
1977 | if (ret < 0) | ||
1978 | goto irq_disable; | ||
1979 | |||
1980 | ret = wl1271_init_vif_specific(wl, vif); | ||
1981 | if (ret < 0) | ||
1982 | goto irq_disable; | ||
1983 | |||
1984 | booted = true; | 1912 | booted = true; |
1985 | break; | 1913 | break; |
1986 | 1914 | ||
@@ -2007,9 +1935,6 @@ power_off: | |||
2007 | goto out; | 1935 | goto out; |
2008 | } | 1936 | } |
2009 | 1937 | ||
2010 | wl->vif = vif; | ||
2011 | wl->state = WL1271_STATE_ON; | ||
2012 | set_bit(WL1271_FLAG_IF_INITIALIZED, &wl->flags); | ||
2013 | wl1271_info("firmware booted (%s)", wl->chip.fw_ver_str); | 1938 | wl1271_info("firmware booted (%s)", wl->chip.fw_ver_str); |
2014 | 1939 | ||
2015 | /* update hw/fw version info in wiphy struct */ | 1940 | /* update hw/fw version info in wiphy struct */ |
@@ -2027,6 +1952,96 @@ power_off: | |||
2027 | wl1271_debug(DEBUG_MAC80211, "11a is %ssupported", | 1952 | wl1271_debug(DEBUG_MAC80211, "11a is %ssupported", |
2028 | wl->enable_11a ? "" : "not "); | 1953 | wl->enable_11a ? "" : "not "); |
2029 | 1954 | ||
1955 | wl->state = WL1271_STATE_ON; | ||
1956 | out: | ||
1957 | return booted; | ||
1958 | } | ||
1959 | |||
1960 | static int wl1271_op_add_interface(struct ieee80211_hw *hw, | ||
1961 | struct ieee80211_vif *vif) | ||
1962 | { | ||
1963 | struct wl1271 *wl = hw->priv; | ||
1964 | struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif); | ||
1965 | int ret = 0; | ||
1966 | u8 role_type; | ||
1967 | bool booted = false; | ||
1968 | |||
1969 | wl1271_debug(DEBUG_MAC80211, "mac80211 add interface type %d mac %pM", | ||
1970 | ieee80211_vif_type_p2p(vif), vif->addr); | ||
1971 | |||
1972 | mutex_lock(&wl->mutex); | ||
1973 | if (wl->vif) { | ||
1974 | wl1271_debug(DEBUG_MAC80211, | ||
1975 | "multiple vifs are not supported yet"); | ||
1976 | ret = -EBUSY; | ||
1977 | goto out; | ||
1978 | } | ||
1979 | |||
1980 | /* | ||
1981 | * in some very corner case HW recovery scenarios its possible to | ||
1982 | * get here before __wl1271_op_remove_interface is complete, so | ||
1983 | * opt out if that is the case. | ||
1984 | */ | ||
1985 | if (test_bit(WL1271_FLAG_IF_INITIALIZED, &wl->flags)) { | ||
1986 | ret = -EBUSY; | ||
1987 | goto out; | ||
1988 | } | ||
1989 | |||
1990 | ret = wl12xx_init_vif_data(vif); | ||
1991 | if (ret < 0) | ||
1992 | goto out; | ||
1993 | |||
1994 | wlvif->wl = wl; | ||
1995 | role_type = wl12xx_get_role_type(wl, wlvif); | ||
1996 | if (role_type == WL12XX_INVALID_ROLE_TYPE) { | ||
1997 | ret = -EINVAL; | ||
1998 | goto out; | ||
1999 | } | ||
2000 | |||
2001 | /* | ||
2002 | * TODO: after the nvs issue will be solved, move this block | ||
2003 | * to start(), and make sure here the driver is ON. | ||
2004 | */ | ||
2005 | if (wl->state == WL1271_STATE_OFF) { | ||
2006 | /* | ||
2007 | * we still need this in order to configure the fw | ||
2008 | * while uploading the nvs | ||
2009 | */ | ||
2010 | memcpy(wl->mac_addr, vif->addr, ETH_ALEN); | ||
2011 | |||
2012 | booted = wl12xx_init_fw(wl); | ||
2013 | if (!booted) { | ||
2014 | ret = -EINVAL; | ||
2015 | goto out; | ||
2016 | } | ||
2017 | } | ||
2018 | |||
2019 | if (wlvif->bss_type == BSS_TYPE_STA_BSS || | ||
2020 | wlvif->bss_type == BSS_TYPE_IBSS) { | ||
2021 | /* | ||
2022 | * The device role is a special role used for | ||
2023 | * rx and tx frames prior to association (as | ||
2024 | * the STA role can get packets only from | ||
2025 | * its associated bssid) | ||
2026 | */ | ||
2027 | ret = wl12xx_cmd_role_enable(wl, vif->addr, | ||
2028 | WL1271_ROLE_DEVICE, | ||
2029 | &wlvif->dev_role_id); | ||
2030 | if (ret < 0) | ||
2031 | goto out; | ||
2032 | } | ||
2033 | |||
2034 | ret = wl12xx_cmd_role_enable(wl, vif->addr, | ||
2035 | role_type, &wlvif->role_id); | ||
2036 | if (ret < 0) | ||
2037 | goto out; | ||
2038 | |||
2039 | ret = wl1271_init_vif_specific(wl, vif); | ||
2040 | if (ret < 0) | ||
2041 | goto out; | ||
2042 | |||
2043 | wl->vif = vif; | ||
2044 | set_bit(WL1271_FLAG_IF_INITIALIZED, &wl->flags); | ||
2030 | out: | 2045 | out: |
2031 | mutex_unlock(&wl->mutex); | 2046 | mutex_unlock(&wl->mutex); |
2032 | 2047 | ||