MFhead@r313433
This commit is contained in:
commit
2709f2493f
@ -126,6 +126,15 @@ struct _Elftc_Bfd_Target _libelftc_targets[] = {
|
||||
.bt_machine = EM_PPC,
|
||||
},
|
||||
|
||||
{
|
||||
.bt_name = "elf32-powerpc-freebsd",
|
||||
.bt_type = ETF_ELF,
|
||||
.bt_byteorder = ELFDATA2MSB,
|
||||
.bt_elfclass = ELFCLASS32,
|
||||
.bt_machine = EM_PPC,
|
||||
.bt_osabi = ELFOSABI_FREEBSD,
|
||||
},
|
||||
|
||||
{
|
||||
.bt_name = "elf32-powerpcle",
|
||||
.bt_type = ETF_ELF,
|
||||
@ -289,6 +298,15 @@ struct _Elftc_Bfd_Target _libelftc_targets[] = {
|
||||
.bt_machine = EM_PPC64,
|
||||
},
|
||||
|
||||
{
|
||||
.bt_name = "elf64-powerpc-freebsd",
|
||||
.bt_type = ETF_ELF,
|
||||
.bt_byteorder = ELFDATA2MSB,
|
||||
.bt_elfclass = ELFCLASS64,
|
||||
.bt_machine = EM_PPC64,
|
||||
.bt_osabi = ELFOSABI_FREEBSD,
|
||||
},
|
||||
|
||||
{
|
||||
.bt_name = "elf64-powerpcle",
|
||||
.bt_type = ETF_ELF,
|
||||
|
@ -1897,7 +1897,7 @@ iwm3160fw.fwo optional iwm3160fw | iwmfw \
|
||||
no-implicit-rule \
|
||||
clean "iwm3160fw.fwo"
|
||||
iwm3160.fw optional iwm3160fw | iwmfw \
|
||||
dependency "$S/contrib/dev/iwm/iwm-3160-16.fw.uu" \
|
||||
dependency "$S/contrib/dev/iwm/iwm-3160-17.fw.uu" \
|
||||
compile-with "${NORMAL_FW}" \
|
||||
no-obj no-implicit-rule \
|
||||
clean "iwm3160.fw"
|
||||
@ -1911,7 +1911,7 @@ iwm7260fw.fwo optional iwm7260fw | iwmfw \
|
||||
no-implicit-rule \
|
||||
clean "iwm7260fw.fwo"
|
||||
iwm7260.fw optional iwm7260fw | iwmfw \
|
||||
dependency "$S/contrib/dev/iwm/iwm-7260-16.fw.uu" \
|
||||
dependency "$S/contrib/dev/iwm/iwm-7260-17.fw.uu" \
|
||||
compile-with "${NORMAL_FW}" \
|
||||
no-obj no-implicit-rule \
|
||||
clean "iwm7260.fw"
|
||||
@ -1925,7 +1925,7 @@ iwm7265fw.fwo optional iwm7265fw | iwmfw \
|
||||
no-implicit-rule \
|
||||
clean "iwm7265fw.fwo"
|
||||
iwm7265.fw optional iwm7265fw | iwmfw \
|
||||
dependency "$S/contrib/dev/iwm/iwm-7265-16.fw.uu" \
|
||||
dependency "$S/contrib/dev/iwm/iwm-7265-17.fw.uu" \
|
||||
compile-with "${NORMAL_FW}" \
|
||||
no-obj no-implicit-rule \
|
||||
clean "iwm7265.fw"
|
||||
|
20409
sys/contrib/dev/iwm/iwm-3160-17.fw.uu
Normal file
20409
sys/contrib/dev/iwm/iwm-3160-17.fw.uu
Normal file
File diff suppressed because it is too large
Load Diff
23322
sys/contrib/dev/iwm/iwm-7260-17.fw.uu
Normal file
23322
sys/contrib/dev/iwm/iwm-7260-17.fw.uu
Normal file
File diff suppressed because it is too large
Load Diff
26235
sys/contrib/dev/iwm/iwm-7265-17.fw.uu
Normal file
26235
sys/contrib/dev/iwm/iwm-7265-17.fw.uu
Normal file
File diff suppressed because it is too large
Load Diff
53122
sys/contrib/dev/iwm/iwm-8000C-17.fw.uu
Normal file
53122
sys/contrib/dev/iwm/iwm-8000C-17.fw.uu
Normal file
File diff suppressed because it is too large
Load Diff
@ -182,7 +182,8 @@ __FBSDID("$FreeBSD$");
|
||||
#define IWM_DEVICE_7000_COMMON \
|
||||
.device_family = IWM_DEVICE_FAMILY_7000, \
|
||||
.eeprom_size = IWM_OTP_LOW_IMAGE_SIZE_FAMILY_7000, \
|
||||
.nvm_hw_section_num = IWM_NVM_HW_SECTION_NUM_FAMILY_7000
|
||||
.nvm_hw_section_num = IWM_NVM_HW_SECTION_NUM_FAMILY_7000, \
|
||||
.apmg_wake_up_wa = 1
|
||||
|
||||
const struct iwm_cfg iwm7260_cfg = {
|
||||
.fw_name = IWM7260_FW,
|
||||
@ -302,7 +303,6 @@ static int iwm_alloc_sched(struct iwm_softc *);
|
||||
static int iwm_alloc_kw(struct iwm_softc *);
|
||||
static int iwm_alloc_ict(struct iwm_softc *);
|
||||
static int iwm_alloc_rx_ring(struct iwm_softc *, struct iwm_rx_ring *);
|
||||
static void iwm_disable_rx_dma(struct iwm_softc *);
|
||||
static void iwm_reset_rx_ring(struct iwm_softc *, struct iwm_rx_ring *);
|
||||
static void iwm_free_rx_ring(struct iwm_softc *, struct iwm_rx_ring *);
|
||||
static int iwm_alloc_tx_ring(struct iwm_softc *, struct iwm_tx_ring *,
|
||||
@ -892,6 +892,9 @@ iwm_read_firmware(struct iwm_softc *sc, enum iwm_ucode_type ucode_type)
|
||||
le32toh(((const uint32_t *)tlv_data)[2]));
|
||||
break;
|
||||
|
||||
case IWM_UCODE_TLV_FW_MEM_SEG:
|
||||
break;
|
||||
|
||||
default:
|
||||
device_printf(sc->sc_dev,
|
||||
"%s: unknown firmware section %d, abort\n",
|
||||
@ -1103,18 +1106,6 @@ fail: iwm_free_rx_ring(sc, ring);
|
||||
return error;
|
||||
}
|
||||
|
||||
static void
|
||||
iwm_disable_rx_dma(struct iwm_softc *sc)
|
||||
{
|
||||
/* XXX conditional nic locks are stupid */
|
||||
/* XXX print out if we can't lock the NIC? */
|
||||
if (iwm_nic_lock(sc)) {
|
||||
/* XXX handle if RX stop doesn't finish? */
|
||||
(void) iwm_pcie_rx_stop(sc);
|
||||
iwm_nic_unlock(sc);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
iwm_reset_rx_ring(struct iwm_softc *sc, struct iwm_rx_ring *ring)
|
||||
{
|
||||
@ -1264,6 +1255,9 @@ iwm_reset_tx_ring(struct iwm_softc *sc, struct iwm_tx_ring *ring)
|
||||
sc->qfullmsk &= ~(1 << ring->qid);
|
||||
ring->queued = 0;
|
||||
ring->cur = 0;
|
||||
|
||||
if (ring->qid == IWM_MVM_CMD_QUEUE && sc->cmd_hold_nic_awake)
|
||||
iwm_pcie_clear_cmd_in_flight(sc);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -1401,7 +1395,7 @@ iwm_stop_device(struct iwm_softc *sc)
|
||||
}
|
||||
iwm_nic_unlock(sc);
|
||||
}
|
||||
iwm_disable_rx_dma(sc);
|
||||
iwm_pcie_rx_stop(sc);
|
||||
|
||||
/* Stop RX ring. */
|
||||
iwm_reset_rx_ring(sc, &sc->rxq);
|
||||
@ -1410,11 +1404,12 @@ iwm_stop_device(struct iwm_softc *sc)
|
||||
for (qid = 0; qid < nitems(sc->txq); qid++)
|
||||
iwm_reset_tx_ring(sc, &sc->txq[qid]);
|
||||
|
||||
/*
|
||||
* Power-down device's busmaster DMA clocks
|
||||
*/
|
||||
iwm_write_prph(sc, IWM_APMG_CLK_DIS_REG, IWM_APMG_CLK_VAL_DMA_CLK_RQT);
|
||||
DELAY(5);
|
||||
if (sc->cfg->device_family == IWM_DEVICE_FAMILY_7000) {
|
||||
/* Power-down device's busmaster DMA clocks */
|
||||
iwm_write_prph(sc, IWM_APMG_CLK_DIS_REG,
|
||||
IWM_APMG_CLK_VAL_DMA_CLK_RQT);
|
||||
DELAY(5);
|
||||
}
|
||||
|
||||
/* Make sure (redundant) we've released our request to stay awake */
|
||||
IWM_CLRBITS(sc, IWM_CSR_GP_CNTRL,
|
||||
@ -1485,16 +1480,18 @@ iwm_mvm_nic_config(struct iwm_softc *sc)
|
||||
static int
|
||||
iwm_nic_rx_init(struct iwm_softc *sc)
|
||||
{
|
||||
if (!iwm_nic_lock(sc))
|
||||
return EBUSY;
|
||||
|
||||
/*
|
||||
* Initialize RX ring. This is from the iwn driver.
|
||||
*/
|
||||
memset(sc->rxq.stat, 0, sizeof(*sc->rxq.stat));
|
||||
|
||||
/* stop DMA */
|
||||
iwm_disable_rx_dma(sc);
|
||||
/* Stop Rx DMA */
|
||||
iwm_pcie_rx_stop(sc);
|
||||
|
||||
if (!iwm_nic_lock(sc))
|
||||
return EBUSY;
|
||||
|
||||
/* reset and flush pointers */
|
||||
IWM_WRITE(sc, IWM_FH_MEM_RCSR_CHNL0_RBDCB_WPTR, 0);
|
||||
IWM_WRITE(sc, IWM_FH_MEM_RCSR_CHNL0_FLUSH_RB_REQ, 0);
|
||||
IWM_WRITE(sc, IWM_FH_RSCSR_CHNL0_RDPTR, 0);
|
||||
@ -2681,12 +2678,6 @@ iwm_load_firmware(struct iwm_softc *sc, enum iwm_ucode_type ucode_type)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Give the firmware some time to initialize.
|
||||
* Accessing it too early causes errors.
|
||||
*/
|
||||
msleep(&w, &sc->sc_mtx, 0, "iwmfwinit", hz);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
@ -3349,6 +3340,18 @@ iwm_cmd_done(struct iwm_softc *sc, struct iwm_rx_packet *pkt)
|
||||
data->m = NULL;
|
||||
}
|
||||
wakeup(&ring->desc[pkt->hdr.idx]);
|
||||
|
||||
if (((pkt->hdr.idx + ring->queued) % IWM_TX_RING_COUNT) != ring->cur) {
|
||||
device_printf(sc->sc_dev,
|
||||
"%s: Some HCMDs skipped?: idx=%d queued=%d cur=%d\n",
|
||||
__func__, pkt->hdr.idx, ring->queued, ring->cur);
|
||||
/* XXX call iwm_force_nmi() */
|
||||
}
|
||||
|
||||
KASSERT(ring->queued > 0, ("ring->queued is empty?"));
|
||||
ring->queued--;
|
||||
if (ring->queued == 0)
|
||||
iwm_pcie_clear_cmd_in_flight(sc);
|
||||
}
|
||||
|
||||
#if 0
|
||||
@ -4962,6 +4965,7 @@ iwm_stop(struct iwm_softc *sc)
|
||||
iwm_led_blink_stop(sc);
|
||||
sc->sc_tx_timer = 0;
|
||||
iwm_stop_device(sc);
|
||||
sc->sc_flags &= ~IWM_FLAG_SCAN_RUNNING;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -5445,7 +5449,21 @@ iwm_notif_intr(struct iwm_softc *sc)
|
||||
break; }
|
||||
|
||||
case IWM_DTS_MEASUREMENT_NOTIFICATION:
|
||||
case IWM_WIDE_ID(IWM_PHY_OPS_GROUP,
|
||||
IWM_DTS_MEASUREMENT_NOTIF_WIDE): {
|
||||
struct iwm_dts_measurement_notif_v1 *notif;
|
||||
|
||||
if (iwm_rx_packet_payload_len(pkt) < sizeof(*notif)) {
|
||||
device_printf(sc->sc_dev,
|
||||
"Invalid DTS_MEASUREMENT_NOTIFICATION\n");
|
||||
break;
|
||||
}
|
||||
notif = (void *)pkt->data;
|
||||
IWM_DPRINTF(sc, IWM_DEBUG_TEMP,
|
||||
"IWM_DTS_MEASUREMENT_NOTIFICATION - %d\n",
|
||||
notif->temp);
|
||||
break;
|
||||
}
|
||||
|
||||
case IWM_PHY_CONFIGURATION_CMD:
|
||||
case IWM_TX_ANT_CONFIGURATION_CMD:
|
||||
@ -5458,7 +5476,9 @@ iwm_notif_intr(struct iwm_softc *sc)
|
||||
case IWM_TIME_EVENT_CMD:
|
||||
case IWM_WIDE_ID(IWM_ALWAYS_LONG_GROUP, IWM_SCAN_CFG_CMD):
|
||||
case IWM_WIDE_ID(IWM_ALWAYS_LONG_GROUP, IWM_SCAN_REQ_UMAC):
|
||||
case IWM_SCAN_ABORT_UMAC:
|
||||
case IWM_SCAN_OFFLOAD_REQUEST_CMD:
|
||||
case IWM_SCAN_OFFLOAD_ABORT_CMD:
|
||||
case IWM_REPLY_BEACON_FILTERING_CMD:
|
||||
case IWM_MAC_PM_POWER_TABLE:
|
||||
case IWM_TIME_QUOTA_CMD:
|
||||
@ -5484,6 +5504,10 @@ iwm_notif_intr(struct iwm_softc *sc)
|
||||
case IWM_SCAN_OFFLOAD_COMPLETE: {
|
||||
struct iwm_periodic_scan_complete *notif;
|
||||
notif = (void *)pkt->data;
|
||||
if (sc->sc_flags & IWM_FLAG_SCAN_RUNNING) {
|
||||
sc->sc_flags &= ~IWM_FLAG_SCAN_RUNNING;
|
||||
ieee80211_runtask(ic, &sc->sc_es_task);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@ -5501,9 +5525,10 @@ iwm_notif_intr(struct iwm_softc *sc)
|
||||
IWM_DPRINTF(sc, IWM_DEBUG_SCAN,
|
||||
"UMAC scan complete, status=0x%x\n",
|
||||
notif->status);
|
||||
#if 0 /* XXX This would be a duplicate scan end call */
|
||||
taskqueue_enqueue(sc->sc_tq, &sc->sc_es_task);
|
||||
#endif
|
||||
if (sc->sc_flags & IWM_FLAG_SCAN_RUNNING) {
|
||||
sc->sc_flags &= ~IWM_FLAG_SCAN_RUNNING;
|
||||
ieee80211_runtask(ic, &sc->sc_es_task);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@ -5583,9 +5608,6 @@ iwm_notif_intr(struct iwm_softc *sc)
|
||||
ADVANCE_RXQ(sc);
|
||||
}
|
||||
|
||||
IWM_CLRBITS(sc, IWM_CSR_GP_CNTRL,
|
||||
IWM_CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
|
||||
|
||||
/*
|
||||
* Tell the firmware what we have processed.
|
||||
* Seems like the hardware gets upset unless we align
|
||||
@ -6263,15 +6285,21 @@ iwm_scan_start(struct ieee80211com *ic)
|
||||
int error;
|
||||
|
||||
IWM_LOCK(sc);
|
||||
if (sc->sc_flags & IWM_FLAG_SCAN_RUNNING) {
|
||||
/* This should not be possible */
|
||||
device_printf(sc->sc_dev,
|
||||
"%s: Previous scan not completed yet\n", __func__);
|
||||
}
|
||||
if (isset(sc->sc_enabled_capa, IWM_UCODE_TLV_CAPA_UMAC_SCAN))
|
||||
error = iwm_mvm_umac_scan(sc);
|
||||
else
|
||||
error = iwm_mvm_lmac_scan(sc);
|
||||
if (error != 0) {
|
||||
device_printf(sc->sc_dev, "could not initiate 2 GHz scan\n");
|
||||
device_printf(sc->sc_dev, "could not initiate scan\n");
|
||||
IWM_UNLOCK(sc);
|
||||
ieee80211_cancel_scan(vap);
|
||||
} else {
|
||||
sc->sc_flags |= IWM_FLAG_SCAN_RUNNING;
|
||||
iwm_led_blink_start(sc);
|
||||
IWM_UNLOCK(sc);
|
||||
}
|
||||
@ -6287,7 +6315,23 @@ iwm_scan_end(struct ieee80211com *ic)
|
||||
iwm_led_blink_stop(sc);
|
||||
if (vap->iv_state == IEEE80211_S_RUN)
|
||||
iwm_mvm_led_enable(sc);
|
||||
if (sc->sc_flags & IWM_FLAG_SCAN_RUNNING) {
|
||||
/*
|
||||
* Removing IWM_FLAG_SCAN_RUNNING now, is fine because
|
||||
* both iwm_scan_end and iwm_scan_start run in the ic->ic_tq
|
||||
* taskqueue.
|
||||
*/
|
||||
sc->sc_flags &= ~IWM_FLAG_SCAN_RUNNING;
|
||||
iwm_mvm_scan_stop_wait(sc);
|
||||
}
|
||||
IWM_UNLOCK(sc);
|
||||
|
||||
/*
|
||||
* Make sure we don't race, if sc_es_task is still enqueued here.
|
||||
* This is to make sure that it won't call ieee80211_scan_done
|
||||
* when we have already started the next scan.
|
||||
*/
|
||||
taskqueue_cancel(ic->ic_tq, &sc->sc_es_task, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -41,6 +41,7 @@ enum {
|
||||
IWM_DEBUG_FIRMWARE_TLV = 0x00020000, /* Firmware TLV parsing */
|
||||
IWM_DEBUG_TRANS = 0x00040000, /* Transport layer (eg PCIe) */
|
||||
IWM_DEBUG_EEPROM = 0x00080000, /* EEPROM/channel information */
|
||||
IWM_DEBUG_TEMP = 0x00100000, /* Thermal Sensor handling */
|
||||
IWM_DEBUG_REGISTER = 0x20000000, /* print chipset register */
|
||||
IWM_DEBUG_TRACE = 0x40000000, /* Print begin and start driver function */
|
||||
IWM_DEBUG_FATAL = 0x80000000, /* fatal errors */
|
||||
|
@ -253,6 +253,9 @@ iwm_nic_lock(struct iwm_softc *sc)
|
||||
{
|
||||
int rv = 0;
|
||||
|
||||
if (sc->cmd_hold_nic_awake)
|
||||
return 1;
|
||||
|
||||
IWM_SETBITS(sc, IWM_CSR_GP_CNTRL,
|
||||
IWM_CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
|
||||
|
||||
@ -277,6 +280,9 @@ iwm_nic_lock(struct iwm_softc *sc)
|
||||
void
|
||||
iwm_nic_unlock(struct iwm_softc *sc)
|
||||
{
|
||||
if (sc->cmd_hold_nic_awake)
|
||||
return;
|
||||
|
||||
IWM_CLRBITS(sc, IWM_CSR_GP_CNTRL,
|
||||
IWM_CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
|
||||
}
|
||||
@ -572,10 +578,66 @@ iwm_set_pwr(struct iwm_softc *sc)
|
||||
int
|
||||
iwm_pcie_rx_stop(struct iwm_softc *sc)
|
||||
{
|
||||
|
||||
IWM_WRITE(sc, IWM_FH_MEM_RCSR_CHNL0_CONFIG_REG, 0);
|
||||
return (iwm_poll_bit(sc, IWM_FH_MEM_RSSR_RX_STATUS_REG,
|
||||
IWM_FH_RSSR_CHNL0_RX_STATUS_CHNL_IDLE,
|
||||
IWM_FH_RSSR_CHNL0_RX_STATUS_CHNL_IDLE,
|
||||
1000));
|
||||
int ret = 0;
|
||||
if (iwm_nic_lock(sc)) {
|
||||
IWM_WRITE(sc, IWM_FH_MEM_RCSR_CHNL0_CONFIG_REG, 0);
|
||||
ret = iwm_poll_bit(sc, IWM_FH_MEM_RSSR_RX_STATUS_REG,
|
||||
IWM_FH_RSSR_CHNL0_RX_STATUS_CHNL_IDLE,
|
||||
IWM_FH_RSSR_CHNL0_RX_STATUS_CHNL_IDLE,
|
||||
1000);
|
||||
iwm_nic_unlock(sc);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
iwm_pcie_clear_cmd_in_flight(struct iwm_softc *sc)
|
||||
{
|
||||
if (!sc->cfg->apmg_wake_up_wa)
|
||||
return;
|
||||
|
||||
if (!sc->cmd_hold_nic_awake) {
|
||||
device_printf(sc->sc_dev,
|
||||
"%s: cmd_hold_nic_awake not set\n", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
sc->cmd_hold_nic_awake = 0;
|
||||
IWM_CLRBITS(sc, IWM_CSR_GP_CNTRL,
|
||||
IWM_CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
|
||||
}
|
||||
|
||||
int
|
||||
iwm_pcie_set_cmd_in_flight(struct iwm_softc *sc)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/*
|
||||
* wake up the NIC to make sure that the firmware will see the host
|
||||
* command - we will let the NIC sleep once all the host commands
|
||||
* returned. This needs to be done only on NICs that have
|
||||
* apmg_wake_up_wa set.
|
||||
*/
|
||||
if (sc->cfg->apmg_wake_up_wa &&
|
||||
!sc->cmd_hold_nic_awake) {
|
||||
|
||||
IWM_SETBITS(sc, IWM_CSR_GP_CNTRL,
|
||||
IWM_CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
|
||||
|
||||
ret = iwm_poll_bit(sc, IWM_CSR_GP_CNTRL,
|
||||
IWM_CSR_GP_CNTRL_REG_VAL_MAC_ACCESS_EN,
|
||||
(IWM_CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY |
|
||||
IWM_CSR_GP_CNTRL_REG_FLAG_GOING_TO_SLEEP),
|
||||
15000);
|
||||
if (ret == 0) {
|
||||
IWM_CLRBITS(sc, IWM_CSR_GP_CNTRL,
|
||||
IWM_CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
|
||||
device_printf(sc->sc_dev,
|
||||
"%s: Failed to wake NIC for hcmd\n", __func__);
|
||||
return EIO;
|
||||
}
|
||||
sc->cmd_hold_nic_awake = 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -129,4 +129,7 @@ extern int iwm_start_hw(struct iwm_softc *sc);
|
||||
extern void iwm_set_pwr(struct iwm_softc *sc);
|
||||
extern int iwm_pcie_rx_stop(struct iwm_softc *sc);
|
||||
|
||||
extern int iwm_pcie_set_cmd_in_flight(struct iwm_softc *sc);
|
||||
extern void iwm_pcie_clear_cmd_in_flight(struct iwm_softc *sc);
|
||||
|
||||
#endif
|
||||
|
@ -153,6 +153,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <dev/iwm/if_iwmreg.h>
|
||||
#include <dev/iwm/if_iwmvar.h>
|
||||
#include <dev/iwm/if_iwm_debug.h>
|
||||
#include <dev/iwm/if_iwm_notif_wait.h>
|
||||
#include <dev/iwm/if_iwm_util.h>
|
||||
#include <dev/iwm/if_iwm_scan.h>
|
||||
|
||||
@ -737,3 +738,86 @@ iwm_mvm_lmac_scan(struct iwm_softc *sc)
|
||||
free(req, M_DEVBUF);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
iwm_mvm_lmac_scan_abort(struct iwm_softc *sc)
|
||||
{
|
||||
int ret;
|
||||
struct iwm_host_cmd hcmd = {
|
||||
.id = IWM_SCAN_OFFLOAD_ABORT_CMD,
|
||||
.len = { 0, },
|
||||
.data = { NULL, },
|
||||
.flags = IWM_CMD_SYNC,
|
||||
};
|
||||
uint32_t status;
|
||||
|
||||
ret = iwm_mvm_send_cmd_status(sc, &hcmd, &status);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (status != IWM_CAN_ABORT_STATUS) {
|
||||
/*
|
||||
* The scan abort will return 1 for success or
|
||||
* 2 for "failure". A failure condition can be
|
||||
* due to simply not being in an active scan which
|
||||
* can occur if we send the scan abort before the
|
||||
* microcode has notified us that a scan is completed.
|
||||
*/
|
||||
IWM_DPRINTF(sc, IWM_DEBUG_SCAN,
|
||||
"SCAN OFFLOAD ABORT ret %d.\n", status);
|
||||
ret = ENOENT;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
iwm_mvm_umac_scan_abort(struct iwm_softc *sc)
|
||||
{
|
||||
struct iwm_umac_scan_abort cmd = {};
|
||||
int uid, ret;
|
||||
|
||||
uid = 0;
|
||||
cmd.uid = htole32(uid);
|
||||
|
||||
IWM_DPRINTF(sc, IWM_DEBUG_SCAN, "Sending scan abort, uid %u\n", uid);
|
||||
|
||||
ret = iwm_mvm_send_cmd_pdu(sc,
|
||||
iwm_cmd_id(IWM_SCAN_ABORT_UMAC,
|
||||
IWM_ALWAYS_LONG_GROUP, 0),
|
||||
0, sizeof(cmd), &cmd);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
iwm_mvm_scan_stop_wait(struct iwm_softc *sc)
|
||||
{
|
||||
struct iwm_notification_wait wait_scan_done;
|
||||
static const uint16_t scan_done_notif[] = { IWM_SCAN_COMPLETE_UMAC,
|
||||
IWM_SCAN_OFFLOAD_COMPLETE, };
|
||||
int ret;
|
||||
|
||||
iwm_init_notification_wait(sc->sc_notif_wait, &wait_scan_done,
|
||||
scan_done_notif, nitems(scan_done_notif),
|
||||
NULL, NULL);
|
||||
|
||||
IWM_DPRINTF(sc, IWM_DEBUG_SCAN, "Preparing to stop scan\n");
|
||||
|
||||
if (isset(sc->sc_enabled_capa, IWM_UCODE_TLV_CAPA_UMAC_SCAN))
|
||||
ret = iwm_mvm_umac_scan_abort(sc);
|
||||
else
|
||||
ret = iwm_mvm_lmac_scan_abort(sc);
|
||||
|
||||
if (ret) {
|
||||
IWM_DPRINTF(sc, IWM_DEBUG_SCAN, "couldn't stop scan\n");
|
||||
iwm_remove_notification(sc->sc_notif_wait, &wait_scan_done);
|
||||
return ret;
|
||||
}
|
||||
|
||||
IWM_UNLOCK(sc);
|
||||
ret = iwm_wait_notification(sc->sc_notif_wait, &wait_scan_done, hz);
|
||||
IWM_LOCK(sc);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -109,5 +109,6 @@
|
||||
extern int iwm_mvm_lmac_scan(struct iwm_softc *sc);
|
||||
extern int iwm_mvm_config_umac_scan(struct iwm_softc *);
|
||||
extern int iwm_mvm_umac_scan(struct iwm_softc *);
|
||||
extern int iwm_mvm_scan_stop_wait(struct iwm_softc *sc);
|
||||
|
||||
#endif /* __IF_IWN_SCAN_H__ */
|
||||
|
@ -305,17 +305,10 @@ iwm_send_cmd(struct iwm_softc *sc, struct iwm_host_cmd *hcmd)
|
||||
bus_dmamap_sync(ring->desc_dma.tag, ring->desc_dma.map,
|
||||
BUS_DMASYNC_PREWRITE);
|
||||
|
||||
IWM_SETBITS(sc, IWM_CSR_GP_CNTRL,
|
||||
IWM_CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
|
||||
if (!iwm_poll_bit(sc, IWM_CSR_GP_CNTRL,
|
||||
IWM_CSR_GP_CNTRL_REG_VAL_MAC_ACCESS_EN,
|
||||
(IWM_CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY |
|
||||
IWM_CSR_GP_CNTRL_REG_FLAG_GOING_TO_SLEEP), 15000)) {
|
||||
device_printf(sc->sc_dev,
|
||||
"%s: acquiring device failed\n", __func__);
|
||||
error = EBUSY;
|
||||
error = iwm_pcie_set_cmd_in_flight(sc);
|
||||
if (error)
|
||||
goto out;
|
||||
}
|
||||
ring->queued++;
|
||||
|
||||
#if 0
|
||||
iwm_update_sched(sc, ring->qid, ring->cur, 0, 0);
|
||||
|
@ -1006,6 +1006,7 @@ enum iwm_ucode_tlv_type {
|
||||
IWM_UCODE_TLV_FW_DBG_CONF = 39,
|
||||
IWM_UCODE_TLV_FW_DBG_TRIGGER = 40,
|
||||
IWM_UCODE_TLV_FW_GSCAN_CAPA = 50,
|
||||
IWM_UCODE_TLV_FW_MEM_SEG = 51,
|
||||
};
|
||||
|
||||
struct iwm_ucode_tlv {
|
||||
@ -1949,6 +1950,25 @@ enum {
|
||||
IWM_REPLY_MAX = 0xff,
|
||||
};
|
||||
|
||||
enum iwm_phy_ops_subcmd_ids {
|
||||
IWM_CMD_DTS_MEASUREMENT_TRIGGER_WIDE = 0x0,
|
||||
IWM_CTDP_CONFIG_CMD = 0x03,
|
||||
IWM_TEMP_REPORTING_THRESHOLDS_CMD = 0x04,
|
||||
IWM_CT_KILL_NOTIFICATION = 0xFE,
|
||||
IWM_DTS_MEASUREMENT_NOTIF_WIDE = 0xFF,
|
||||
};
|
||||
|
||||
/* command groups */
|
||||
enum {
|
||||
IWM_LEGACY_GROUP = 0x0,
|
||||
IWM_LONG_GROUP = 0x1,
|
||||
IWM_SYSTEM_GROUP = 0x2,
|
||||
IWM_MAC_CONF_GROUP = 0x3,
|
||||
IWM_PHY_OPS_GROUP = 0x4,
|
||||
IWM_DATA_PATH_GROUP = 0x5,
|
||||
IWM_PROT_OFFLOAD_GROUP = 0xb,
|
||||
};
|
||||
|
||||
/**
|
||||
* struct iwm_cmd_response - generic response struct for most commands
|
||||
* @status: status of the command asked, changes for each one
|
||||
@ -5978,6 +5998,30 @@ enum iwm_mcc_source {
|
||||
IWM_MCC_SOURCE_GETTING_MCC_TEST_MODE = 0x11,
|
||||
};
|
||||
|
||||
/**
|
||||
* struct iwm_dts_measurement_notif_v1 - measurements notification
|
||||
*
|
||||
* @temp: the measured temperature
|
||||
* @voltage: the measured voltage
|
||||
*/
|
||||
struct iwm_dts_measurement_notif_v1 {
|
||||
int32_t temp;
|
||||
int32_t voltage;
|
||||
} __packed; /* TEMPERATURE_MEASUREMENT_TRIGGER_NTFY_S_VER_1*/
|
||||
|
||||
/**
|
||||
* struct iwm_dts_measurement_notif_v2 - measurements notification
|
||||
*
|
||||
* @temp: the measured temperature
|
||||
* @voltage: the measured voltage
|
||||
* @threshold_idx: the trip index that was crossed
|
||||
*/
|
||||
struct iwm_dts_measurement_notif_v2 {
|
||||
int32_t temp;
|
||||
int32_t voltage;
|
||||
int32_t threshold_idx;
|
||||
} __packed; /* TEMPERATURE_MEASUREMENT_TRIGGER_NTFY_S_VER_2 */
|
||||
|
||||
/*
|
||||
* Some cherry-picked definitions
|
||||
*/
|
||||
|
@ -389,6 +389,8 @@ enum iwm_device_family {
|
||||
* @host_interrupt_operation_mode: device needs host interrupt operation
|
||||
* mode set
|
||||
* @nvm_hw_section_num: the ID of the HW NVM section
|
||||
* @apmg_wake_up_wa: should the MAC access REQ be asserted when a command
|
||||
* is in flight. This is due to a HW bug in 7260, 3160 and 7265.
|
||||
*/
|
||||
struct iwm_cfg {
|
||||
const char *fw_name;
|
||||
@ -396,6 +398,7 @@ struct iwm_cfg {
|
||||
enum iwm_device_family device_family;
|
||||
int host_interrupt_operation_mode;
|
||||
uint8_t nvm_hw_section_num;
|
||||
int apmg_wake_up_wa;
|
||||
};
|
||||
|
||||
struct iwm_softc {
|
||||
@ -415,6 +418,7 @@ struct iwm_softc {
|
||||
#define IWM_FLAG_RFKILL (1 << 3)
|
||||
#define IWM_FLAG_BUSY (1 << 4)
|
||||
#define IWM_FLAG_SCANNING (1 << 5)
|
||||
#define IWM_FLAG_SCAN_RUNNING (1 << 6)
|
||||
|
||||
struct intr_config_hook sc_preinit_hook;
|
||||
struct callout sc_watchdog_to;
|
||||
@ -520,6 +524,8 @@ struct iwm_softc {
|
||||
int sc_max_rssi;
|
||||
|
||||
struct iwm_notif_wait_data *sc_notif_wait;
|
||||
|
||||
int cmd_hold_nic_awake;
|
||||
};
|
||||
|
||||
#define IWM_LOCK_INIT(_sc) \
|
||||
|
@ -227,11 +227,14 @@ struct g_class g_journal_class = {
|
||||
|
||||
static int g_journal_destroy(struct g_journal_softc *sc);
|
||||
static void g_journal_metadata_update(struct g_journal_softc *sc);
|
||||
static void g_journal_start_switcher(struct g_class *mp);
|
||||
static void g_journal_stop_switcher(void);
|
||||
static void g_journal_switch_wait(struct g_journal_softc *sc);
|
||||
|
||||
#define GJ_SWITCHER_WORKING 0
|
||||
#define GJ_SWITCHER_DIE 1
|
||||
#define GJ_SWITCHER_DIED 2
|
||||
static struct proc *g_journal_switcher_proc = NULL;
|
||||
static int g_journal_switcher_state = GJ_SWITCHER_WORKING;
|
||||
static int g_journal_switcher_wokenup = 0;
|
||||
static int g_journal_sync_requested = 0;
|
||||
@ -2383,6 +2386,10 @@ g_journal_create(struct g_class *mp, struct g_provider *pp,
|
||||
sc->sc_jconsumer = cp;
|
||||
}
|
||||
|
||||
/* Start switcher kproc if needed. */
|
||||
if (g_journal_switcher_proc == NULL)
|
||||
g_journal_start_switcher(mp);
|
||||
|
||||
if ((sc->sc_type & GJ_TYPE_COMPLETE) != GJ_TYPE_COMPLETE) {
|
||||
/* Journal is not complete yet. */
|
||||
return (gp);
|
||||
@ -2759,7 +2766,6 @@ static void g_journal_switcher(void *arg);
|
||||
static void
|
||||
g_journal_init(struct g_class *mp)
|
||||
{
|
||||
int error;
|
||||
|
||||
/* Pick a conservative value if provided value sucks. */
|
||||
if (g_journal_cache_divisor <= 0 ||
|
||||
@ -2779,9 +2785,6 @@ g_journal_init(struct g_class *mp)
|
||||
g_journal_lowmem, mp, EVENTHANDLER_PRI_FIRST);
|
||||
if (g_journal_event_lowmem == NULL)
|
||||
GJ_DEBUG(0, "Warning! Cannot register lowmem event.");
|
||||
error = kproc_create(g_journal_switcher, mp, NULL, 0, 0,
|
||||
"g_journal switcher");
|
||||
KASSERT(error == 0, ("Cannot create switcher thread."));
|
||||
}
|
||||
|
||||
static void
|
||||
@ -2794,11 +2797,7 @@ g_journal_fini(struct g_class *mp)
|
||||
}
|
||||
if (g_journal_event_lowmem != NULL)
|
||||
EVENTHANDLER_DEREGISTER(vm_lowmem, g_journal_event_lowmem);
|
||||
g_journal_switcher_state = GJ_SWITCHER_DIE;
|
||||
wakeup(&g_journal_switcher_state);
|
||||
while (g_journal_switcher_state != GJ_SWITCHER_DIED)
|
||||
tsleep(&g_journal_switcher_state, PRIBIO, "jfini:wait", hz / 5);
|
||||
GJ_DEBUG(1, "Switcher died.");
|
||||
g_journal_stop_switcher();
|
||||
}
|
||||
|
||||
DECLARE_GEOM_CLASS(g_journal_class, g_journal);
|
||||
@ -2998,9 +2997,34 @@ next:
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
g_journal_start_switcher(struct g_class *mp)
|
||||
{
|
||||
int error;
|
||||
|
||||
g_topology_assert();
|
||||
MPASS(g_journal_switcher_proc == NULL);
|
||||
g_journal_switcher_state = GJ_SWITCHER_WORKING;
|
||||
error = kproc_create(g_journal_switcher, mp, &g_journal_switcher_proc,
|
||||
0, 0, "g_journal switcher");
|
||||
KASSERT(error == 0, ("Cannot create switcher thread."));
|
||||
}
|
||||
|
||||
static void
|
||||
g_journal_stop_switcher(void)
|
||||
{
|
||||
g_topology_assert();
|
||||
MPASS(g_journal_switcher_proc != NULL);
|
||||
g_journal_switcher_state = GJ_SWITCHER_DIE;
|
||||
wakeup(&g_journal_switcher_state);
|
||||
while (g_journal_switcher_state != GJ_SWITCHER_DIED)
|
||||
tsleep(&g_journal_switcher_state, PRIBIO, "jfini:wait", hz / 5);
|
||||
GJ_DEBUG(1, "Switcher died.");
|
||||
g_journal_switcher_proc = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* TODO: Switcher thread should be started on first geom creation and killed on
|
||||
* last geom destruction.
|
||||
* TODO: Kill switcher thread on last geom destruction?
|
||||
*/
|
||||
static void
|
||||
g_journal_switcher(void *arg)
|
||||
|
@ -1055,6 +1055,8 @@ __CONCAT(exec_, __elfN(imgact))(struct image_params *imgp)
|
||||
imgp->interpreted = 0;
|
||||
imgp->reloc_base = addr;
|
||||
imgp->proc->p_osrel = osrel;
|
||||
imgp->proc->p_elf_machine = hdr->e_machine;
|
||||
imgp->proc->p_elf_flags = hdr->e_flags;
|
||||
|
||||
ret:
|
||||
free(interp_buf, M_TEMP);
|
||||
@ -1655,15 +1657,11 @@ __elfN(puthdr)(struct thread *td, void *hdr, size_t hdrsize, int numsegs,
|
||||
ehdr->e_ident[EI_ABIVERSION] = 0;
|
||||
ehdr->e_ident[EI_PAD] = 0;
|
||||
ehdr->e_type = ET_CORE;
|
||||
#if defined(COMPAT_FREEBSD32) && __ELF_WORD_SIZE == 32
|
||||
ehdr->e_machine = ELF_ARCH32;
|
||||
#else
|
||||
ehdr->e_machine = ELF_ARCH;
|
||||
#endif
|
||||
ehdr->e_machine = td->td_proc->p_elf_machine;
|
||||
ehdr->e_version = EV_CURRENT;
|
||||
ehdr->e_entry = 0;
|
||||
ehdr->e_phoff = sizeof(Elf_Ehdr);
|
||||
ehdr->e_flags = 0;
|
||||
ehdr->e_flags = td->td_proc->p_elf_flags;
|
||||
ehdr->e_ehsize = sizeof(Elf_Ehdr);
|
||||
ehdr->e_phentsize = sizeof(Elf_Phdr);
|
||||
ehdr->e_shentsize = sizeof(Elf_Shdr);
|
||||
|
@ -1,6 +1,6 @@
|
||||
# $FreeBSD$
|
||||
|
||||
KMOD= iwm3160fw
|
||||
IMG= iwm-3160-16
|
||||
IMG= iwm-3160-17
|
||||
|
||||
.include <bsd.kmod.mk>
|
||||
|
@ -1,6 +1,6 @@
|
||||
# $FreeBSD$
|
||||
|
||||
KMOD= iwm7260fw
|
||||
IMG= iwm-7260-16
|
||||
IMG= iwm-7260-17
|
||||
|
||||
.include <bsd.kmod.mk>
|
||||
|
@ -1,6 +1,6 @@
|
||||
# $FreeBSD$
|
||||
|
||||
KMOD= iwm7265fw
|
||||
IMG= iwm-7265-16
|
||||
IMG= iwm-7265-17
|
||||
|
||||
.include <bsd.kmod.mk>
|
||||
|
@ -617,8 +617,11 @@ struct proc {
|
||||
our subtree. */
|
||||
u_int p_xexit; /* (c) Exit code. */
|
||||
u_int p_xsig; /* (c) Stop/kill sig. */
|
||||
uint16_t p_elf_machine; /* (x) ELF machine type */
|
||||
uint64_t p_elf_flags; /* (x) ELF flags */
|
||||
|
||||
/* End area that is copied on creation. */
|
||||
#define p_endcopy p_xsig
|
||||
#define p_endcopy p_elf_flags
|
||||
struct pgrp *p_pgrp; /* (c + e) Pointer to process group. */
|
||||
struct knlist *p_klist; /* (c) Knotes attached to this proc. */
|
||||
int p_numthreads; /* (c) Number of threads. */
|
||||
|
@ -117,8 +117,8 @@ static void *elf_note_procstat_psstrings(void *, size_t *);
|
||||
static void *elf_note_procstat_rlimit(void *, size_t *);
|
||||
static void *elf_note_procstat_umask(void *, size_t *);
|
||||
static void *elf_note_procstat_vmmap(void *, size_t *);
|
||||
static void elf_puthdr(pid_t, vm_map_entry_t, void *, size_t, size_t, size_t,
|
||||
int);
|
||||
static void elf_puthdr(int, pid_t, vm_map_entry_t, void *, size_t, size_t,
|
||||
size_t, int);
|
||||
static void elf_putnote(int, notefunc_t, void *, struct sbuf *);
|
||||
static void elf_putnotes(pid_t, struct sbuf *, size_t *);
|
||||
static void freemap(vm_map_entry_t);
|
||||
@ -178,7 +178,7 @@ elf_detach(void)
|
||||
* Write an ELF coredump for the given pid to the given fd.
|
||||
*/
|
||||
static void
|
||||
elf_coredump(int efd __unused, int fd, pid_t pid)
|
||||
elf_coredump(int efd, int fd, pid_t pid)
|
||||
{
|
||||
vm_map_entry_t map;
|
||||
struct sseg_closure seginfo;
|
||||
@ -230,7 +230,7 @@ elf_coredump(int efd __unused, int fd, pid_t pid)
|
||||
hdr = sbuf_data(sb);
|
||||
segoff = sbuf_len(sb);
|
||||
/* Fill in the header. */
|
||||
elf_puthdr(pid, map, hdr, hdrsize, notesz, segoff, seginfo.count);
|
||||
elf_puthdr(efd, pid, map, hdr, hdrsize, notesz, segoff, seginfo.count);
|
||||
|
||||
n = write(fd, hdr, segoff);
|
||||
if (n == -1)
|
||||
@ -420,14 +420,21 @@ elf_putnote(int type, notefunc_t notefunc, void *arg, struct sbuf *sb)
|
||||
* Generate the ELF coredump header.
|
||||
*/
|
||||
static void
|
||||
elf_puthdr(pid_t pid, vm_map_entry_t map, void *hdr, size_t hdrsize,
|
||||
elf_puthdr(int efd, pid_t pid, vm_map_entry_t map, void *hdr, size_t hdrsize,
|
||||
size_t notesz, size_t segoff, int numsegs)
|
||||
{
|
||||
Elf_Ehdr *ehdr;
|
||||
Elf_Ehdr *ehdr, binhdr;
|
||||
Elf_Phdr *phdr;
|
||||
Elf_Shdr *shdr;
|
||||
struct phdr_closure phc;
|
||||
ssize_t cnt;
|
||||
|
||||
cnt = read(efd, &binhdr, sizeof(binhdr));
|
||||
if (cnt < 0)
|
||||
err(1, "Failed to re-read ELF header");
|
||||
else if (cnt != sizeof(binhdr))
|
||||
errx(1, "Failed to re-read ELF header");
|
||||
|
||||
ehdr = (Elf_Ehdr *)hdr;
|
||||
|
||||
ehdr->e_ident[EI_MAG0] = ELFMAG0;
|
||||
@ -441,11 +448,11 @@ elf_puthdr(pid_t pid, vm_map_entry_t map, void *hdr, size_t hdrsize,
|
||||
ehdr->e_ident[EI_ABIVERSION] = 0;
|
||||
ehdr->e_ident[EI_PAD] = 0;
|
||||
ehdr->e_type = ET_CORE;
|
||||
ehdr->e_machine = ELF_ARCH;
|
||||
ehdr->e_machine = binhdr.e_machine;
|
||||
ehdr->e_version = EV_CURRENT;
|
||||
ehdr->e_entry = 0;
|
||||
ehdr->e_phoff = sizeof(Elf_Ehdr);
|
||||
ehdr->e_flags = 0;
|
||||
ehdr->e_flags = binhdr.e_flags;
|
||||
ehdr->e_ehsize = sizeof(Elf_Ehdr);
|
||||
ehdr->e_phentsize = sizeof(Elf_Phdr);
|
||||
ehdr->e_shentsize = sizeof(Elf_Shdr);
|
||||
|
@ -85,7 +85,7 @@ part_config(char *disk, const char *scheme, char *config)
|
||||
LIST_FOREACH(classp, &mesh.lg_class, lg_class)
|
||||
if (strcmp(classp->lg_name, "PART") == 0)
|
||||
break;
|
||||
if (classp != NULL) {
|
||||
if (classp != NULL) {
|
||||
LIST_FOREACH(gpart, &classp->lg_geom, lg_geom)
|
||||
if (strcmp(gpart->lg_name, disk) == 0)
|
||||
break;
|
||||
|
Loading…
x
Reference in New Issue
Block a user