static int iwm_phy_db_get_section_data(struct iwm_phy_db *phy_db, uint32_t type, uint8_t **data, uint16_t *size, uint16_t ch_id) { struct iwm_phy_db_entry *entry; uint16_t ch_group_id = 0; if (!phy_db) return EINVAL; /* find wanted channel group */ if (type == IWM_PHY_DB_CALIB_CHG_PAPD) ch_group_id = channel_id_to_papd(ch_id); else if (type == IWM_PHY_DB_CALIB_CHG_TXP) ch_group_id = channel_id_to_txp(phy_db, ch_id); entry = iwm_phy_db_get_section(phy_db, type, ch_group_id); if (!entry) return EINVAL; *data = entry->data; *size = entry->size; IWM_DPRINTF(phy_db->sc, IWM_DEBUG_RESET, "%s(%d): [PHYDB] GET: Type %d , Size: %d\n", __func__, __LINE__, type, *size); return 0; }
static int iwm_phy_db_send_all_channel_groups(struct iwm_softc *sc, enum iwm_phy_db_section_type type, uint8_t max_ch_groups) { uint16_t i; int err; struct iwm_phy_db_entry *entry; /* Send all the channel-specific groups to operational fw */ for (i = 0; i < max_ch_groups; i++) { entry = iwm_phy_db_get_section(sc, type, i); if (!entry) return EINVAL; if (!entry->size) continue; /* Send the requested PHY DB section */ err = iwm_send_phy_db_cmd(sc, type, entry->size, entry->data); if (err) { IWM_DPRINTF(sc, IWM_DEBUG_CMD, "%s: Can't SEND phy_db section %d (%d), " "err %d\n", __func__, type, i, err); return err; } IWM_DPRINTF(sc, IWM_DEBUG_CMD, "Sent PHY_DB HCMD, type = %d num = %d\n", type, i); } return 0; }
int iwm_phy_db_set_section(struct iwm_softc *sc, struct iwm_calib_res_notif_phy_db *phy_db_notif) { enum iwm_phy_db_section_type type = le16toh(phy_db_notif->type); uint16_t size = le16toh(phy_db_notif->length); struct iwm_phy_db_entry *entry; uint16_t chg_id = 0; if (type == IWM_PHY_DB_CALIB_CHG_PAPD || type == IWM_PHY_DB_CALIB_CHG_TXP) chg_id = le16toh(*(uint16_t *)phy_db_notif->data); entry = iwm_phy_db_get_section(sc, type, chg_id); if (!entry) return EINVAL; if (entry->data) kfree(entry->data, M_DEVBUF); entry->data = kmalloc(size, M_DEVBUF, M_INTWAIT); if (!entry->data) { entry->size = 0; return ENOMEM; } memcpy(entry->data, phy_db_notif->data, size); entry->size = size; IWM_DPRINTF(sc, IWM_DEBUG_RESET, "%s(%d): [PHYDB]SET: Type %d , Size: %d, data: %p\n", __func__, __LINE__, type, size, entry->data); return 0; }
static void iwm_phy_db_free_section(struct iwm_phy_db *phy_db, enum iwm_phy_db_section_type type, uint16_t chg_id) { struct iwm_phy_db_entry *entry = iwm_phy_db_get_section(phy_db, type, chg_id); if (!entry) return; if (entry->data != NULL) free(entry->data, M_DEVBUF); entry->data = NULL; entry->size = 0; }
int iwm_phy_db_set_section(struct iwm_phy_db *phy_db, struct iwm_rx_packet *pkt) { struct iwm_calib_res_notif_phy_db *phy_db_notif = (struct iwm_calib_res_notif_phy_db *)pkt->data; enum iwm_phy_db_section_type type = le16toh(phy_db_notif->type); uint16_t size = le16toh(phy_db_notif->length); struct iwm_phy_db_entry *entry; uint16_t chg_id = 0; if (!phy_db) return EINVAL; if (type == IWM_PHY_DB_CALIB_CHG_PAPD) { chg_id = le16toh(*(uint16_t *)phy_db_notif->data); if (phy_db && !phy_db->calib_ch_group_papd) { /* * Firmware sends the largest index first, so we can use * it to know how much we should allocate. */ phy_db->calib_ch_group_papd = malloc( (chg_id + 1) * sizeof(struct iwm_phy_db_entry), M_DEVBUF, M_NOWAIT | M_ZERO); if (!phy_db->calib_ch_group_papd) return ENOMEM; phy_db->n_group_papd = chg_id + 1; } } else if (type == IWM_PHY_DB_CALIB_CHG_TXP) { chg_id = le16toh(*(uint16_t *)phy_db_notif->data); if (phy_db && !phy_db->calib_ch_group_txp) { /* * Firmware sends the largest index first, so we can use * it to know how much we should allocate. */ phy_db->calib_ch_group_txp = malloc( (chg_id + 1) * sizeof(struct iwm_phy_db_entry), M_DEVBUF, M_NOWAIT | M_ZERO); if (!phy_db->calib_ch_group_txp) return ENOMEM; phy_db->n_group_txp = chg_id + 1; } } entry = iwm_phy_db_get_section(phy_db, type, chg_id); if (!entry) return EINVAL; if (entry->data != NULL) free(entry->data, M_DEVBUF); entry->data = malloc(size, M_DEVBUF, M_NOWAIT); if (!entry->data) { entry->size = 0; return ENOMEM; } memcpy(entry->data, phy_db_notif->data, size); entry->size = size; IWM_DPRINTF(phy_db->sc, IWM_DEBUG_RESET, "%s(%d): [PHYDB]SET: Type %d , Size: %d\n", __func__, __LINE__, type, size); return 0; }