if_iwm.c (9a6695532b3997e4e2bc3fe57481cc49be5e9e93) | if_iwm.c (355c15130aef13484821051a655da9b9066e1015) |
---|---|
1/* $OpenBSD: if_iwm.c,v 1.167 2017/04/04 00:40:52 claudio Exp $ */ 2 3/* 4 * Copyright (c) 2014 genua mbh <info@genua.de> 5 * Copyright (c) 2014 Fixup Software Ltd. 6 * 7 * Permission to use, copy, modify, and distribute this software for any 8 * purpose with or without fee is hereby granted, provided that the above --- 1900 unchanged lines hidden (view full) --- 1909} 1910 1911/* 1912 * BEGIN IWM_NVM_PARSE 1913 */ 1914 1915/* iwlwifi/iwl-nvm-parse.c */ 1916 | 1/* $OpenBSD: if_iwm.c,v 1.167 2017/04/04 00:40:52 claudio Exp $ */ 2 3/* 4 * Copyright (c) 2014 genua mbh <info@genua.de> 5 * Copyright (c) 2014 Fixup Software Ltd. 6 * 7 * Permission to use, copy, modify, and distribute this software for any 8 * purpose with or without fee is hereby granted, provided that the above --- 1900 unchanged lines hidden (view full) --- 1909} 1910 1911/* 1912 * BEGIN IWM_NVM_PARSE 1913 */ 1914 1915/* iwlwifi/iwl-nvm-parse.c */ 1916 |
1917/* NVM offsets (in words) definitions */ 1918enum iwm_nvm_offsets { 1919 /* NVM HW-Section offset (in words) definitions */ 1920 IWM_HW_ADDR = 0x15, 1921 1922/* NVM SW-Section offset (in words) definitions */ 1923 IWM_NVM_SW_SECTION = 0x1C0, 1924 IWM_NVM_VERSION = 0, 1925 IWM_RADIO_CFG = 1, 1926 IWM_SKU = 2, 1927 IWM_N_HW_ADDRS = 3, 1928 IWM_NVM_CHANNELS = 0x1E0 - IWM_NVM_SW_SECTION, 1929 1930/* NVM calibration section offset (in words) definitions */ 1931 IWM_NVM_CALIB_SECTION = 0x2B8, 1932 IWM_XTAL_CALIB = 0x316 - IWM_NVM_CALIB_SECTION 1933}; 1934 1935enum iwm_8000_nvm_offsets { 1936 /* NVM HW-Section offset (in words) definitions */ 1937 IWM_HW_ADDR0_WFPM_8000 = 0x12, 1938 IWM_HW_ADDR1_WFPM_8000 = 0x16, 1939 IWM_HW_ADDR0_PCIE_8000 = 0x8A, 1940 IWM_HW_ADDR1_PCIE_8000 = 0x8E, 1941 IWM_MAC_ADDRESS_OVERRIDE_8000 = 1, 1942 1943 /* NVM SW-Section offset (in words) definitions */ 1944 IWM_NVM_SW_SECTION_8000 = 0x1C0, 1945 IWM_NVM_VERSION_8000 = 0, 1946 IWM_RADIO_CFG_8000 = 0, 1947 IWM_SKU_8000 = 2, 1948 IWM_N_HW_ADDRS_8000 = 3, 1949 1950 /* NVM REGULATORY -Section offset (in words) definitions */ 1951 IWM_NVM_CHANNELS_8000 = 0, 1952 IWM_NVM_LAR_OFFSET_8000_OLD = 0x4C7, 1953 IWM_NVM_LAR_OFFSET_8000 = 0x507, 1954 IWM_NVM_LAR_ENABLED_8000 = 0x7, 1955 1956 /* NVM calibration section offset (in words) definitions */ 1957 IWM_NVM_CALIB_SECTION_8000 = 0x2B8, 1958 IWM_XTAL_CALIB_8000 = 0x316 - IWM_NVM_CALIB_SECTION_8000 1959}; 1960 1961/* SKU Capabilities (actual values from NVM definition) */ 1962enum nvm_sku_bits { 1963 IWM_NVM_SKU_CAP_BAND_24GHZ = (1 << 0), 1964 IWM_NVM_SKU_CAP_BAND_52GHZ = (1 << 1), 1965 IWM_NVM_SKU_CAP_11N_ENABLE = (1 << 2), 1966 IWM_NVM_SKU_CAP_11AC_ENABLE = (1 << 3), 1967}; 1968 1969/* radio config bits (actual values from NVM definition) */ 1970#define IWM_NVM_RF_CFG_DASH_MSK(x) (x & 0x3) /* bits 0-1 */ 1971#define IWM_NVM_RF_CFG_STEP_MSK(x) ((x >> 2) & 0x3) /* bits 2-3 */ 1972#define IWM_NVM_RF_CFG_TYPE_MSK(x) ((x >> 4) & 0x3) /* bits 4-5 */ 1973#define IWM_NVM_RF_CFG_PNUM_MSK(x) ((x >> 6) & 0x3) /* bits 6-7 */ 1974#define IWM_NVM_RF_CFG_TX_ANT_MSK(x) ((x >> 8) & 0xF) /* bits 8-11 */ 1975#define IWM_NVM_RF_CFG_RX_ANT_MSK(x) ((x >> 12) & 0xF) /* bits 12-15 */ 1976 1977#define IWM_NVM_RF_CFG_FLAVOR_MSK_8000(x) (x & 0xF) 1978#define IWM_NVM_RF_CFG_DASH_MSK_8000(x) ((x >> 4) & 0xF) 1979#define IWM_NVM_RF_CFG_STEP_MSK_8000(x) ((x >> 8) & 0xF) 1980#define IWM_NVM_RF_CFG_TYPE_MSK_8000(x) ((x >> 12) & 0xFFF) 1981#define IWM_NVM_RF_CFG_TX_ANT_MSK_8000(x) ((x >> 24) & 0xF) 1982#define IWM_NVM_RF_CFG_RX_ANT_MSK_8000(x) ((x >> 28) & 0xF) 1983 1984/** 1985 * enum iwm_nvm_channel_flags - channel flags in NVM 1986 * @IWM_NVM_CHANNEL_VALID: channel is usable for this SKU/geo 1987 * @IWM_NVM_CHANNEL_IBSS: usable as an IBSS channel 1988 * @IWM_NVM_CHANNEL_ACTIVE: active scanning allowed 1989 * @IWM_NVM_CHANNEL_RADAR: radar detection required 1990 * XXX cannot find this (DFS) flag in iwm-nvm-parse.c 1991 * @IWM_NVM_CHANNEL_DFS: dynamic freq selection candidate 1992 * @IWM_NVM_CHANNEL_WIDE: 20 MHz channel okay (?) 1993 * @IWM_NVM_CHANNEL_40MHZ: 40 MHz channel okay (?) 1994 * @IWM_NVM_CHANNEL_80MHZ: 80 MHz channel okay (?) 1995 * @IWM_NVM_CHANNEL_160MHZ: 160 MHz channel okay (?) 1996 */ 1997enum iwm_nvm_channel_flags { 1998 IWM_NVM_CHANNEL_VALID = (1 << 0), 1999 IWM_NVM_CHANNEL_IBSS = (1 << 1), 2000 IWM_NVM_CHANNEL_ACTIVE = (1 << 3), 2001 IWM_NVM_CHANNEL_RADAR = (1 << 4), 2002 IWM_NVM_CHANNEL_DFS = (1 << 7), 2003 IWM_NVM_CHANNEL_WIDE = (1 << 8), 2004 IWM_NVM_CHANNEL_40MHZ = (1 << 9), 2005 IWM_NVM_CHANNEL_80MHZ = (1 << 10), 2006 IWM_NVM_CHANNEL_160MHZ = (1 << 11), 2007}; 2008 | |
2009/* 2010 * Translate EEPROM flags to net80211. 2011 */ 2012static uint32_t 2013iwm_eeprom_channel_flags(uint16_t ch_flags) 2014{ 2015 uint32_t nflags; 2016 --- 198 unchanged lines hidden (view full) --- 2215 data->radio_cfg_pnum = IWM_NVM_RF_CFG_PNUM_MSK(radio_cfg); 2216 return; 2217 } 2218 2219 /* set the radio configuration for family 8000 */ 2220 data->radio_cfg_type = IWM_NVM_RF_CFG_TYPE_MSK_8000(radio_cfg); 2221 data->radio_cfg_step = IWM_NVM_RF_CFG_STEP_MSK_8000(radio_cfg); 2222 data->radio_cfg_dash = IWM_NVM_RF_CFG_DASH_MSK_8000(radio_cfg); | 1917/* 1918 * Translate EEPROM flags to net80211. 1919 */ 1920static uint32_t 1921iwm_eeprom_channel_flags(uint16_t ch_flags) 1922{ 1923 uint32_t nflags; 1924 --- 198 unchanged lines hidden (view full) --- 2123 data->radio_cfg_pnum = IWM_NVM_RF_CFG_PNUM_MSK(radio_cfg); 2124 return; 2125 } 2126 2127 /* set the radio configuration for family 8000 */ 2128 data->radio_cfg_type = IWM_NVM_RF_CFG_TYPE_MSK_8000(radio_cfg); 2129 data->radio_cfg_step = IWM_NVM_RF_CFG_STEP_MSK_8000(radio_cfg); 2130 data->radio_cfg_dash = IWM_NVM_RF_CFG_DASH_MSK_8000(radio_cfg); |
2223 data->radio_cfg_pnum = IWM_NVM_RF_CFG_FLAVOR_MSK_8000(radio_cfg); | 2131 data->radio_cfg_pnum = IWM_NVM_RF_CFG_PNUM_MSK_8000(radio_cfg); |
2224 data->valid_tx_ant = IWM_NVM_RF_CFG_TX_ANT_MSK_8000(radio_cfg); 2225 data->valid_rx_ant = IWM_NVM_RF_CFG_RX_ANT_MSK_8000(radio_cfg); 2226} 2227 2228static int 2229iwm_set_hw_address(struct iwm_softc *sc, struct iwm_nvm_data *data, 2230 const uint16_t *nvm_hw, const uint16_t *mac_override) 2231{ --- 146 unchanged lines hidden (view full) --- 2378 2379 return iwm_parse_nvm_data(sc, hw, sw, calib, mac_override, 2380 phy_sku, regulatory); 2381} 2382 2383static int 2384iwm_nvm_init(struct iwm_softc *sc) 2385{ | 2132 data->valid_tx_ant = IWM_NVM_RF_CFG_TX_ANT_MSK_8000(radio_cfg); 2133 data->valid_rx_ant = IWM_NVM_RF_CFG_RX_ANT_MSK_8000(radio_cfg); 2134} 2135 2136static int 2137iwm_set_hw_address(struct iwm_softc *sc, struct iwm_nvm_data *data, 2138 const uint16_t *nvm_hw, const uint16_t *mac_override) 2139{ --- 146 unchanged lines hidden (view full) --- 2286 2287 return iwm_parse_nvm_data(sc, hw, sw, calib, mac_override, 2288 phy_sku, regulatory); 2289} 2290 2291static int 2292iwm_nvm_init(struct iwm_softc *sc) 2293{ |
2386 struct iwm_nvm_section nvm_sections[IWM_NVM_MAX_NUM_SECTIONS]; | 2294 struct iwm_nvm_section nvm_sections[IWM_NVM_NUM_OF_SECTIONS]; |
2387 int i, ret, section; 2388 uint32_t size_read = 0; 2389 uint8_t *nvm_buffer, *temp; 2390 uint16_t len; 2391 2392 memset(nvm_sections, 0, sizeof(nvm_sections)); 2393 | 2295 int i, ret, section; 2296 uint32_t size_read = 0; 2297 uint8_t *nvm_buffer, *temp; 2298 uint16_t len; 2299 2300 memset(nvm_sections, 0, sizeof(nvm_sections)); 2301 |
2394 if (sc->cfg->nvm_hw_section_num >= IWM_NVM_MAX_NUM_SECTIONS) | 2302 if (sc->cfg->nvm_hw_section_num >= IWM_NVM_NUM_OF_SECTIONS) |
2395 return EINVAL; 2396 2397 /* load NVM values from nic */ 2398 /* Read From FW NVM */ 2399 IWM_DPRINTF(sc, IWM_DEBUG_EEPROM, "Read from NVM\n"); 2400 2401 nvm_buffer = malloc(sc->cfg->eeprom_size, M_DEVBUF, M_NOWAIT | M_ZERO); 2402 if (!nvm_buffer) 2403 return ENOMEM; | 2303 return EINVAL; 2304 2305 /* load NVM values from nic */ 2306 /* Read From FW NVM */ 2307 IWM_DPRINTF(sc, IWM_DEBUG_EEPROM, "Read from NVM\n"); 2308 2309 nvm_buffer = malloc(sc->cfg->eeprom_size, M_DEVBUF, M_NOWAIT | M_ZERO); 2310 if (!nvm_buffer) 2311 return ENOMEM; |
2404 for (section = 0; section < IWM_NVM_MAX_NUM_SECTIONS; section++) { | 2312 for (section = 0; section < IWM_NVM_NUM_OF_SECTIONS; section++) { |
2405 /* we override the constness for initial read */ 2406 ret = iwm_nvm_read_section(sc, section, nvm_buffer, 2407 &len, size_read); 2408 if (ret) 2409 continue; 2410 size_read += len; 2411 temp = malloc(len, M_DEVBUF, M_NOWAIT); 2412 if (!temp) { --- 10 unchanged lines hidden (view full) --- 2423 free(nvm_buffer, M_DEVBUF); 2424 2425 sc->nvm_data = iwm_parse_nvm_sections(sc, nvm_sections); 2426 if (!sc->nvm_data) 2427 return EINVAL; 2428 IWM_DPRINTF(sc, IWM_DEBUG_EEPROM | IWM_DEBUG_RESET, 2429 "nvm version = %x\n", sc->nvm_data->nvm_version); 2430 | 2313 /* we override the constness for initial read */ 2314 ret = iwm_nvm_read_section(sc, section, nvm_buffer, 2315 &len, size_read); 2316 if (ret) 2317 continue; 2318 size_read += len; 2319 temp = malloc(len, M_DEVBUF, M_NOWAIT); 2320 if (!temp) { --- 10 unchanged lines hidden (view full) --- 2331 free(nvm_buffer, M_DEVBUF); 2332 2333 sc->nvm_data = iwm_parse_nvm_sections(sc, nvm_sections); 2334 if (!sc->nvm_data) 2335 return EINVAL; 2336 IWM_DPRINTF(sc, IWM_DEBUG_EEPROM | IWM_DEBUG_RESET, 2337 "nvm version = %x\n", sc->nvm_data->nvm_version); 2338 |
2431 for (i = 0; i < IWM_NVM_MAX_NUM_SECTIONS; i++) { | 2339 for (i = 0; i < IWM_NVM_NUM_OF_SECTIONS; i++) { |
2432 if (nvm_sections[i].data != NULL) 2433 free(nvm_sections[i].data, M_DEVBUF); 2434 } 2435 2436 return 0; 2437} 2438 2439static int --- 736 unchanged lines hidden (view full) --- 3176 /* For now, just hard-code it to -96 to be safe */ 3177 return (-96); 3178#endif 3179} 3180 3181static void 3182iwm_handle_rx_statistics(struct iwm_softc *sc, struct iwm_rx_packet *pkt) 3183{ | 2340 if (nvm_sections[i].data != NULL) 2341 free(nvm_sections[i].data, M_DEVBUF); 2342 } 2343 2344 return 0; 2345} 2346 2347static int --- 736 unchanged lines hidden (view full) --- 3084 /* For now, just hard-code it to -96 to be safe */ 3085 return (-96); 3086#endif 3087} 3088 3089static void 3090iwm_handle_rx_statistics(struct iwm_softc *sc, struct iwm_rx_packet *pkt) 3091{ |
3184 struct iwm_notif_statistics_v10 *stats = (void *)&pkt->data; | 3092 struct iwm_notif_statistics *stats = (void *)&pkt->data; |
3185 3186 memcpy(&sc->sc_stats, stats, sizeof(sc->sc_stats)); 3187 sc->sc_noise = iwm_get_noise(sc, &stats->rx.general); 3188} 3189 3190/* iwlwifi: mvm/rx.c */ 3191/* 3192 * iwm_get_signal_strength - use new rx PHY INFO API --- 699 unchanged lines hidden (view full) --- 3892 } 3893 } else { 3894 tx->pm_frame_timeout = htole16(IWM_PM_FRAME_NONE); 3895 } 3896 3897 if (hdrlen & 3) { 3898 /* First segment length must be a multiple of 4. */ 3899 flags |= IWM_TX_CMD_FLG_MH_PAD; | 3093 3094 memcpy(&sc->sc_stats, stats, sizeof(sc->sc_stats)); 3095 sc->sc_noise = iwm_get_noise(sc, &stats->rx.general); 3096} 3097 3098/* iwlwifi: mvm/rx.c */ 3099/* 3100 * iwm_get_signal_strength - use new rx PHY INFO API --- 699 unchanged lines hidden (view full) --- 3800 } 3801 } else { 3802 tx->pm_frame_timeout = htole16(IWM_PM_FRAME_NONE); 3803 } 3804 3805 if (hdrlen & 3) { 3806 /* First segment length must be a multiple of 4. */ 3807 flags |= IWM_TX_CMD_FLG_MH_PAD; |
3900 tx->offload_assist |= htole16(1 << IWM_TX_CMD_OFFLD_PAD); | 3808 tx->offload_assist |= htole16(IWM_TX_CMD_OFFLD_PAD); |
3901 pad = 4 - (hdrlen & 3); 3902 } else { 3903 tx->offload_assist = 0; 3904 pad = 0; 3905 } 3906 3907 tx->len = htole16(totlen); 3908 tx->tid_tspec = tid; --- 145 unchanged lines hidden (view full) --- 4054 * 1) set the station as draining 4055 * 2) flush the Tx path 4056 * 3) wait for the transport queues to be empty 4057 */ 4058int 4059iwm_flush_tx_path(struct iwm_softc *sc, uint32_t tfd_msk, uint32_t flags) 4060{ 4061 int ret; | 3809 pad = 4 - (hdrlen & 3); 3810 } else { 3811 tx->offload_assist = 0; 3812 pad = 0; 3813 } 3814 3815 tx->len = htole16(totlen); 3816 tx->tid_tspec = tid; --- 145 unchanged lines hidden (view full) --- 3962 * 1) set the station as draining 3963 * 2) flush the Tx path 3964 * 3) wait for the transport queues to be empty 3965 */ 3966int 3967iwm_flush_tx_path(struct iwm_softc *sc, uint32_t tfd_msk, uint32_t flags) 3968{ 3969 int ret; |
4062 struct iwm_tx_path_flush_cmd flush_cmd = { | 3970 struct iwm_tx_path_flush_cmd_v1 flush_cmd = { |
4063 .queues_ctl = htole32(tfd_msk), 4064 .flush_ctl = htole16(IWM_DUMP_TX_FIFO_FLUSH), 4065 }; 4066 4067 ret = iwm_send_cmd_pdu(sc, IWM_TXPATH_FLUSH, flags, 4068 sizeof(flush_cmd), &flush_cmd); 4069 if (ret) 4070 device_printf(sc->sc_dev, 4071 "Flushing tx queue failed: %d\n", ret); 4072 return ret; 4073} 4074 4075/* 4076 * BEGIN mvm/quota.c 4077 */ 4078 4079static int 4080iwm_update_quotas(struct iwm_softc *sc, struct iwm_vap *ivp) 4081{ | 3971 .queues_ctl = htole32(tfd_msk), 3972 .flush_ctl = htole16(IWM_DUMP_TX_FIFO_FLUSH), 3973 }; 3974 3975 ret = iwm_send_cmd_pdu(sc, IWM_TXPATH_FLUSH, flags, 3976 sizeof(flush_cmd), &flush_cmd); 3977 if (ret) 3978 device_printf(sc->sc_dev, 3979 "Flushing tx queue failed: %d\n", ret); 3980 return ret; 3981} 3982 3983/* 3984 * BEGIN mvm/quota.c 3985 */ 3986 3987static int 3988iwm_update_quotas(struct iwm_softc *sc, struct iwm_vap *ivp) 3989{ |
4082 struct iwm_time_quota_cmd cmd; | 3990 struct iwm_time_quota_cmd_v1 cmd; |
4083 int i, idx, ret, num_active_macs, quota, quota_rem; 4084 int colors[IWM_MAX_BINDINGS] = { -1, -1, -1, -1, }; 4085 int n_ifs[IWM_MAX_BINDINGS] = {0, }; 4086 uint16_t id; 4087 4088 memset(&cmd, 0, sizeof(cmd)); 4089 4090 /* currently, PHY ID == binding ID */ --- 615 unchanged lines hidden (view full) --- 4706 .id = IWM_MCC_UPDATE_CMD, 4707 .flags = (IWM_CMD_SYNC | IWM_CMD_WANT_SKB), 4708 .data = { &mcc_cmd }, 4709 }; 4710 int ret; 4711#ifdef IWM_DEBUG 4712 struct iwm_rx_packet *pkt; 4713 struct iwm_mcc_update_resp_v1 *mcc_resp_v1 = NULL; | 3991 int i, idx, ret, num_active_macs, quota, quota_rem; 3992 int colors[IWM_MAX_BINDINGS] = { -1, -1, -1, -1, }; 3993 int n_ifs[IWM_MAX_BINDINGS] = {0, }; 3994 uint16_t id; 3995 3996 memset(&cmd, 0, sizeof(cmd)); 3997 3998 /* currently, PHY ID == binding ID */ --- 615 unchanged lines hidden (view full) --- 4614 .id = IWM_MCC_UPDATE_CMD, 4615 .flags = (IWM_CMD_SYNC | IWM_CMD_WANT_SKB), 4616 .data = { &mcc_cmd }, 4617 }; 4618 int ret; 4619#ifdef IWM_DEBUG 4620 struct iwm_rx_packet *pkt; 4621 struct iwm_mcc_update_resp_v1 *mcc_resp_v1 = NULL; |
4714 struct iwm_mcc_update_resp *mcc_resp; | 4622 struct iwm_mcc_update_resp_v2 *mcc_resp; |
4715 int n_channels; 4716 uint16_t mcc; 4717#endif 4718 int resp_v2 = iwm_fw_has_capa(sc, IWM_UCODE_TLV_CAPA_LAR_SUPPORT_V2); 4719 4720 if (!iwm_is_lar_supported(sc)) { 4721 IWM_DPRINTF(sc, IWM_DEBUG_LAR, "%s: no LAR support\n", 4722 __func__); --- 1967 unchanged lines hidden --- | 4623 int n_channels; 4624 uint16_t mcc; 4625#endif 4626 int resp_v2 = iwm_fw_has_capa(sc, IWM_UCODE_TLV_CAPA_LAR_SUPPORT_V2); 4627 4628 if (!iwm_is_lar_supported(sc)) { 4629 IWM_DPRINTF(sc, IWM_DEBUG_LAR, "%s: no LAR support\n", 4630 __func__); --- 1967 unchanged lines hidden --- |