[iwm] Add support for Firmware paging, needed for newer 8000C firmware.
* Uses the IWM_FW_PAGING_BLOCK_CMD firmware command to tell the firmware what memory ranges to use for paging. Obtained from: dragonflybsd.git 8a5b199964f8e7bdb00039f0b48817a01b402f18
This commit is contained in:
parent
8f7861b26f
commit
ad35d47138
@ -1864,6 +1864,7 @@ dev/iwm/if_iwm.c optional iwm
|
||||
dev/iwm/if_iwm_7000.c optional iwm
|
||||
dev/iwm/if_iwm_8000.c optional iwm
|
||||
dev/iwm/if_iwm_binding.c optional iwm
|
||||
dev/iwm/if_iwm_fw.c optional iwm
|
||||
dev/iwm/if_iwm_led.c optional iwm
|
||||
dev/iwm/if_iwm_mac_ctxt.c optional iwm
|
||||
dev/iwm/if_iwm_notif_wait.c optional iwm
|
||||
|
@ -166,6 +166,7 @@ __FBSDID("$FreeBSD$");
|
||||
|
||||
#include <dev/iwm/if_iwm_pcie_trans.h>
|
||||
#include <dev/iwm/if_iwm_led.h>
|
||||
#include <dev/iwm/if_iwm_fw.h>
|
||||
|
||||
const uint8_t iwm_nvm_channels[] = {
|
||||
/* 2.4 GHz */
|
||||
@ -2869,9 +2870,21 @@ iwm_mvm_load_ucode_wait_alive(struct iwm_softc *sc,
|
||||
* included in the IWM_UCODE_INIT image.
|
||||
*/
|
||||
if (fw->paging_mem_size) {
|
||||
/* XXX implement FW paging */
|
||||
device_printf(sc->sc_dev,
|
||||
"%s: XXX FW paging not implemented yet\n", __func__);
|
||||
error = iwm_save_fw_paging(sc, fw);
|
||||
if (error) {
|
||||
device_printf(sc->sc_dev,
|
||||
"%s: failed to save the FW paging image\n",
|
||||
__func__);
|
||||
return error;
|
||||
}
|
||||
|
||||
error = iwm_send_paging_cmd(sc, fw);
|
||||
if (error) {
|
||||
device_printf(sc->sc_dev,
|
||||
"%s: failed to send the paging cmd\n", __func__);
|
||||
iwm_free_fw_paging(sc);
|
||||
return error;
|
||||
}
|
||||
}
|
||||
|
||||
if (!error)
|
||||
@ -5517,6 +5530,7 @@ iwm_notif_intr(struct iwm_softc *sc)
|
||||
case IWM_REMOVE_STA:
|
||||
case IWM_TXPATH_FLUSH:
|
||||
case IWM_LQ_CMD:
|
||||
case IWM_FW_PAGING_BLOCK_CMD:
|
||||
case IWM_BT_CONFIG:
|
||||
case IWM_REPLY_THERMAL_MNG_BACKOFF:
|
||||
cresp = (void *)pkt->data;
|
||||
@ -6475,6 +6489,8 @@ iwm_detach_local(struct iwm_softc *sc, int do_net80211)
|
||||
iwm_dma_contig_free(&sc->kw_dma);
|
||||
iwm_dma_contig_free(&sc->fw_dma);
|
||||
|
||||
iwm_free_fw_paging(sc);
|
||||
|
||||
/* Finished with the hardware - detach things */
|
||||
iwm_pci_detach(dev);
|
||||
|
||||
|
@ -42,6 +42,7 @@ enum {
|
||||
IWM_DEBUG_TRANS = 0x00040000, /* Transport layer (eg PCIe) */
|
||||
IWM_DEBUG_EEPROM = 0x00080000, /* EEPROM/channel information */
|
||||
IWM_DEBUG_TEMP = 0x00100000, /* Thermal Sensor handling */
|
||||
IWM_DEBUG_FW = 0x00200000, /* Firmware management */
|
||||
IWM_DEBUG_REGISTER = 0x20000000, /* print chipset register */
|
||||
IWM_DEBUG_TRACE = 0x40000000, /* Print begin and start driver function */
|
||||
IWM_DEBUG_FATAL = 0x80000000, /* fatal errors */
|
||||
|
@ -888,28 +888,6 @@ struct iwm_fw_cipher_scheme {
|
||||
uint8_t hw_cipher;
|
||||
} __packed;
|
||||
|
||||
/*
|
||||
* Block paging calculations
|
||||
*/
|
||||
#define IWM_PAGE_2_EXP_SIZE 12 /* 4K == 2^12 */
|
||||
#define IWM_FW_PAGING_SIZE (1 << IWM_PAGE_2_EXP_SIZE) /* page size is 4KB */
|
||||
#define IWM_PAGE_PER_GROUP_2_EXP_SIZE 3
|
||||
/* 8 pages per group */
|
||||
#define IWM_NUM_OF_PAGE_PER_GROUP (1 << IWM_PAGE_PER_GROUP_2_EXP_SIZE)
|
||||
/* don't change, support only 32KB size */
|
||||
#define IWM_PAGING_BLOCK_SIZE (IWM_NUM_OF_PAGE_PER_GROUP * IWM_FW_PAGING_SIZE)
|
||||
/* 32K == 2^15 */
|
||||
#define IWM_BLOCK_2_EXP_SIZE (IWM_PAGE_2_EXP_SIZE + IWM_PAGE_PER_GROUP_2_EXP_SIZE)
|
||||
|
||||
/*
|
||||
* Image paging calculations
|
||||
*/
|
||||
#define IWM_BLOCK_PER_IMAGE_2_EXP_SIZE 5
|
||||
/* 2^5 == 32 blocks per image */
|
||||
#define IWM_NUM_OF_BLOCK_PER_IMAGE (1 << IWM_BLOCK_PER_IMAGE_2_EXP_SIZE)
|
||||
/* maximum image size 1024KB */
|
||||
#define IWM_MAX_PAGING_IMAGE_SIZE (IWM_NUM_OF_BLOCK_PER_IMAGE * IWM_PAGING_BLOCK_SIZE)
|
||||
|
||||
/**
|
||||
* struct iwm_fw_cscheme_list - a cipher scheme list
|
||||
* @size: a number of entries
|
||||
@ -1842,12 +1820,8 @@ enum {
|
||||
|
||||
IWM_LQ_CMD = 0x4e,
|
||||
|
||||
/* Calibration */
|
||||
IWM_TEMPERATURE_NOTIFICATION = 0x62,
|
||||
IWM_CALIBRATION_CFG_CMD = 0x65,
|
||||
IWM_CALIBRATION_RES_NOTIFICATION = 0x66,
|
||||
IWM_CALIBRATION_COMPLETE_NOTIFICATION = 0x67,
|
||||
IWM_RADIO_VERSION_NOTIFICATION = 0x68,
|
||||
/* paging block to FW cpu2 */
|
||||
IWM_FW_PAGING_BLOCK_CMD = 0x4f,
|
||||
|
||||
/* Scan offload */
|
||||
IWM_SCAN_OFFLOAD_REQUEST_CMD = 0x51,
|
||||
@ -2092,6 +2066,44 @@ struct iwm_nvm_access_cmd {
|
||||
uint8_t data[];
|
||||
} __packed; /* IWM_NVM_ACCESS_CMD_API_S_VER_2 */
|
||||
|
||||
#define IWM_NUM_OF_FW_PAGING_BLOCKS 33 /* 32 for data and 1 block for CSS */
|
||||
|
||||
/*
|
||||
* struct iwm_fw_paging_cmd - paging layout
|
||||
*
|
||||
* (IWM_FW_PAGING_BLOCK_CMD = 0x4f)
|
||||
*
|
||||
* Send to FW the paging layout in the driver.
|
||||
*
|
||||
* @flags: various flags for the command
|
||||
* @block_size: the block size in powers of 2
|
||||
* @block_num: number of blocks specified in the command.
|
||||
* @device_phy_addr: virtual addresses from device side
|
||||
*/
|
||||
struct iwm_fw_paging_cmd {
|
||||
uint32_t flags;
|
||||
uint32_t block_size;
|
||||
uint32_t block_num;
|
||||
uint32_t device_phy_addr[IWM_NUM_OF_FW_PAGING_BLOCKS];
|
||||
} __packed; /* IWM_FW_PAGING_BLOCK_CMD_API_S_VER_1 */
|
||||
|
||||
/*
|
||||
* Fw items ID's
|
||||
*
|
||||
* @IWM_FW_ITEM_ID_PAGING: Address of the pages that the FW will upload
|
||||
* download
|
||||
*/
|
||||
enum iwm_fw_item_id {
|
||||
IWM_FW_ITEM_ID_PAGING = 3,
|
||||
};
|
||||
|
||||
/*
|
||||
* struct iwm_fw_get_item_cmd - get an item from the fw
|
||||
*/
|
||||
struct iwm_fw_get_item_cmd {
|
||||
uint32_t item_id;
|
||||
} __packed; /* IWM_FW_GET_ITEM_CMD_API_S_VER_1 */
|
||||
|
||||
/**
|
||||
* struct iwm_nvm_access_resp_ver2 - response to IWM_NVM_ACCESS_CMD
|
||||
* @offset: offset in bytes into the section
|
||||
|
@ -246,6 +246,16 @@ struct iwm_dma_info {
|
||||
bus_size_t size;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct iwm_fw_paging
|
||||
* @fw_paging_block: dma memory info
|
||||
* @fw_paging_size: page size
|
||||
*/
|
||||
struct iwm_fw_paging {
|
||||
struct iwm_dma_info fw_paging_block;
|
||||
uint32_t fw_paging_size;
|
||||
};
|
||||
|
||||
#define IWM_TX_RING_COUNT 256
|
||||
#define IWM_TX_RING_LOMARK 192
|
||||
#define IWM_TX_RING_HIMARK 224
|
||||
@ -500,6 +510,14 @@ struct iwm_softc {
|
||||
uint32_t log_event_table;
|
||||
uint32_t umac_error_event_table;
|
||||
int support_umac_log;
|
||||
|
||||
/*
|
||||
* Paging parameters - All of the parameters should be set by the
|
||||
* opmode when paging is enabled
|
||||
*/
|
||||
struct iwm_fw_paging fw_paging_db[IWM_NUM_OF_FW_PAGING_BLOCKS];
|
||||
uint16_t num_of_paging_blk;
|
||||
uint16_t num_of_pages_in_last_blk;
|
||||
};
|
||||
|
||||
#define IWM_LOCK_INIT(_sc) \
|
||||
|
@ -7,7 +7,7 @@ KMOD= if_iwm
|
||||
SRCS= if_iwm.c if_iwm_binding.c if_iwm_util.c if_iwm_phy_db.c
|
||||
SRCS+= if_iwm_mac_ctxt.c if_iwm_phy_ctxt.c if_iwm_time_event.c
|
||||
SRCS+= if_iwm_power.c if_iwm_scan.c if_iwm_led.c if_iwm_notif_wait.c
|
||||
SRCS+= if_iwm_7000.c if_iwm_8000.c
|
||||
SRCS+= if_iwm_7000.c if_iwm_8000.c if_iwm_fw.c
|
||||
# bus layer
|
||||
SRCS+= if_iwm_pcie_trans.c
|
||||
SRCS+= device_if.h bus_if.h pci_if.h opt_wlan.h
|
||||
|
Loading…
x
Reference in New Issue
Block a user