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;
}
Example #2
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;
}
Example #3
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;
}