iwm: fix support for 3168 devices

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

iwm: fix support for 3168 devices

Stefan Sperling-5
This diff makes 3168 devices actually work with iwm(4).
These devices have never worked right since the driver just threw
errors when trying to load firmware.

Loosely based on FreeBSD r345002 and Linux commit
44fd09dad5d2b78efbabbbbf623774e561e36cca

Tested with:
iwm0 at pci4 dev 0 function 0 "Intel Dual Band Wireless-AC 3168" rev 0x10, msi
iwm0: hw rev 0x220, fw ver 29.1654887522.0, address xx:xx:xx:xx:xx:xx

Please also test on any other types of iwm devices to ensure that this
won't break anything.

diff refs/heads/master refs/heads/nvmsdp
blob - ea6f2b9561ee5f7634fb0db5a19e466b67e8f473 (mode 644)
blob + 322894c03b5705071d8fd79391b8b138f2b01c34 (mode 600)
--- sys/dev/pci/if_iwm.c
+++ sys/dev/pci/if_iwm.c
@@ -319,7 +319,7 @@ int iwm_nvm_read_chunk(struct iwm_softc *, uint16_t, u
 int iwm_nvm_read_section(struct iwm_softc *, uint16_t, uint8_t *,
     uint16_t *, size_t);
 void iwm_init_channel_map(struct iwm_softc *, const uint16_t * const,
-    const uint8_t *nvm_channels, size_t nchan);
+    const uint8_t *nvm_channels, int nchan);
 void iwm_setup_ht_rates(struct iwm_softc *);
 void iwm_htprot_task(void *);
 void iwm_update_htprot(struct ieee80211com *, struct ieee80211_node *);
@@ -340,7 +340,7 @@ void iwm_ba_task(void *);
 int iwm_parse_nvm_data(struct iwm_softc *, const uint16_t *,
     const uint16_t *, const uint16_t *,
     const uint16_t *, const uint16_t *,
-    const uint16_t *);
+    const uint16_t *, int);
 void iwm_set_hw_address_8000(struct iwm_softc *, struct iwm_nvm_data *,
     const uint16_t *, const uint16_t *);
 int iwm_parse_nvm_sections(struct iwm_softc *, struct iwm_nvm_section *);
@@ -2374,6 +2374,7 @@ const int iwm_nvm_to_read[] = {
  IWM_NVM_SECTION_TYPE_REGULATORY,
  IWM_NVM_SECTION_TYPE_CALIBRATION,
  IWM_NVM_SECTION_TYPE_PRODUCTION,
+ IWM_NVM_SECTION_TYPE_REGULATORY_SDP,
  IWM_NVM_SECTION_TYPE_HW_8000,
  IWM_NVM_SECTION_TYPE_MAC_OVERRIDE,
  IWM_NVM_SECTION_TYPE_PHY_SKU,
@@ -2511,7 +2512,7 @@ iwm_fw_valid_rx_ant(struct iwm_softc *sc)
 
 void
 iwm_init_channel_map(struct iwm_softc *sc, const uint16_t * const nvm_ch_flags,
-    const uint8_t *nvm_channels, size_t nchan)
+    const uint8_t *nvm_channels, int nchan)
 {
  struct ieee80211com *ic = &sc->sc_ic;
  struct iwm_nvm_data *data = &sc->sc_nvm;
@@ -2796,7 +2797,7 @@ int
 iwm_parse_nvm_data(struct iwm_softc *sc, const uint16_t *nvm_hw,
     const uint16_t *nvm_sw, const uint16_t *nvm_calib,
     const uint16_t *mac_override, const uint16_t *phy_sku,
-    const uint16_t *regulatory)
+    const uint16_t *regulatory, int n_regulatory)
 {
  struct iwm_nvm_data *data = &sc->sc_nvm;
  uint8_t hw_addr[ETHER_ADDR_LEN];
@@ -2855,12 +2856,19 @@ iwm_parse_nvm_data(struct iwm_softc *sc, const uint16_
  } else
  iwm_set_hw_address_8000(sc, data, mac_override, nvm_hw);
 
- if (sc->sc_device_family == IWM_DEVICE_FAMILY_7000)
- iwm_init_channel_map(sc, &nvm_sw[IWM_NVM_CHANNELS],
-    iwm_nvm_channels, nitems(iwm_nvm_channels));
- else
+ if (sc->sc_device_family == IWM_DEVICE_FAMILY_7000) {
+ if (sc->nvm_type == IWM_NVM_SDP) {
+ iwm_init_channel_map(sc, regulatory, iwm_nvm_channels,
+    MIN(n_regulatory, nitems(iwm_nvm_channels)));
+ } else {
+ iwm_init_channel_map(sc, &nvm_sw[IWM_NVM_CHANNELS],
+    iwm_nvm_channels,
+    MIN(n_regulatory, nitems(iwm_nvm_channels)));
+ }
+ } else
  iwm_init_channel_map(sc, &regulatory[IWM_NVM_CHANNELS_8000],
-    iwm_nvm_channels_8000, nitems(iwm_nvm_channels_8000));
+    iwm_nvm_channels_8000,
+    MIN(n_regulatory, nitems(iwm_nvm_channels_8000)));
 
  data->calib_version = 255;   /* TODO:
  this value will prevent some checks from
@@ -2876,6 +2884,7 @@ iwm_parse_nvm_sections(struct iwm_softc *sc, struct iw
 {
  const uint16_t *hw, *sw, *calib, *mac_override = NULL, *phy_sku = NULL;
  const uint16_t *regulatory = NULL;
+ int n_regulatory = 0;
 
  /* Checking for required sections */
  if (sc->sc_device_family == IWM_DEVICE_FAMILY_7000) {
@@ -2885,6 +2894,15 @@ iwm_parse_nvm_sections(struct iwm_softc *sc, struct iw
  }
 
  hw = (const uint16_t *) sections[IWM_NVM_SECTION_TYPE_HW].data;
+
+ if (sc->nvm_type == IWM_NVM_SDP) {
+ if (!sections[IWM_NVM_SECTION_TYPE_REGULATORY_SDP].data)
+ return ENOENT;
+ regulatory = (const uint16_t *)
+    sections[IWM_NVM_SECTION_TYPE_REGULATORY_SDP].data;
+ n_regulatory =
+    sections[IWM_NVM_SECTION_TYPE_REGULATORY_SDP].length;
+ }
  } else if (sc->sc_device_family == IWM_DEVICE_FAMILY_8000) {
  /* SW and REGULATORY sections are mandatory */
  if (!sections[IWM_NVM_SECTION_TYPE_SW].data ||
@@ -2904,6 +2922,7 @@ iwm_parse_nvm_sections(struct iwm_softc *sc, struct iw
 
  regulatory = (const uint16_t *)
     sections[IWM_NVM_SECTION_TYPE_REGULATORY].data;
+ n_regulatory = sections[IWM_NVM_SECTION_TYPE_REGULATORY].length;
  hw = (const uint16_t *)
     sections[IWM_NVM_SECTION_TYPE_HW_8000].data;
  mac_override =
@@ -2919,8 +2938,9 @@ iwm_parse_nvm_sections(struct iwm_softc *sc, struct iw
  calib = (const uint16_t *)
     sections[IWM_NVM_SECTION_TYPE_CALIBRATION].data;
 
+ /* XXX should pass in the length of every section */
  return iwm_parse_nvm_data(sc, hw, sw, calib, mac_override,
-    phy_sku, regulatory);
+    phy_sku, regulatory, n_regulatory);
 }
 
 int
@@ -8138,6 +8158,7 @@ iwm_attach(struct device *parent, struct device *self,
  sc->sc_device_family = IWM_DEVICE_FAMILY_7000;
  sc->sc_fwdmasegsz = IWM_FWDMASEGSZ;
  sc->sc_nvm_max_section_size = 16384;
+ sc->nvm_type = IWM_NVM;
  break;
  case PCI_PRODUCT_INTEL_WL_3165_1:
  case PCI_PRODUCT_INTEL_WL_3165_2:
@@ -8146,13 +8167,15 @@ iwm_attach(struct device *parent, struct device *self,
  sc->sc_device_family = IWM_DEVICE_FAMILY_7000;
  sc->sc_fwdmasegsz = IWM_FWDMASEGSZ;
  sc->sc_nvm_max_section_size = 16384;
+ sc->nvm_type = IWM_NVM;
  break;
  case PCI_PRODUCT_INTEL_WL_3168_1:
- sc->sc_fwname = "iwm-3168-22";
+ sc->sc_fwname = "iwm-3168-29";
  sc->host_interrupt_operation_mode = 0;
  sc->sc_device_family = IWM_DEVICE_FAMILY_7000;
  sc->sc_fwdmasegsz = IWM_FWDMASEGSZ;
  sc->sc_nvm_max_section_size = 16384;
+ sc->nvm_type = IWM_NVM_SDP;
  break;
  case PCI_PRODUCT_INTEL_WL_7260_1:
  case PCI_PRODUCT_INTEL_WL_7260_2:
@@ -8161,6 +8184,7 @@ iwm_attach(struct device *parent, struct device *self,
  sc->sc_device_family = IWM_DEVICE_FAMILY_7000;
  sc->sc_fwdmasegsz = IWM_FWDMASEGSZ;
  sc->sc_nvm_max_section_size = 16384;
+ sc->nvm_type = IWM_NVM;
  break;
  case PCI_PRODUCT_INTEL_WL_7265_1:
  case PCI_PRODUCT_INTEL_WL_7265_2:
@@ -8169,6 +8193,7 @@ iwm_attach(struct device *parent, struct device *self,
  sc->sc_device_family = IWM_DEVICE_FAMILY_7000;
  sc->sc_fwdmasegsz = IWM_FWDMASEGSZ;
  sc->sc_nvm_max_section_size = 16384;
+ sc->nvm_type = IWM_NVM;
  break;
  case PCI_PRODUCT_INTEL_WL_8260_1:
  case PCI_PRODUCT_INTEL_WL_8260_2:
@@ -8177,6 +8202,7 @@ iwm_attach(struct device *parent, struct device *self,
  sc->sc_device_family = IWM_DEVICE_FAMILY_8000;
  sc->sc_fwdmasegsz = IWM_FWDMASEGSZ_8000;
  sc->sc_nvm_max_section_size = 32768;
+ sc->nvm_type = IWM_NVM_EXT;
  break;
  case PCI_PRODUCT_INTEL_WL_8265_1:
  sc->sc_fwname = "iwm-8265-34";
@@ -8184,6 +8210,7 @@ iwm_attach(struct device *parent, struct device *self,
  sc->sc_device_family = IWM_DEVICE_FAMILY_8000;
  sc->sc_fwdmasegsz = IWM_FWDMASEGSZ_8000;
  sc->sc_nvm_max_section_size = 32768;
+ sc->nvm_type = IWM_NVM_EXT;
  break;
  default:
  printf("%s: unknown adapter type\n", DEVNAME(sc));
blob - ebdbb2114cadf32ee444d148f5d85fd99096e525
blob + c16860241d1d2e5cf974e89e3a138822c1c7314c
--- sys/dev/pci/if_iwmreg.h
+++ sys/dev/pci/if_iwmreg.h
@@ -2096,11 +2096,25 @@ struct iwm_calib_res_notif_phy_db {
 #define IWM_NVM_SECTION_TYPE_CALIBRATION 4
 #define IWM_NVM_SECTION_TYPE_PRODUCTION 5
 #define IWM_NVM_SECTION_TYPE_POST_FCS_CALIB 6
-/* 7, 8, 9 unknown */
+/* 7 unknown */
+#define IWM_NVM_SECTION_TYPE_REGULATORY_SDP 8
+/* 9 unknown */
 #define IWM_NVM_SECTION_TYPE_HW_8000 10
 #define IWM_NVM_SECTION_TYPE_MAC_OVERRIDE 11
 #define IWM_NVM_SECTION_TYPE_PHY_SKU 12
 #define IWM_NVM_NUM_OF_SECTIONS 13
+
+/**
+ * enum iwm_nvm_type - nvm formats
+ * @IWM_NVM: the regular format
+ * @IWM_NVM_EXT: extended NVM format
+ * @IWM_NVM_SDP: NVM format used by 3168 series
+ */
+enum iwm_nvm_type {
+ IWM_NVM,
+ IWM_NVM_EXT,
+ IWM_NVM_SDP,
+};
 
 /**
  * struct iwm_nvm_access_cmd_ver2 - Request the device to send an NVM section
blob - 9a5da32ea7dd6d59623ddab32125620fca36f644
blob + c69c7fbe7e558939b5f9398cbfb421d9e115b725
--- sys/dev/pci/if_iwmvar.h
+++ sys/dev/pci/if_iwmvar.h
@@ -498,6 +498,7 @@ struct iwm_softc {
 
  int host_interrupt_operation_mode;
  int sc_ltr_enabled;
+ enum iwm_nvm_type nvm_type;
 
  /*
  * Paging parameters - All of the parameters should be set by the

Reply | Threaded
Open this post in threaded view
|

Re: iwm: fix support for 3168 devices

Kevin Lo
On Sat, Nov 09, 2019 at 01:01:39PM +0200, Stefan Sperling wrote:
>
> This diff makes 3168 devices actually work with iwm(4).
> These devices have never worked right since the driver just threw
> errors when trying to load firmware.

Indeed.  The 3168 device didn't work for me (for example, ifconfig iwm0 scan
returns empty results) until your diff is applied.

> Loosely based on FreeBSD r345002 and Linux commit
> 44fd09dad5d2b78efbabbbbf623774e561e36cca
>
> Tested with:
> iwm0 at pci4 dev 0 function 0 "Intel Dual Band Wireless-AC 3168" rev 0x10, msi
> iwm0: hw rev 0x220, fw ver 29.1654887522.0, address xx:xx:xx:xx:xx:xx

Tested with:
iwm0 at pci3 dev 0 function 0 "Intel Dual Band Wireless-AC 3168" rev 0x10, msi
iwm0: hw rev 0x220, fw ver 29.1654887522.0, address b0:35:9f:xx:xx:xx

> Please also test on any other types of iwm devices to ensure that this
> won't break anything.

I also tested with 3165,  it works as usual.

Thank you,
Kevin

Reply | Threaded
Open this post in threaded view
|

Re: iwm: fix support for 3168 devices

Stefan Sperling-5
On Mon, Nov 11, 2019 at 10:19:12AM +0800, Kevin Lo wrote:
> On Sat, Nov 09, 2019 at 01:01:39PM +0200, Stefan Sperling wrote:
> >
> > This diff makes 3168 devices actually work with iwm(4).
> > These devices have never worked right since the driver just threw
> > errors when trying to load firmware.
>
> Indeed.  The 3168 device didn't work for me (for example, ifconfig iwm0 scan
> returns empty results) until your diff is applied.

The previous diff broke 7260/7265 devices. I made a mistake which resulted
in channel data structures not being initialized on those devices which
resulted in "panic: iwm0: bogus channel pointer" during boot.

Problem fixed with the diff below.

ok?

diff refs/heads/master refs/heads/nvmsdp
blob - ea6f2b9561ee5f7634fb0db5a19e466b67e8f473 (mode 644)
blob + 741617c6fb5ad4bffc00232d20c448349f1efd7e (mode 600)
--- sys/dev/pci/if_iwm.c
+++ sys/dev/pci/if_iwm.c
@@ -319,7 +319,7 @@ int iwm_nvm_read_chunk(struct iwm_softc *, uint16_t, u
 int iwm_nvm_read_section(struct iwm_softc *, uint16_t, uint8_t *,
     uint16_t *, size_t);
 void iwm_init_channel_map(struct iwm_softc *, const uint16_t * const,
-    const uint8_t *nvm_channels, size_t nchan);
+    const uint8_t *nvm_channels, int nchan);
 void iwm_setup_ht_rates(struct iwm_softc *);
 void iwm_htprot_task(void *);
 void iwm_update_htprot(struct ieee80211com *, struct ieee80211_node *);
@@ -340,7 +340,7 @@ void iwm_ba_task(void *);
 int iwm_parse_nvm_data(struct iwm_softc *, const uint16_t *,
     const uint16_t *, const uint16_t *,
     const uint16_t *, const uint16_t *,
-    const uint16_t *);
+    const uint16_t *, int);
 void iwm_set_hw_address_8000(struct iwm_softc *, struct iwm_nvm_data *,
     const uint16_t *, const uint16_t *);
 int iwm_parse_nvm_sections(struct iwm_softc *, struct iwm_nvm_section *);
@@ -2374,6 +2374,7 @@ const int iwm_nvm_to_read[] = {
  IWM_NVM_SECTION_TYPE_REGULATORY,
  IWM_NVM_SECTION_TYPE_CALIBRATION,
  IWM_NVM_SECTION_TYPE_PRODUCTION,
+ IWM_NVM_SECTION_TYPE_REGULATORY_SDP,
  IWM_NVM_SECTION_TYPE_HW_8000,
  IWM_NVM_SECTION_TYPE_MAC_OVERRIDE,
  IWM_NVM_SECTION_TYPE_PHY_SKU,
@@ -2511,7 +2512,7 @@ iwm_fw_valid_rx_ant(struct iwm_softc *sc)
 
 void
 iwm_init_channel_map(struct iwm_softc *sc, const uint16_t * const nvm_ch_flags,
-    const uint8_t *nvm_channels, size_t nchan)
+    const uint8_t *nvm_channels, int nchan)
 {
  struct ieee80211com *ic = &sc->sc_ic;
  struct iwm_nvm_data *data = &sc->sc_nvm;
@@ -2796,7 +2797,7 @@ int
 iwm_parse_nvm_data(struct iwm_softc *sc, const uint16_t *nvm_hw,
     const uint16_t *nvm_sw, const uint16_t *nvm_calib,
     const uint16_t *mac_override, const uint16_t *phy_sku,
-    const uint16_t *regulatory)
+    const uint16_t *regulatory, int n_regulatory)
 {
  struct iwm_nvm_data *data = &sc->sc_nvm;
  uint8_t hw_addr[ETHER_ADDR_LEN];
@@ -2855,12 +2856,18 @@ iwm_parse_nvm_data(struct iwm_softc *sc, const uint16_
  } else
  iwm_set_hw_address_8000(sc, data, mac_override, nvm_hw);
 
- if (sc->sc_device_family == IWM_DEVICE_FAMILY_7000)
- iwm_init_channel_map(sc, &nvm_sw[IWM_NVM_CHANNELS],
-    iwm_nvm_channels, nitems(iwm_nvm_channels));
- else
+ if (sc->sc_device_family == IWM_DEVICE_FAMILY_7000) {
+ if (sc->nvm_type == IWM_NVM_SDP) {
+ iwm_init_channel_map(sc, regulatory, iwm_nvm_channels,
+    MIN(n_regulatory, nitems(iwm_nvm_channels)));
+ } else {
+ iwm_init_channel_map(sc, &nvm_sw[IWM_NVM_CHANNELS],
+    iwm_nvm_channels, nitems(iwm_nvm_channels));
+ }
+ } else
  iwm_init_channel_map(sc, &regulatory[IWM_NVM_CHANNELS_8000],
-    iwm_nvm_channels_8000, nitems(iwm_nvm_channels_8000));
+    iwm_nvm_channels_8000,
+    MIN(n_regulatory, nitems(iwm_nvm_channels_8000)));
 
  data->calib_version = 255;   /* TODO:
  this value will prevent some checks from
@@ -2876,6 +2883,7 @@ iwm_parse_nvm_sections(struct iwm_softc *sc, struct iw
 {
  const uint16_t *hw, *sw, *calib, *mac_override = NULL, *phy_sku = NULL;
  const uint16_t *regulatory = NULL;
+ int n_regulatory = 0;
 
  /* Checking for required sections */
  if (sc->sc_device_family == IWM_DEVICE_FAMILY_7000) {
@@ -2885,6 +2893,15 @@ iwm_parse_nvm_sections(struct iwm_softc *sc, struct iw
  }
 
  hw = (const uint16_t *) sections[IWM_NVM_SECTION_TYPE_HW].data;
+
+ if (sc->nvm_type == IWM_NVM_SDP) {
+ if (!sections[IWM_NVM_SECTION_TYPE_REGULATORY_SDP].data)
+ return ENOENT;
+ regulatory = (const uint16_t *)
+    sections[IWM_NVM_SECTION_TYPE_REGULATORY_SDP].data;
+ n_regulatory =
+    sections[IWM_NVM_SECTION_TYPE_REGULATORY_SDP].length;
+ }
  } else if (sc->sc_device_family == IWM_DEVICE_FAMILY_8000) {
  /* SW and REGULATORY sections are mandatory */
  if (!sections[IWM_NVM_SECTION_TYPE_SW].data ||
@@ -2904,6 +2921,7 @@ iwm_parse_nvm_sections(struct iwm_softc *sc, struct iw
 
  regulatory = (const uint16_t *)
     sections[IWM_NVM_SECTION_TYPE_REGULATORY].data;
+ n_regulatory = sections[IWM_NVM_SECTION_TYPE_REGULATORY].length;
  hw = (const uint16_t *)
     sections[IWM_NVM_SECTION_TYPE_HW_8000].data;
  mac_override =
@@ -2919,8 +2937,9 @@ iwm_parse_nvm_sections(struct iwm_softc *sc, struct iw
  calib = (const uint16_t *)
     sections[IWM_NVM_SECTION_TYPE_CALIBRATION].data;
 
+ /* XXX should pass in the length of every section */
  return iwm_parse_nvm_data(sc, hw, sw, calib, mac_override,
-    phy_sku, regulatory);
+    phy_sku, regulatory, n_regulatory);
 }
 
 int
@@ -8138,6 +8157,7 @@ iwm_attach(struct device *parent, struct device *self,
  sc->sc_device_family = IWM_DEVICE_FAMILY_7000;
  sc->sc_fwdmasegsz = IWM_FWDMASEGSZ;
  sc->sc_nvm_max_section_size = 16384;
+ sc->nvm_type = IWM_NVM;
  break;
  case PCI_PRODUCT_INTEL_WL_3165_1:
  case PCI_PRODUCT_INTEL_WL_3165_2:
@@ -8146,13 +8166,15 @@ iwm_attach(struct device *parent, struct device *self,
  sc->sc_device_family = IWM_DEVICE_FAMILY_7000;
  sc->sc_fwdmasegsz = IWM_FWDMASEGSZ;
  sc->sc_nvm_max_section_size = 16384;
+ sc->nvm_type = IWM_NVM;
  break;
  case PCI_PRODUCT_INTEL_WL_3168_1:
- sc->sc_fwname = "iwm-3168-22";
+ sc->sc_fwname = "iwm-3168-29";
  sc->host_interrupt_operation_mode = 0;
  sc->sc_device_family = IWM_DEVICE_FAMILY_7000;
  sc->sc_fwdmasegsz = IWM_FWDMASEGSZ;
  sc->sc_nvm_max_section_size = 16384;
+ sc->nvm_type = IWM_NVM_SDP;
  break;
  case PCI_PRODUCT_INTEL_WL_7260_1:
  case PCI_PRODUCT_INTEL_WL_7260_2:
@@ -8161,6 +8183,7 @@ iwm_attach(struct device *parent, struct device *self,
  sc->sc_device_family = IWM_DEVICE_FAMILY_7000;
  sc->sc_fwdmasegsz = IWM_FWDMASEGSZ;
  sc->sc_nvm_max_section_size = 16384;
+ sc->nvm_type = IWM_NVM;
  break;
  case PCI_PRODUCT_INTEL_WL_7265_1:
  case PCI_PRODUCT_INTEL_WL_7265_2:
@@ -8169,6 +8192,7 @@ iwm_attach(struct device *parent, struct device *self,
  sc->sc_device_family = IWM_DEVICE_FAMILY_7000;
  sc->sc_fwdmasegsz = IWM_FWDMASEGSZ;
  sc->sc_nvm_max_section_size = 16384;
+ sc->nvm_type = IWM_NVM;
  break;
  case PCI_PRODUCT_INTEL_WL_8260_1:
  case PCI_PRODUCT_INTEL_WL_8260_2:
@@ -8177,6 +8201,7 @@ iwm_attach(struct device *parent, struct device *self,
  sc->sc_device_family = IWM_DEVICE_FAMILY_8000;
  sc->sc_fwdmasegsz = IWM_FWDMASEGSZ_8000;
  sc->sc_nvm_max_section_size = 32768;
+ sc->nvm_type = IWM_NVM_EXT;
  break;
  case PCI_PRODUCT_INTEL_WL_8265_1:
  sc->sc_fwname = "iwm-8265-34";
@@ -8184,6 +8209,7 @@ iwm_attach(struct device *parent, struct device *self,
  sc->sc_device_family = IWM_DEVICE_FAMILY_8000;
  sc->sc_fwdmasegsz = IWM_FWDMASEGSZ_8000;
  sc->sc_nvm_max_section_size = 32768;
+ sc->nvm_type = IWM_NVM_EXT;
  break;
  default:
  printf("%s: unknown adapter type\n", DEVNAME(sc));
blob - ebdbb2114cadf32ee444d148f5d85fd99096e525
blob + c16860241d1d2e5cf974e89e3a138822c1c7314c
--- sys/dev/pci/if_iwmreg.h
+++ sys/dev/pci/if_iwmreg.h
@@ -2096,11 +2096,25 @@ struct iwm_calib_res_notif_phy_db {
 #define IWM_NVM_SECTION_TYPE_CALIBRATION 4
 #define IWM_NVM_SECTION_TYPE_PRODUCTION 5
 #define IWM_NVM_SECTION_TYPE_POST_FCS_CALIB 6
-/* 7, 8, 9 unknown */
+/* 7 unknown */
+#define IWM_NVM_SECTION_TYPE_REGULATORY_SDP 8
+/* 9 unknown */
 #define IWM_NVM_SECTION_TYPE_HW_8000 10
 #define IWM_NVM_SECTION_TYPE_MAC_OVERRIDE 11
 #define IWM_NVM_SECTION_TYPE_PHY_SKU 12
 #define IWM_NVM_NUM_OF_SECTIONS 13
+
+/**
+ * enum iwm_nvm_type - nvm formats
+ * @IWM_NVM: the regular format
+ * @IWM_NVM_EXT: extended NVM format
+ * @IWM_NVM_SDP: NVM format used by 3168 series
+ */
+enum iwm_nvm_type {
+ IWM_NVM,
+ IWM_NVM_EXT,
+ IWM_NVM_SDP,
+};
 
 /**
  * struct iwm_nvm_access_cmd_ver2 - Request the device to send an NVM section
blob - 9a5da32ea7dd6d59623ddab32125620fca36f644
blob + c69c7fbe7e558939b5f9398cbfb421d9e115b725
--- sys/dev/pci/if_iwmvar.h
+++ sys/dev/pci/if_iwmvar.h
@@ -498,6 +498,7 @@ struct iwm_softc {
 
  int host_interrupt_operation_mode;
  int sc_ltr_enabled;
+ enum iwm_nvm_type nvm_type;
 
  /*
  * Paging parameters - All of the parameters should be set by the

Reply | Threaded
Open this post in threaded view
|

Re: iwm: fix support for 3168 devices

Kevin Lo
On Mon, Nov 11, 2019 at 06:33:39PM +0200, Stefan Sperling wrote:

>
> On Mon, Nov 11, 2019 at 10:19:12AM +0800, Kevin Lo wrote:
> > On Sat, Nov 09, 2019 at 01:01:39PM +0200, Stefan Sperling wrote:
> > >
> > > This diff makes 3168 devices actually work with iwm(4).
> > > These devices have never worked right since the driver just threw
> > > errors when trying to load firmware.
> >
> > Indeed.  The 3168 device didn't work for me (for example, ifconfig iwm0 scan
> > returns empty results) until your diff is applied.
>
> The previous diff broke 7260/7265 devices. I made a mistake which resulted
> in channel data structures not being initialized on those devices which
> resulted in "panic: iwm0: bogus channel pointer" during boot.
>
> Problem fixed with the diff below.

This diff still works on my msi Cubi 3 Silent.

> ok?

ok kevlo@