|
Lines 322-337
static int iwm_mvm_load_ucode_wait_alive(struct iwm_softc *,
Link Here
|
| 322 |
static int iwm_run_init_mvm_ucode(struct iwm_softc *, int); |
322 |
static int iwm_run_init_mvm_ucode(struct iwm_softc *, int); |
| 323 |
static int iwm_mvm_config_ltr(struct iwm_softc *sc); |
323 |
static int iwm_mvm_config_ltr(struct iwm_softc *sc); |
| 324 |
static int iwm_rx_addbuf(struct iwm_softc *, int, int); |
324 |
static int iwm_rx_addbuf(struct iwm_softc *, int, int); |
| 325 |
static int iwm_mvm_get_signal_strength(struct iwm_softc *, |
|
|
| 326 |
struct iwm_rx_phy_info *); |
| 327 |
static void iwm_mvm_rx_rx_phy_cmd(struct iwm_softc *, |
325 |
static void iwm_mvm_rx_rx_phy_cmd(struct iwm_softc *, |
| 328 |
struct iwm_rx_packet *); |
326 |
struct iwm_rx_packet *); |
| 329 |
static int iwm_get_noise(struct iwm_softc *, |
327 |
static int iwm_get_noise(struct iwm_softc *, |
| 330 |
const struct iwm_mvm_statistics_rx_non_phy *); |
328 |
const struct iwm_mvm_statistics_rx_non_phy *); |
| 331 |
static void iwm_mvm_handle_rx_statistics(struct iwm_softc *, |
329 |
static void iwm_mvm_handle_rx_statistics(struct iwm_softc *, |
| 332 |
struct iwm_rx_packet *); |
330 |
struct iwm_rx_packet *); |
| 333 |
static boolean_t iwm_mvm_rx_rx_mpdu(struct iwm_softc *, struct mbuf *, |
331 |
static bool iwm_mvm_rx_mpdu(struct iwm_softc *, struct mbuf *, |
| 334 |
uint32_t, boolean_t); |
332 |
uint32_t, bool); |
| 335 |
static int iwm_mvm_rx_tx_cmd_single(struct iwm_softc *, |
333 |
static int iwm_mvm_rx_tx_cmd_single(struct iwm_softc *, |
| 336 |
struct iwm_rx_packet *, |
334 |
struct iwm_rx_packet *, |
| 337 |
struct iwm_node *); |
335 |
struct iwm_node *); |
|
Lines 793-799
iwm_read_firmware(struct iwm_softc *sc)
Link Here
|
| 793 |
break; |
791 |
break; |
| 794 |
} |
792 |
} |
| 795 |
|
793 |
|
| 796 |
case 48: /* undocumented TLV */ |
794 |
case IWM_UCODE_TLV_CMD_VERSIONS: |
| 797 |
case IWM_UCODE_TLV_SDIO_ADMA_ADDR: |
795 |
case IWM_UCODE_TLV_SDIO_ADMA_ADDR: |
| 798 |
case IWM_UCODE_TLV_FW_GSCAN_CAPA: |
796 |
case IWM_UCODE_TLV_FW_GSCAN_CAPA: |
| 799 |
/* ignore, not used by current driver */ |
797 |
/* ignore, not used by current driver */ |
|
Lines 864-873
iwm_read_firmware(struct iwm_softc *sc)
Link Here
|
| 864 |
|
862 |
|
| 865 |
default: |
863 |
default: |
| 866 |
device_printf(sc->sc_dev, |
864 |
device_printf(sc->sc_dev, |
| 867 |
"%s: unknown firmware section %d, abort\n", |
865 |
"%s: unknown firmware section %d\n", |
| 868 |
__func__, tlv_type); |
866 |
__func__, tlv_type); |
| 869 |
error = EINVAL; |
867 |
break; |
| 870 |
goto parse_out; |
|
|
| 871 |
} |
868 |
} |
| 872 |
} |
869 |
} |
| 873 |
|
870 |
|
|
Lines 929-947
static int
Link Here
|
| 929 |
iwm_alloc_rx_ring(struct iwm_softc *sc, struct iwm_rx_ring *ring) |
926 |
iwm_alloc_rx_ring(struct iwm_softc *sc, struct iwm_rx_ring *ring) |
| 930 |
{ |
927 |
{ |
| 931 |
bus_size_t size; |
928 |
bus_size_t size; |
| 932 |
int i, error; |
929 |
size_t descsz; |
|
|
930 |
int count, i, error; |
| 933 |
|
931 |
|
| 934 |
ring->cur = 0; |
932 |
ring->cur = 0; |
|
|
933 |
if (sc->cfg->mqrx_supported) { |
| 934 |
count = IWM_RX_MQ_RING_COUNT; |
| 935 |
descsz = sizeof(uint64_t); |
| 936 |
} else { |
| 937 |
count = IWM_RX_LEGACY_RING_COUNT; |
| 938 |
descsz = sizeof(uint32_t); |
| 939 |
} |
| 935 |
|
940 |
|
| 936 |
/* Allocate RX descriptors (256-byte aligned). */ |
941 |
/* Allocate RX descriptors (256-byte aligned). */ |
| 937 |
size = IWM_RX_RING_COUNT * sizeof(uint32_t); |
942 |
size = count * descsz; |
| 938 |
error = iwm_dma_contig_alloc(sc->sc_dmat, &ring->desc_dma, size, 256); |
943 |
error = iwm_dma_contig_alloc(sc->sc_dmat, &ring->free_desc_dma, size, |
|
|
944 |
256); |
| 939 |
if (error != 0) { |
945 |
if (error != 0) { |
| 940 |
device_printf(sc->sc_dev, |
946 |
device_printf(sc->sc_dev, |
| 941 |
"could not allocate RX ring DMA memory\n"); |
947 |
"could not allocate RX ring DMA memory\n"); |
| 942 |
goto fail; |
948 |
goto fail; |
| 943 |
} |
949 |
} |
| 944 |
ring->desc = ring->desc_dma.vaddr; |
950 |
ring->desc = ring->free_desc_dma.vaddr; |
| 945 |
|
951 |
|
| 946 |
/* Allocate RX status area (16-byte aligned). */ |
952 |
/* Allocate RX status area (16-byte aligned). */ |
| 947 |
error = iwm_dma_contig_alloc(sc->sc_dmat, &ring->stat_dma, |
953 |
error = iwm_dma_contig_alloc(sc->sc_dmat, &ring->stat_dma, |
|
Lines 953-958
iwm_alloc_rx_ring(struct iwm_softc *sc, struct iwm_rx_ring *ring)
Link Here
|
| 953 |
} |
959 |
} |
| 954 |
ring->stat = ring->stat_dma.vaddr; |
960 |
ring->stat = ring->stat_dma.vaddr; |
| 955 |
|
961 |
|
|
|
962 |
if (sc->cfg->mqrx_supported) { |
| 963 |
size = count * sizeof(uint32_t); |
| 964 |
error = iwm_dma_contig_alloc(sc->sc_dmat, &ring->used_desc_dma, |
| 965 |
size, 256); |
| 966 |
if (error != 0) { |
| 967 |
device_printf(sc->sc_dev, |
| 968 |
"could not allocate RX ring DMA memory\n"); |
| 969 |
goto fail; |
| 970 |
} |
| 971 |
} |
| 972 |
|
| 956 |
/* Create RX buffer DMA tag. */ |
973 |
/* Create RX buffer DMA tag. */ |
| 957 |
error = bus_dma_tag_create(sc->sc_dmat, 1, 0, |
974 |
error = bus_dma_tag_create(sc->sc_dmat, 1, 0, |
| 958 |
BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL, |
975 |
BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL, |
|
Lines 972-981
iwm_alloc_rx_ring(struct iwm_softc *sc, struct iwm_rx_ring *ring)
Link Here
|
| 972 |
__func__, error); |
989 |
__func__, error); |
| 973 |
goto fail; |
990 |
goto fail; |
| 974 |
} |
991 |
} |
|
|
992 |
|
| 975 |
/* |
993 |
/* |
| 976 |
* Allocate and map RX buffers. |
994 |
* Allocate and map RX buffers. |
| 977 |
*/ |
995 |
*/ |
| 978 |
for (i = 0; i < IWM_RX_RING_COUNT; i++) { |
996 |
for (i = 0; i < count; i++) { |
| 979 |
struct iwm_rx_data *data = &ring->data[i]; |
997 |
struct iwm_rx_data *data = &ring->data[i]; |
| 980 |
error = bus_dmamap_create(ring->data_dmat, 0, &data->map); |
998 |
error = bus_dmamap_create(ring->data_dmat, 0, &data->map); |
| 981 |
if (error != 0) { |
999 |
if (error != 0) { |
|
Lines 1013-1024
iwm_reset_rx_ring(struct iwm_softc *sc, struct iwm_rx_ring *ring)
Link Here
|
| 1013 |
static void |
1031 |
static void |
| 1014 |
iwm_free_rx_ring(struct iwm_softc *sc, struct iwm_rx_ring *ring) |
1032 |
iwm_free_rx_ring(struct iwm_softc *sc, struct iwm_rx_ring *ring) |
| 1015 |
{ |
1033 |
{ |
| 1016 |
int i; |
1034 |
int count, i; |
| 1017 |
|
1035 |
|
| 1018 |
iwm_dma_contig_free(&ring->desc_dma); |
1036 |
iwm_dma_contig_free(&ring->free_desc_dma); |
| 1019 |
iwm_dma_contig_free(&ring->stat_dma); |
1037 |
iwm_dma_contig_free(&ring->stat_dma); |
|
|
1038 |
iwm_dma_contig_free(&ring->used_desc_dma); |
| 1039 |
|
| 1040 |
count = sc->cfg->mqrx_supported ? IWM_RX_MQ_RING_COUNT : |
| 1041 |
IWM_RX_LEGACY_RING_COUNT; |
| 1020 |
|
1042 |
|
| 1021 |
for (i = 0; i < IWM_RX_RING_COUNT; i++) { |
1043 |
for (i = 0; i < count; i++) { |
| 1022 |
struct iwm_rx_data *data = &ring->data[i]; |
1044 |
struct iwm_rx_data *data = &ring->data[i]; |
| 1023 |
|
1045 |
|
| 1024 |
if (data->m != NULL) { |
1046 |
if (data->m != NULL) { |
|
Lines 1315-1326
iwm_stop_device(struct iwm_softc *sc)
Link Here
|
| 1315 |
/* Stop the device, and put it in low power state */ |
1337 |
/* Stop the device, and put it in low power state */ |
| 1316 |
iwm_apm_stop(sc); |
1338 |
iwm_apm_stop(sc); |
| 1317 |
|
1339 |
|
| 1318 |
/* Upon stop, the APM issues an interrupt if HW RF kill is set. |
1340 |
/* stop and reset the on-board processor */ |
| 1319 |
* Clean again the interrupt here |
1341 |
IWM_SETBITS(sc, IWM_CSR_RESET, IWM_CSR_RESET_REG_FLAG_SW_RESET); |
|
|
1342 |
DELAY(5000); |
| 1343 |
|
| 1344 |
/* |
| 1345 |
* Upon stop, the APM issues an interrupt if HW RF kill is set. |
| 1320 |
*/ |
1346 |
*/ |
| 1321 |
iwm_disable_interrupts(sc); |
1347 |
iwm_disable_interrupts(sc); |
| 1322 |
/* stop and reset the on-board processor */ |
|
|
| 1323 |
IWM_WRITE(sc, IWM_CSR_RESET, IWM_CSR_RESET_REG_FLAG_SW_RESET); |
| 1324 |
|
1348 |
|
| 1325 |
/* |
1349 |
/* |
| 1326 |
* Even if we stop the HW, we still want the RF kill |
1350 |
* Even if we stop the HW, we still want the RF kill |
|
Lines 1328-1333
iwm_stop_device(struct iwm_softc *sc)
Link Here
|
| 1328 |
*/ |
1352 |
*/ |
| 1329 |
iwm_enable_rfkill_int(sc); |
1353 |
iwm_enable_rfkill_int(sc); |
| 1330 |
iwm_check_rfkill(sc); |
1354 |
iwm_check_rfkill(sc); |
|
|
1355 |
|
| 1356 |
iwm_prepare_card_hw(sc); |
| 1331 |
} |
1357 |
} |
| 1332 |
|
1358 |
|
| 1333 |
/* iwlwifi: mvm/ops.c */ |
1359 |
/* iwlwifi: mvm/ops.c */ |
|
Lines 1356-1362
iwm_mvm_nic_config(struct iwm_softc *sc)
Link Here
|
| 1356 |
reg_val |= radio_cfg_step << IWM_CSR_HW_IF_CONFIG_REG_POS_PHY_STEP; |
1382 |
reg_val |= radio_cfg_step << IWM_CSR_HW_IF_CONFIG_REG_POS_PHY_STEP; |
| 1357 |
reg_val |= radio_cfg_dash << IWM_CSR_HW_IF_CONFIG_REG_POS_PHY_DASH; |
1383 |
reg_val |= radio_cfg_dash << IWM_CSR_HW_IF_CONFIG_REG_POS_PHY_DASH; |
| 1358 |
|
1384 |
|
| 1359 |
IWM_WRITE(sc, IWM_CSR_HW_IF_CONFIG_REG, reg_val); |
1385 |
IWM_WRITE(sc, IWM_CSR_HW_IF_CONFIG_REG, |
|
|
1386 |
IWM_CSR_HW_IF_CONFIG_REG_MSK_MAC_DASH | |
| 1387 |
IWM_CSR_HW_IF_CONFIG_REG_MSK_MAC_STEP | |
| 1388 |
IWM_CSR_HW_IF_CONFIG_REG_MSK_PHY_STEP | |
| 1389 |
IWM_CSR_HW_IF_CONFIG_REG_MSK_PHY_DASH | |
| 1390 |
IWM_CSR_HW_IF_CONFIG_REG_MSK_PHY_TYPE | |
| 1391 |
IWM_CSR_HW_IF_CONFIG_REG_BIT_RADIO_SI | |
| 1392 |
IWM_CSR_HW_IF_CONFIG_REG_BIT_MAC_SI | |
| 1393 |
reg_val); |
| 1360 |
|
1394 |
|
| 1361 |
IWM_DPRINTF(sc, IWM_DEBUG_RESET, |
1395 |
IWM_DPRINTF(sc, IWM_DEBUG_RESET, |
| 1362 |
"Radio type=0x%x-0x%x-0x%x\n", radio_cfg_type, |
1396 |
"Radio type=0x%x-0x%x-0x%x\n", radio_cfg_type, |
|
Lines 1375-1386
iwm_mvm_nic_config(struct iwm_softc *sc)
Link Here
|
| 1375 |
} |
1409 |
} |
| 1376 |
|
1410 |
|
| 1377 |
static int |
1411 |
static int |
| 1378 |
iwm_nic_rx_init(struct iwm_softc *sc) |
1412 |
iwm_nic_rx_mq_init(struct iwm_softc *sc) |
|
|
1413 |
{ |
| 1414 |
int enabled; |
| 1415 |
|
| 1416 |
if (!iwm_nic_lock(sc)) |
| 1417 |
return EBUSY; |
| 1418 |
|
| 1419 |
/* Stop RX DMA. */ |
| 1420 |
iwm_write_prph(sc, IWM_RFH_RXF_DMA_CFG, 0); |
| 1421 |
/* Disable RX used and free queue operation. */ |
| 1422 |
iwm_write_prph(sc, IWM_RFH_RXF_RXQ_ACTIVE, 0); |
| 1423 |
|
| 1424 |
iwm_write_prph64(sc, IWM_RFH_Q0_FRBDCB_BA_LSB, |
| 1425 |
sc->rxq.free_desc_dma.paddr); |
| 1426 |
iwm_write_prph64(sc, IWM_RFH_Q0_URBDCB_BA_LSB, |
| 1427 |
sc->rxq.used_desc_dma.paddr); |
| 1428 |
iwm_write_prph64(sc, IWM_RFH_Q0_URBD_STTS_WPTR_LSB, |
| 1429 |
sc->rxq.stat_dma.paddr); |
| 1430 |
iwm_write_prph(sc, IWM_RFH_Q0_FRBDCB_WIDX, 0); |
| 1431 |
iwm_write_prph(sc, IWM_RFH_Q0_FRBDCB_RIDX, 0); |
| 1432 |
iwm_write_prph(sc, IWM_RFH_Q0_URBDCB_WIDX, 0); |
| 1433 |
|
| 1434 |
/* We configure only queue 0 for now. */ |
| 1435 |
enabled = ((1 << 0) << 16) | (1 << 0); |
| 1436 |
|
| 1437 |
/* Enable RX DMA, 4KB buffer size. */ |
| 1438 |
iwm_write_prph(sc, IWM_RFH_RXF_DMA_CFG, |
| 1439 |
IWM_RFH_DMA_EN_ENABLE_VAL | |
| 1440 |
IWM_RFH_RXF_DMA_RB_SIZE_4K | |
| 1441 |
IWM_RFH_RXF_DMA_MIN_RB_4_8 | |
| 1442 |
IWM_RFH_RXF_DMA_DROP_TOO_LARGE_MASK | |
| 1443 |
IWM_RFH_RXF_DMA_RBDCB_SIZE_512); |
| 1444 |
|
| 1445 |
/* Enable RX DMA snooping. */ |
| 1446 |
iwm_write_prph(sc, IWM_RFH_GEN_CFG, |
| 1447 |
IWM_RFH_GEN_CFG_RFH_DMA_SNOOP | |
| 1448 |
IWM_RFH_GEN_CFG_SERVICE_DMA_SNOOP | |
| 1449 |
(sc->cfg->integrated ? IWM_RFH_GEN_CFG_RB_CHUNK_SIZE_64 : |
| 1450 |
IWM_RFH_GEN_CFG_RB_CHUNK_SIZE_128)); |
| 1451 |
|
| 1452 |
/* Enable the configured queue(s). */ |
| 1453 |
iwm_write_prph(sc, IWM_RFH_RXF_RXQ_ACTIVE, enabled); |
| 1454 |
|
| 1455 |
iwm_nic_unlock(sc); |
| 1456 |
|
| 1457 |
IWM_WRITE_1(sc, IWM_CSR_INT_COALESCING, IWM_HOST_INT_TIMEOUT_DEF); |
| 1458 |
|
| 1459 |
IWM_WRITE(sc, IWM_RFH_Q0_FRBDCB_WIDX_TRG, 8); |
| 1460 |
|
| 1461 |
return (0); |
| 1462 |
} |
| 1463 |
|
| 1464 |
static int |
| 1465 |
iwm_nic_rx_legacy_init(struct iwm_softc *sc) |
| 1379 |
{ |
1466 |
{ |
| 1380 |
/* |
|
|
| 1381 |
* Initialize RX ring. This is from the iwn driver. |
| 1382 |
*/ |
| 1383 |
memset(sc->rxq.stat, 0, sizeof(*sc->rxq.stat)); |
| 1384 |
|
1467 |
|
| 1385 |
/* Stop Rx DMA */ |
1468 |
/* Stop Rx DMA */ |
| 1386 |
iwm_pcie_rx_stop(sc); |
1469 |
iwm_pcie_rx_stop(sc); |
|
Lines 1396-1402
iwm_nic_rx_init(struct iwm_softc *sc)
Link Here
|
| 1396 |
|
1479 |
|
| 1397 |
/* Set physical address of RX ring (256-byte aligned). */ |
1480 |
/* Set physical address of RX ring (256-byte aligned). */ |
| 1398 |
IWM_WRITE(sc, |
1481 |
IWM_WRITE(sc, |
| 1399 |
IWM_FH_RSCSR_CHNL0_RBDCB_BASE_REG, sc->rxq.desc_dma.paddr >> 8); |
1482 |
IWM_FH_RSCSR_CHNL0_RBDCB_BASE_REG, |
|
|
1483 |
sc->rxq.free_desc_dma.paddr >> 8); |
| 1400 |
|
1484 |
|
| 1401 |
/* Set physical address of RX status (16-byte aligned). */ |
1485 |
/* Set physical address of RX status (16-byte aligned). */ |
| 1402 |
IWM_WRITE(sc, |
1486 |
IWM_WRITE(sc, |
|
Lines 1425-1443
iwm_nic_rx_init(struct iwm_softc *sc)
Link Here
|
| 1425 |
if (sc->cfg->host_interrupt_operation_mode) |
1509 |
if (sc->cfg->host_interrupt_operation_mode) |
| 1426 |
IWM_SETBITS(sc, IWM_CSR_INT_COALESCING, IWM_HOST_INT_OPER_MODE); |
1510 |
IWM_SETBITS(sc, IWM_CSR_INT_COALESCING, IWM_HOST_INT_OPER_MODE); |
| 1427 |
|
1511 |
|
| 1428 |
/* |
|
|
| 1429 |
* Thus sayeth el jefe (iwlwifi) via a comment: |
| 1430 |
* |
| 1431 |
* This value should initially be 0 (before preparing any |
| 1432 |
* RBs), should be 8 after preparing the first 8 RBs (for example) |
| 1433 |
*/ |
| 1434 |
IWM_WRITE(sc, IWM_FH_RSCSR_CHNL0_WPTR, 8); |
| 1435 |
|
| 1436 |
iwm_nic_unlock(sc); |
1512 |
iwm_nic_unlock(sc); |
| 1437 |
|
1513 |
|
|
|
1514 |
IWM_WRITE(sc, IWM_FH_RSCSR_CHNL0_WPTR, 8); |
| 1515 |
|
| 1438 |
return 0; |
1516 |
return 0; |
| 1439 |
} |
1517 |
} |
| 1440 |
|
1518 |
|
|
|
1519 |
static int |
| 1520 |
iwm_nic_rx_init(struct iwm_softc *sc) |
| 1521 |
{ |
| 1522 |
if (sc->cfg->mqrx_supported) |
| 1523 |
return iwm_nic_rx_mq_init(sc); |
| 1524 |
else |
| 1525 |
return iwm_nic_rx_legacy_init(sc); |
| 1526 |
} |
| 1527 |
|
| 1441 |
static int |
1528 |
static int |
| 1442 |
iwm_nic_tx_init(struct iwm_softc *sc) |
1529 |
iwm_nic_tx_init(struct iwm_softc *sc) |
| 1443 |
{ |
1530 |
{ |
|
Lines 1466-1472
iwm_nic_tx_init(struct iwm_softc *sc)
Link Here
|
| 1466 |
(unsigned long) (txq->desc_dma.paddr >> 8)); |
1553 |
(unsigned long) (txq->desc_dma.paddr >> 8)); |
| 1467 |
} |
1554 |
} |
| 1468 |
|
1555 |
|
| 1469 |
iwm_write_prph(sc, IWM_SCD_GP_CTRL, IWM_SCD_GP_CTRL_AUTO_ACTIVE_MODE); |
1556 |
iwm_set_bits_prph(sc, IWM_SCD_GP_CTRL, |
|
|
1557 |
IWM_SCD_GP_CTRL_AUTO_ACTIVE_MODE | |
| 1558 |
IWM_SCD_GP_CTRL_ENABLE_31_QUEUES); |
| 1470 |
|
1559 |
|
| 1471 |
iwm_nic_unlock(sc); |
1560 |
iwm_nic_unlock(sc); |
| 1472 |
|
1561 |
|
|
Lines 1503-1527
iwm_nic_init(struct iwm_softc *sc)
Link Here
|
| 1503 |
int |
1592 |
int |
| 1504 |
iwm_enable_txq(struct iwm_softc *sc, int sta_id, int qid, int fifo) |
1593 |
iwm_enable_txq(struct iwm_softc *sc, int sta_id, int qid, int fifo) |
| 1505 |
{ |
1594 |
{ |
|
|
1595 |
int qmsk; |
| 1596 |
|
| 1597 |
qmsk = 1 << qid; |
| 1598 |
|
| 1506 |
if (!iwm_nic_lock(sc)) { |
1599 |
if (!iwm_nic_lock(sc)) { |
| 1507 |
device_printf(sc->sc_dev, |
1600 |
device_printf(sc->sc_dev, "%s: cannot enable txq %d\n", |
| 1508 |
"%s: cannot enable txq %d\n", |
1601 |
__func__, qid); |
| 1509 |
__func__, |
|
|
| 1510 |
qid); |
| 1511 |
return EBUSY; |
1602 |
return EBUSY; |
| 1512 |
} |
1603 |
} |
| 1513 |
|
1604 |
|
| 1514 |
IWM_WRITE(sc, IWM_HBUS_TARG_WRPTR, qid << 8 | 0); |
1605 |
IWM_WRITE(sc, IWM_HBUS_TARG_WRPTR, qid << 8 | 0); |
| 1515 |
|
1606 |
|
| 1516 |
if (qid == IWM_MVM_CMD_QUEUE) { |
1607 |
if (qid == IWM_MVM_CMD_QUEUE) { |
| 1517 |
/* unactivate before configuration */ |
1608 |
/* Disable the scheduler. */ |
|
|
1609 |
iwm_write_prph(sc, IWM_SCD_EN_CTRL, 0); |
| 1610 |
|
| 1611 |
/* Stop the TX queue prior to configuration. */ |
| 1518 |
iwm_write_prph(sc, IWM_SCD_QUEUE_STATUS_BITS(qid), |
1612 |
iwm_write_prph(sc, IWM_SCD_QUEUE_STATUS_BITS(qid), |
| 1519 |
(0 << IWM_SCD_QUEUE_STTS_REG_POS_ACTIVE) |
1613 |
(0 << IWM_SCD_QUEUE_STTS_REG_POS_ACTIVE) | |
| 1520 |
| (1 << IWM_SCD_QUEUE_STTS_REG_POS_SCD_ACT_EN)); |
1614 |
(1 << IWM_SCD_QUEUE_STTS_REG_POS_SCD_ACT_EN)); |
| 1521 |
|
1615 |
|
| 1522 |
iwm_nic_unlock(sc); |
1616 |
iwm_nic_unlock(sc); |
| 1523 |
|
1617 |
|
| 1524 |
iwm_clear_bits_prph(sc, IWM_SCD_AGGR_SEL, (1 << qid)); |
1618 |
/* Disable aggregations for this queue. */ |
|
|
1619 |
iwm_clear_bits_prph(sc, IWM_SCD_AGGR_SEL, qmsk); |
| 1525 |
|
1620 |
|
| 1526 |
if (!iwm_nic_lock(sc)) { |
1621 |
if (!iwm_nic_lock(sc)) { |
| 1527 |
device_printf(sc->sc_dev, |
1622 |
device_printf(sc->sc_dev, |
|
Lines 1531-1537
iwm_enable_txq(struct iwm_softc *sc, int sta_id, int qid, int fifo)
Link Here
|
| 1531 |
iwm_write_prph(sc, IWM_SCD_QUEUE_RDPTR(qid), 0); |
1626 |
iwm_write_prph(sc, IWM_SCD_QUEUE_RDPTR(qid), 0); |
| 1532 |
iwm_nic_unlock(sc); |
1627 |
iwm_nic_unlock(sc); |
| 1533 |
|
1628 |
|
| 1534 |
iwm_write_mem32(sc, sc->scd_base_addr + IWM_SCD_CONTEXT_QUEUE_OFFSET(qid), 0); |
1629 |
iwm_write_mem32(sc, |
|
|
1630 |
sc->scd_base_addr + IWM_SCD_CONTEXT_QUEUE_OFFSET(qid), 0); |
| 1535 |
/* Set scheduler window size and frame limit. */ |
1631 |
/* Set scheduler window size and frame limit. */ |
| 1536 |
iwm_write_mem32(sc, |
1632 |
iwm_write_mem32(sc, |
| 1537 |
sc->scd_base_addr + IWM_SCD_CONTEXT_QUEUE_OFFSET(qid) + |
1633 |
sc->scd_base_addr + IWM_SCD_CONTEXT_QUEUE_OFFSET(qid) + |
|
Lines 1551-1556
iwm_enable_txq(struct iwm_softc *sc, int sta_id, int qid, int fifo)
Link Here
|
| 1551 |
(fifo << IWM_SCD_QUEUE_STTS_REG_POS_TXF) | |
1647 |
(fifo << IWM_SCD_QUEUE_STTS_REG_POS_TXF) | |
| 1552 |
(1 << IWM_SCD_QUEUE_STTS_REG_POS_WSL) | |
1648 |
(1 << IWM_SCD_QUEUE_STTS_REG_POS_WSL) | |
| 1553 |
IWM_SCD_QUEUE_STTS_REG_MSK); |
1649 |
IWM_SCD_QUEUE_STTS_REG_MSK); |
|
|
1650 |
|
| 1651 |
/* Enable the scheduler for this queue. */ |
| 1652 |
iwm_write_prph(sc, IWM_SCD_EN_CTRL, qmsk); |
| 1554 |
} else { |
1653 |
} else { |
| 1555 |
struct iwm_scd_txq_cfg_cmd cmd; |
1654 |
struct iwm_scd_txq_cfg_cmd cmd; |
| 1556 |
int error; |
1655 |
int error; |
|
Lines 1577-1585
iwm_enable_txq(struct iwm_softc *sc, int sta_id, int qid, int fifo)
Link Here
|
| 1577 |
return EBUSY; |
1676 |
return EBUSY; |
| 1578 |
} |
1677 |
} |
| 1579 |
|
1678 |
|
| 1580 |
iwm_write_prph(sc, IWM_SCD_EN_CTRL, |
|
|
| 1581 |
iwm_read_prph(sc, IWM_SCD_EN_CTRL) | qid); |
| 1582 |
|
| 1583 |
iwm_nic_unlock(sc); |
1679 |
iwm_nic_unlock(sc); |
| 1584 |
|
1680 |
|
| 1585 |
IWM_DPRINTF(sc, IWM_DEBUG_XMIT, "%s: enabled txq %d FIFO %d\n", |
1681 |
IWM_DPRINTF(sc, IWM_DEBUG_XMIT, "%s: enabled txq %d FIFO %d\n", |
|
Lines 1651-1657
iwm_trans_pcie_fw_alive(struct iwm_softc *sc, uint32_t scd_base_addr)
Link Here
|
| 1651 |
iwm_nic_unlock(sc); |
1747 |
iwm_nic_unlock(sc); |
| 1652 |
|
1748 |
|
| 1653 |
/* Enable L1-Active */ |
1749 |
/* Enable L1-Active */ |
| 1654 |
if (sc->cfg->device_family != IWM_DEVICE_FAMILY_8000) { |
1750 |
if (sc->cfg->device_family < IWM_DEVICE_FAMILY_8000) { |
| 1655 |
iwm_clear_bits_prph(sc, IWM_APMG_PCIDEV_STT_REG, |
1751 |
iwm_clear_bits_prph(sc, IWM_APMG_PCIDEV_STT_REG, |
| 1656 |
IWM_APMG_PCIDEV_STT_VAL_L1_ACT_DIS); |
1752 |
IWM_APMG_PCIDEV_STT_VAL_L1_ACT_DIS); |
| 1657 |
} |
1753 |
} |
|
Lines 2069-2075
static int
Link Here
|
| 2069 |
iwm_get_sku(const struct iwm_softc *sc, const uint16_t *nvm_sw, |
2165 |
iwm_get_sku(const struct iwm_softc *sc, const uint16_t *nvm_sw, |
| 2070 |
const uint16_t *phy_sku) |
2166 |
const uint16_t *phy_sku) |
| 2071 |
{ |
2167 |
{ |
| 2072 |
if (sc->cfg->device_family != IWM_DEVICE_FAMILY_8000) |
2168 |
if (sc->cfg->device_family < IWM_DEVICE_FAMILY_8000) |
| 2073 |
return le16_to_cpup(nvm_sw + IWM_SKU); |
2169 |
return le16_to_cpup(nvm_sw + IWM_SKU); |
| 2074 |
|
2170 |
|
| 2075 |
return le32_to_cpup((const uint32_t *)(phy_sku + IWM_SKU_8000)); |
2171 |
return le32_to_cpup((const uint32_t *)(phy_sku + IWM_SKU_8000)); |
|
Lines 2078-2084
iwm_get_sku(const struct iwm_softc *sc, const uint16_t *nvm_sw,
Link Here
|
| 2078 |
static int |
2174 |
static int |
| 2079 |
iwm_get_nvm_version(const struct iwm_softc *sc, const uint16_t *nvm_sw) |
2175 |
iwm_get_nvm_version(const struct iwm_softc *sc, const uint16_t *nvm_sw) |
| 2080 |
{ |
2176 |
{ |
| 2081 |
if (sc->cfg->device_family != IWM_DEVICE_FAMILY_8000) |
2177 |
if (sc->cfg->device_family < IWM_DEVICE_FAMILY_8000) |
| 2082 |
return le16_to_cpup(nvm_sw + IWM_NVM_VERSION); |
2178 |
return le16_to_cpup(nvm_sw + IWM_NVM_VERSION); |
| 2083 |
else |
2179 |
else |
| 2084 |
return le32_to_cpup((const uint32_t *)(nvm_sw + |
2180 |
return le32_to_cpup((const uint32_t *)(nvm_sw + |
|
Lines 2089-2095
static int
Link Here
|
| 2089 |
iwm_get_radio_cfg(const struct iwm_softc *sc, const uint16_t *nvm_sw, |
2185 |
iwm_get_radio_cfg(const struct iwm_softc *sc, const uint16_t *nvm_sw, |
| 2090 |
const uint16_t *phy_sku) |
2186 |
const uint16_t *phy_sku) |
| 2091 |
{ |
2187 |
{ |
| 2092 |
if (sc->cfg->device_family != IWM_DEVICE_FAMILY_8000) |
2188 |
if (sc->cfg->device_family < IWM_DEVICE_FAMILY_8000) |
| 2093 |
return le16_to_cpup(nvm_sw + IWM_RADIO_CFG); |
2189 |
return le16_to_cpup(nvm_sw + IWM_RADIO_CFG); |
| 2094 |
|
2190 |
|
| 2095 |
return le32_to_cpup((const uint32_t *)(phy_sku + IWM_RADIO_CFG_8000)); |
2191 |
return le32_to_cpup((const uint32_t *)(phy_sku + IWM_RADIO_CFG_8000)); |
|
Lines 2100-2106
iwm_get_n_hw_addrs(const struct iwm_softc *sc, const uint16_t *nvm_sw)
Link Here
|
| 2100 |
{ |
2196 |
{ |
| 2101 |
int n_hw_addr; |
2197 |
int n_hw_addr; |
| 2102 |
|
2198 |
|
| 2103 |
if (sc->cfg->device_family != IWM_DEVICE_FAMILY_8000) |
2199 |
if (sc->cfg->device_family < IWM_DEVICE_FAMILY_8000) |
| 2104 |
return le16_to_cpup(nvm_sw + IWM_N_HW_ADDRS); |
2200 |
return le16_to_cpup(nvm_sw + IWM_N_HW_ADDRS); |
| 2105 |
|
2201 |
|
| 2106 |
n_hw_addr = le32_to_cpup((const uint32_t *)(nvm_sw + IWM_N_HW_ADDRS_8000)); |
2202 |
n_hw_addr = le32_to_cpup((const uint32_t *)(nvm_sw + IWM_N_HW_ADDRS_8000)); |
|
Lines 2112-2118
static void
Link Here
|
| 2112 |
iwm_set_radio_cfg(const struct iwm_softc *sc, struct iwm_nvm_data *data, |
2208 |
iwm_set_radio_cfg(const struct iwm_softc *sc, struct iwm_nvm_data *data, |
| 2113 |
uint32_t radio_cfg) |
2209 |
uint32_t radio_cfg) |
| 2114 |
{ |
2210 |
{ |
| 2115 |
if (sc->cfg->device_family != IWM_DEVICE_FAMILY_8000) { |
2211 |
if (sc->cfg->device_family < IWM_DEVICE_FAMILY_8000) { |
| 2116 |
data->radio_cfg_type = IWM_NVM_RF_CFG_TYPE_MSK(radio_cfg); |
2212 |
data->radio_cfg_type = IWM_NVM_RF_CFG_TYPE_MSK(radio_cfg); |
| 2117 |
data->radio_cfg_step = IWM_NVM_RF_CFG_STEP_MSK(radio_cfg); |
2213 |
data->radio_cfg_step = IWM_NVM_RF_CFG_STEP_MSK(radio_cfg); |
| 2118 |
data->radio_cfg_dash = IWM_NVM_RF_CFG_DASH_MSK(radio_cfg); |
2214 |
data->radio_cfg_dash = IWM_NVM_RF_CFG_DASH_MSK(radio_cfg); |
|
Lines 2138-2144
iwm_set_hw_address(struct iwm_softc *sc, struct iwm_nvm_data *data,
Link Here
|
| 2138 |
iwm_set_hw_address_from_csr(sc, data); |
2234 |
iwm_set_hw_address_from_csr(sc, data); |
| 2139 |
} else |
2235 |
} else |
| 2140 |
#endif |
2236 |
#endif |
| 2141 |
if (sc->cfg->device_family != IWM_DEVICE_FAMILY_8000) { |
2237 |
if (sc->cfg->device_family < IWM_DEVICE_FAMILY_8000) { |
| 2142 |
const uint8_t *hw_addr = (const uint8_t *)(nvm_hw + IWM_HW_ADDR); |
2238 |
const uint8_t *hw_addr = (const uint8_t *)(nvm_hw + IWM_HW_ADDR); |
| 2143 |
|
2239 |
|
| 2144 |
/* The byte order is little endian 16 bit, meaning 214365 */ |
2240 |
/* The byte order is little endian 16 bit, meaning 214365 */ |
|
Lines 2170-2176
iwm_parse_nvm_data(struct iwm_softc *sc,
Link Here
|
| 2170 |
uint32_t sku, radio_cfg; |
2266 |
uint32_t sku, radio_cfg; |
| 2171 |
uint16_t lar_config; |
2267 |
uint16_t lar_config; |
| 2172 |
|
2268 |
|
| 2173 |
if (sc->cfg->device_family != IWM_DEVICE_FAMILY_8000) { |
2269 |
if (sc->cfg->device_family < IWM_DEVICE_FAMILY_8000) { |
| 2174 |
data = malloc(sizeof(*data) + |
2270 |
data = malloc(sizeof(*data) + |
| 2175 |
IWM_NUM_CHANNELS * sizeof(uint16_t), |
2271 |
IWM_NUM_CHANNELS * sizeof(uint16_t), |
| 2176 |
M_DEVBUF, M_NOWAIT | M_ZERO); |
2272 |
M_DEVBUF, M_NOWAIT | M_ZERO); |
|
Lines 2194-2200
iwm_parse_nvm_data(struct iwm_softc *sc,
Link Here
|
| 2194 |
|
2290 |
|
| 2195 |
data->n_hw_addrs = iwm_get_n_hw_addrs(sc, nvm_sw); |
2291 |
data->n_hw_addrs = iwm_get_n_hw_addrs(sc, nvm_sw); |
| 2196 |
|
2292 |
|
| 2197 |
if (sc->cfg->device_family == IWM_DEVICE_FAMILY_8000) { |
2293 |
if (sc->cfg->device_family >= IWM_DEVICE_FAMILY_8000) { |
|
|
2294 |
/* TODO: use IWL_NVM_EXT */ |
| 2198 |
uint16_t lar_offset = data->nvm_version < 0xE39 ? |
2295 |
uint16_t lar_offset = data->nvm_version < 0xE39 ? |
| 2199 |
IWM_NVM_LAR_OFFSET_8000_OLD : |
2296 |
IWM_NVM_LAR_OFFSET_8000_OLD : |
| 2200 |
IWM_NVM_LAR_OFFSET_8000; |
2297 |
IWM_NVM_LAR_OFFSET_8000; |
|
Lines 2242-2248
iwm_parse_nvm_sections(struct iwm_softc *sc, struct iwm_nvm_section *sections)
Link Here
|
| 2242 |
"Can't parse empty OTP/NVM sections\n"); |
2339 |
"Can't parse empty OTP/NVM sections\n"); |
| 2243 |
return NULL; |
2340 |
return NULL; |
| 2244 |
} |
2341 |
} |
| 2245 |
} else if (sc->cfg->device_family == IWM_DEVICE_FAMILY_8000) { |
2342 |
} else if (sc->cfg->device_family >= IWM_DEVICE_FAMILY_8000) { |
| 2246 |
/* SW and REGULATORY sections are mandatory */ |
2343 |
/* SW and REGULATORY sections are mandatory */ |
| 2247 |
if (!sections[IWM_NVM_SECTION_TYPE_SW].data || |
2344 |
if (!sections[IWM_NVM_SECTION_TYPE_SW].data || |
| 2248 |
!sections[IWM_NVM_SECTION_TYPE_REGULATORY].data) { |
2345 |
!sections[IWM_NVM_SECTION_TYPE_REGULATORY].data) { |
|
Lines 2672-2678
iwm_start_fw(struct iwm_softc *sc, const struct iwm_fw_img *fw)
Link Here
|
| 2672 |
IWM_WRITE(sc, IWM_CSR_UCODE_DRV_GP1_CLR, IWM_CSR_UCODE_SW_BIT_RFKILL); |
2769 |
IWM_WRITE(sc, IWM_CSR_UCODE_DRV_GP1_CLR, IWM_CSR_UCODE_SW_BIT_RFKILL); |
| 2673 |
|
2770 |
|
| 2674 |
/* Load the given image to the HW */ |
2771 |
/* Load the given image to the HW */ |
| 2675 |
if (sc->cfg->device_family == IWM_DEVICE_FAMILY_8000) |
2772 |
if (sc->cfg->device_family >= IWM_DEVICE_FAMILY_8000) |
| 2676 |
ret = iwm_pcie_load_given_ucode_8000(sc, fw); |
2773 |
ret = iwm_pcie_load_given_ucode_8000(sc, fw); |
| 2677 |
else |
2774 |
else |
| 2678 |
ret = iwm_pcie_load_given_ucode(sc, fw); |
2775 |
ret = iwm_pcie_load_given_ucode(sc, fw); |
|
Lines 2823-2829
iwm_mvm_load_ucode_wait_alive(struct iwm_softc *sc,
Link Here
|
| 2823 |
IWM_MVM_UCODE_ALIVE_TIMEOUT); |
2920 |
IWM_MVM_UCODE_ALIVE_TIMEOUT); |
| 2824 |
IWM_LOCK(sc); |
2921 |
IWM_LOCK(sc); |
| 2825 |
if (error) { |
2922 |
if (error) { |
| 2826 |
if (sc->cfg->device_family == IWM_DEVICE_FAMILY_8000) { |
2923 |
if (sc->cfg->device_family >= IWM_DEVICE_FAMILY_8000) { |
| 2827 |
uint32_t a = 0x5a5a5a5a, b = 0x5a5a5a5a; |
2924 |
uint32_t a = 0x5a5a5a5a, b = 0x5a5a5a5a; |
| 2828 |
if (iwm_nic_lock(sc)) { |
2925 |
if (iwm_nic_lock(sc)) { |
| 2829 |
a = iwm_read_prph(sc, IWM_SB_CPU_1_STATUS); |
2926 |
a = iwm_read_prph(sc, IWM_SB_CPU_1_STATUS); |
|
Lines 2914-2919
iwm_run_init_mvm_ucode(struct iwm_softc *sc, int justnvm)
Link Here
|
| 2914 |
goto error; |
3011 |
goto error; |
| 2915 |
} |
3012 |
} |
| 2916 |
|
3013 |
|
|
|
3014 |
if (sc->cfg->device_family < IWM_DEVICE_FAMILY_8000) { |
| 3015 |
ret = iwm_send_bt_init_conf(sc); |
| 3016 |
if (ret) { |
| 3017 |
device_printf(sc->sc_dev, |
| 3018 |
"failed to send bt coex configuration: %d\n", ret); |
| 3019 |
goto error; |
| 3020 |
} |
| 3021 |
} |
| 3022 |
|
| 2917 |
if (justnvm) { |
3023 |
if (justnvm) { |
| 2918 |
/* Read nvm */ |
3024 |
/* Read nvm */ |
| 2919 |
ret = iwm_nvm_init(sc); |
3025 |
ret = iwm_nvm_init(sc); |
|
Lines 2925-2937
iwm_run_init_mvm_ucode(struct iwm_softc *sc, int justnvm)
Link Here
|
| 2925 |
goto error; |
3031 |
goto error; |
| 2926 |
} |
3032 |
} |
| 2927 |
|
3033 |
|
| 2928 |
ret = iwm_send_bt_init_conf(sc); |
|
|
| 2929 |
if (ret) { |
| 2930 |
device_printf(sc->sc_dev, |
| 2931 |
"failed to send bt coex configuration: %d\n", ret); |
| 2932 |
goto error; |
| 2933 |
} |
| 2934 |
|
| 2935 |
/* Send TX valid antennas before triggering calibrations */ |
3034 |
/* Send TX valid antennas before triggering calibrations */ |
| 2936 |
ret = iwm_send_tx_ant_cfg(sc, iwm_mvm_get_valid_tx_ant(sc)); |
3035 |
ret = iwm_send_tx_ant_cfg(sc, iwm_mvm_get_valid_tx_ant(sc)); |
| 2937 |
if (ret) { |
3036 |
if (ret) { |
|
Lines 3025-3070
iwm_rx_addbuf(struct iwm_softc *sc, int size, int idx)
Link Here
|
| 3025 |
|
3124 |
|
| 3026 |
/* Update RX descriptor. */ |
3125 |
/* Update RX descriptor. */ |
| 3027 |
KASSERT((seg.ds_addr & 255) == 0, ("seg.ds_addr not aligned")); |
3126 |
KASSERT((seg.ds_addr & 255) == 0, ("seg.ds_addr not aligned")); |
| 3028 |
ring->desc[idx] = htole32(seg.ds_addr >> 8); |
3127 |
if (sc->cfg->mqrx_supported) |
| 3029 |
bus_dmamap_sync(ring->desc_dma.tag, ring->desc_dma.map, |
3128 |
((uint64_t *)ring->desc)[idx] = |
|
|
3129 |
htole64(seg.ds_addr | (idx + 1)); |
| 3130 |
else |
| 3131 |
((uint32_t *)ring->desc)[idx] = htole32(seg.ds_addr >> 8); |
| 3132 |
bus_dmamap_sync(ring->free_desc_dma.tag, ring->free_desc_dma.map, |
| 3030 |
BUS_DMASYNC_PREWRITE); |
3133 |
BUS_DMASYNC_PREWRITE); |
| 3031 |
|
3134 |
|
| 3032 |
return 0; |
3135 |
return 0; |
| 3033 |
} |
3136 |
} |
| 3034 |
|
3137 |
|
| 3035 |
/* iwlwifi: mvm/rx.c */ |
|
|
| 3036 |
/* |
| 3037 |
* iwm_mvm_get_signal_strength - use new rx PHY INFO API |
| 3038 |
* values are reported by the fw as positive values - need to negate |
| 3039 |
* to obtain their dBM. Account for missing antennas by replacing 0 |
| 3040 |
* values by -256dBm: practically 0 power and a non-feasible 8 bit value. |
| 3041 |
*/ |
| 3042 |
static int |
| 3043 |
iwm_mvm_get_signal_strength(struct iwm_softc *sc, struct iwm_rx_phy_info *phy_info) |
| 3044 |
{ |
| 3045 |
int energy_a, energy_b, energy_c, max_energy; |
| 3046 |
uint32_t val; |
| 3047 |
|
| 3048 |
val = le32toh(phy_info->non_cfg_phy[IWM_RX_INFO_ENERGY_ANT_ABC_IDX]); |
| 3049 |
energy_a = (val & IWM_RX_INFO_ENERGY_ANT_A_MSK) >> |
| 3050 |
IWM_RX_INFO_ENERGY_ANT_A_POS; |
| 3051 |
energy_a = energy_a ? -energy_a : -256; |
| 3052 |
energy_b = (val & IWM_RX_INFO_ENERGY_ANT_B_MSK) >> |
| 3053 |
IWM_RX_INFO_ENERGY_ANT_B_POS; |
| 3054 |
energy_b = energy_b ? -energy_b : -256; |
| 3055 |
energy_c = (val & IWM_RX_INFO_ENERGY_ANT_C_MSK) >> |
| 3056 |
IWM_RX_INFO_ENERGY_ANT_C_POS; |
| 3057 |
energy_c = energy_c ? -energy_c : -256; |
| 3058 |
max_energy = MAX(energy_a, energy_b); |
| 3059 |
max_energy = MAX(max_energy, energy_c); |
| 3060 |
|
| 3061 |
IWM_DPRINTF(sc, IWM_DEBUG_RECV, |
| 3062 |
"energy In A %d B %d C %d , and max %d\n", |
| 3063 |
energy_a, energy_b, energy_c, max_energy); |
| 3064 |
|
| 3065 |
return max_energy; |
| 3066 |
} |
| 3067 |
|
| 3068 |
static void |
3138 |
static void |
| 3069 |
iwm_mvm_rx_rx_phy_cmd(struct iwm_softc *sc, struct iwm_rx_packet *pkt) |
3139 |
iwm_mvm_rx_rx_phy_cmd(struct iwm_softc *sc, struct iwm_rx_packet *pkt) |
| 3070 |
{ |
3140 |
{ |
|
Lines 3118-3136
iwm_mvm_handle_rx_statistics(struct iwm_softc *sc, struct iwm_rx_packet *pkt)
Link Here
|
| 3118 |
sc->sc_noise = iwm_get_noise(sc, &stats->rx.general); |
3188 |
sc->sc_noise = iwm_get_noise(sc, &stats->rx.general); |
| 3119 |
} |
3189 |
} |
| 3120 |
|
3190 |
|
|
|
3191 |
/* iwlwifi: mvm/rx.c */ |
| 3192 |
/* |
| 3193 |
* iwm_mvm_get_signal_strength - use new rx PHY INFO API |
| 3194 |
* values are reported by the fw as positive values - need to negate |
| 3195 |
* to obtain their dBM. Account for missing antennas by replacing 0 |
| 3196 |
* values by -256dBm: practically 0 power and a non-feasible 8 bit value. |
| 3197 |
*/ |
| 3198 |
static int |
| 3199 |
iwm_mvm_rx_get_signal_strength(struct iwm_softc *sc, |
| 3200 |
struct iwm_rx_phy_info *phy_info) |
| 3201 |
{ |
| 3202 |
int energy_a, energy_b, energy_c, max_energy; |
| 3203 |
uint32_t val; |
| 3204 |
|
| 3205 |
val = le32toh(phy_info->non_cfg_phy[IWM_RX_INFO_ENERGY_ANT_ABC_IDX]); |
| 3206 |
energy_a = (val & IWM_RX_INFO_ENERGY_ANT_A_MSK) >> |
| 3207 |
IWM_RX_INFO_ENERGY_ANT_A_POS; |
| 3208 |
energy_a = energy_a ? -energy_a : -256; |
| 3209 |
energy_b = (val & IWM_RX_INFO_ENERGY_ANT_B_MSK) >> |
| 3210 |
IWM_RX_INFO_ENERGY_ANT_B_POS; |
| 3211 |
energy_b = energy_b ? -energy_b : -256; |
| 3212 |
energy_c = (val & IWM_RX_INFO_ENERGY_ANT_C_MSK) >> |
| 3213 |
IWM_RX_INFO_ENERGY_ANT_C_POS; |
| 3214 |
energy_c = energy_c ? -energy_c : -256; |
| 3215 |
max_energy = MAX(energy_a, energy_b); |
| 3216 |
max_energy = MAX(max_energy, energy_c); |
| 3217 |
|
| 3218 |
IWM_DPRINTF(sc, IWM_DEBUG_RECV, |
| 3219 |
"energy In A %d B %d C %d , and max %d\n", |
| 3220 |
energy_a, energy_b, energy_c, max_energy); |
| 3221 |
|
| 3222 |
return max_energy; |
| 3223 |
} |
| 3224 |
|
| 3225 |
static int |
| 3226 |
iwm_mvm_rxmq_get_signal_strength(struct iwm_softc *sc, |
| 3227 |
struct iwm_rx_mpdu_desc *desc) |
| 3228 |
{ |
| 3229 |
int energy_a, energy_b; |
| 3230 |
|
| 3231 |
energy_a = desc->v1.energy_a; |
| 3232 |
energy_b = desc->v1.energy_b; |
| 3233 |
energy_a = energy_a ? -energy_a : -256; |
| 3234 |
energy_b = energy_b ? -energy_b : -256; |
| 3235 |
return MAX(energy_a, energy_b); |
| 3236 |
} |
| 3237 |
|
| 3121 |
/* |
3238 |
/* |
| 3122 |
* iwm_mvm_rx_rx_mpdu - IWM_REPLY_RX_MPDU_CMD handler |
3239 |
* iwm_mvm_rx_rx_mpdu - IWM_REPLY_RX_MPDU_CMD handler |
| 3123 |
* |
3240 |
* |
| 3124 |
* Handles the actual data of the Rx packet from the fw |
3241 |
* Handles the actual data of the Rx packet from the fw |
| 3125 |
*/ |
3242 |
*/ |
| 3126 |
static boolean_t |
3243 |
static bool |
| 3127 |
iwm_mvm_rx_rx_mpdu(struct iwm_softc *sc, struct mbuf *m, uint32_t offset, |
3244 |
iwm_mvm_rx_rx_mpdu(struct iwm_softc *sc, struct mbuf *m, uint32_t offset, |
| 3128 |
boolean_t stolen) |
3245 |
bool stolen) |
| 3129 |
{ |
3246 |
{ |
| 3130 |
struct ieee80211com *ic = &sc->sc_ic; |
3247 |
struct ieee80211com *ic = &sc->sc_ic; |
| 3131 |
struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); |
3248 |
struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); |
| 3132 |
struct ieee80211_frame *wh; |
3249 |
struct ieee80211_frame *wh; |
| 3133 |
struct ieee80211_node *ni; |
|
|
| 3134 |
struct ieee80211_rx_stats rxs; |
3250 |
struct ieee80211_rx_stats rxs; |
| 3135 |
struct iwm_rx_phy_info *phy_info; |
3251 |
struct iwm_rx_phy_info *phy_info; |
| 3136 |
struct iwm_rx_mpdu_res_start *rx_res; |
3252 |
struct iwm_rx_mpdu_res_start *rx_res; |
|
Lines 3149-3165
iwm_mvm_rx_rx_mpdu(struct iwm_softc *sc, struct mbuf *m, uint32_t offset,
Link Here
|
| 3149 |
device_printf(sc->sc_dev, |
3265 |
device_printf(sc->sc_dev, |
| 3150 |
"dsp size out of range [0,20]: %d\n", |
3266 |
"dsp size out of range [0,20]: %d\n", |
| 3151 |
phy_info->cfg_phy_cnt); |
3267 |
phy_info->cfg_phy_cnt); |
| 3152 |
goto fail; |
3268 |
return false; |
| 3153 |
} |
3269 |
} |
| 3154 |
|
3270 |
|
| 3155 |
if (!(rx_pkt_status & IWM_RX_MPDU_RES_STATUS_CRC_OK) || |
3271 |
if (!(rx_pkt_status & IWM_RX_MPDU_RES_STATUS_CRC_OK) || |
| 3156 |
!(rx_pkt_status & IWM_RX_MPDU_RES_STATUS_OVERRUN_OK)) { |
3272 |
!(rx_pkt_status & IWM_RX_MPDU_RES_STATUS_OVERRUN_OK)) { |
| 3157 |
IWM_DPRINTF(sc, IWM_DEBUG_RECV, |
3273 |
IWM_DPRINTF(sc, IWM_DEBUG_RECV, |
| 3158 |
"Bad CRC or FIFO: 0x%08X.\n", rx_pkt_status); |
3274 |
"Bad CRC or FIFO: 0x%08X.\n", rx_pkt_status); |
| 3159 |
goto fail; |
3275 |
return false; |
| 3160 |
} |
3276 |
} |
| 3161 |
|
3277 |
|
| 3162 |
rssi = iwm_mvm_get_signal_strength(sc, phy_info); |
3278 |
rssi = iwm_mvm_rx_get_signal_strength(sc, phy_info); |
| 3163 |
|
3279 |
|
| 3164 |
/* Map it to relative value */ |
3280 |
/* Map it to relative value */ |
| 3165 |
rssi = rssi - sc->sc_noise; |
3281 |
rssi = rssi - sc->sc_noise; |
|
Lines 3168-3174
iwm_mvm_rx_rx_mpdu(struct iwm_softc *sc, struct mbuf *m, uint32_t offset,
Link Here
|
| 3168 |
if (!stolen && iwm_rx_addbuf(sc, IWM_RBUF_SIZE, sc->rxq.cur) != 0) { |
3284 |
if (!stolen && iwm_rx_addbuf(sc, IWM_RBUF_SIZE, sc->rxq.cur) != 0) { |
| 3169 |
device_printf(sc->sc_dev, "%s: unable to add more buffers\n", |
3285 |
device_printf(sc->sc_dev, "%s: unable to add more buffers\n", |
| 3170 |
__func__); |
3286 |
__func__); |
| 3171 |
goto fail; |
3287 |
return false; |
| 3172 |
} |
3288 |
} |
| 3173 |
|
3289 |
|
| 3174 |
m->m_data = pkt->data + sizeof(*rx_res); |
3290 |
m->m_data = pkt->data + sizeof(*rx_res); |
|
Lines 3177-3184
iwm_mvm_rx_rx_mpdu(struct iwm_softc *sc, struct mbuf *m, uint32_t offset,
Link Here
|
| 3177 |
IWM_DPRINTF(sc, IWM_DEBUG_RECV, |
3293 |
IWM_DPRINTF(sc, IWM_DEBUG_RECV, |
| 3178 |
"%s: rssi=%d, noise=%d\n", __func__, rssi, sc->sc_noise); |
3294 |
"%s: rssi=%d, noise=%d\n", __func__, rssi, sc->sc_noise); |
| 3179 |
|
3295 |
|
| 3180 |
ni = ieee80211_find_rxnode(ic, (struct ieee80211_frame_min *)wh); |
|
|
| 3181 |
|
| 3182 |
IWM_DPRINTF(sc, IWM_DEBUG_RECV, |
3296 |
IWM_DPRINTF(sc, IWM_DEBUG_RECV, |
| 3183 |
"%s: phy_info: channel=%d, flags=0x%08x\n", |
3297 |
"%s: phy_info: channel=%d, flags=0x%08x\n", |
| 3184 |
__func__, |
3298 |
__func__, |
|
Lines 3201-3211
iwm_mvm_rx_rx_mpdu(struct iwm_softc *sc, struct mbuf *m, uint32_t offset,
Link Here
|
| 3201 |
/* rssi is in 1/2db units */ |
3315 |
/* rssi is in 1/2db units */ |
| 3202 |
rxs.c_rssi = rssi * 2; |
3316 |
rxs.c_rssi = rssi * 2; |
| 3203 |
rxs.c_nf = sc->sc_noise; |
3317 |
rxs.c_nf = sc->sc_noise; |
| 3204 |
if (ieee80211_add_rx_params(m, &rxs) == 0) { |
3318 |
if (ieee80211_add_rx_params(m, &rxs) == 0) |
| 3205 |
if (ni) |
3319 |
return false; |
| 3206 |
ieee80211_free_node(ni); |
|
|
| 3207 |
goto fail; |
| 3208 |
} |
| 3209 |
|
3320 |
|
| 3210 |
if (ieee80211_radiotap_active_vap(vap)) { |
3321 |
if (ieee80211_radiotap_active_vap(vap)) { |
| 3211 |
struct iwm_rx_radiotap_header *tap = &sc->sc_rxtap; |
3322 |
struct iwm_rx_radiotap_header *tap = &sc->sc_rxtap; |
|
Lines 3239-3244
iwm_mvm_rx_rx_mpdu(struct iwm_softc *sc, struct mbuf *m, uint32_t offset,
Link Here
|
| 3239 |
} |
3350 |
} |
| 3240 |
} |
3351 |
} |
| 3241 |
|
3352 |
|
|
|
3353 |
return true; |
| 3354 |
} |
| 3355 |
|
| 3356 |
static bool |
| 3357 |
iwm_mvm_rx_mpdu_mq(struct iwm_softc *sc, struct mbuf *m, uint32_t offset, |
| 3358 |
bool stolen) |
| 3359 |
{ |
| 3360 |
struct ieee80211com *ic = &sc->sc_ic; |
| 3361 |
struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); |
| 3362 |
struct ieee80211_frame *wh; |
| 3363 |
struct ieee80211_rx_stats rxs; |
| 3364 |
struct iwm_rx_mpdu_desc *desc; |
| 3365 |
struct iwm_rx_packet *pkt; |
| 3366 |
int rssi; |
| 3367 |
uint32_t hdrlen, len, rate_n_flags; |
| 3368 |
uint16_t phy_info; |
| 3369 |
uint8_t channel; |
| 3370 |
|
| 3371 |
pkt = mtodo(m, offset); |
| 3372 |
desc = (void *)pkt->data; |
| 3373 |
|
| 3374 |
if (!(desc->status & htole16(IWM_RX_MPDU_RES_STATUS_CRC_OK)) || |
| 3375 |
!(desc->status & htole16(IWM_RX_MPDU_RES_STATUS_OVERRUN_OK))) { |
| 3376 |
IWM_DPRINTF(sc, IWM_DEBUG_RECV, |
| 3377 |
"Bad CRC or FIFO: 0x%08X.\n", desc->status); |
| 3378 |
return false; |
| 3379 |
} |
| 3380 |
|
| 3381 |
channel = desc->v1.channel; |
| 3382 |
len = le16toh(desc->mpdu_len); |
| 3383 |
phy_info = le16toh(desc->phy_info); |
| 3384 |
rate_n_flags = desc->v1.rate_n_flags; |
| 3385 |
|
| 3386 |
wh = mtodo(m, sizeof(*desc)); |
| 3387 |
m->m_data = pkt->data + sizeof(*desc); |
| 3388 |
m->m_pkthdr.len = m->m_len = len; |
| 3389 |
m->m_len = len; |
| 3390 |
|
| 3391 |
/* Account for padding following the frame header. */ |
| 3392 |
if ((desc->mac_flags2 & IWM_RX_MPDU_MFLG2_PAD)) { |
| 3393 |
hdrlen = ieee80211_anyhdrsize(wh); |
| 3394 |
memmove(mtodo(m, 2), mtodo(m, 0), hdrlen); |
| 3395 |
m->m_data = mtodo(m, 2); |
| 3396 |
wh = mtod(m, struct ieee80211_frame *); |
| 3397 |
} |
| 3398 |
|
| 3399 |
/* Map it to relative value */ |
| 3400 |
rssi = iwm_mvm_rxmq_get_signal_strength(sc, desc); |
| 3401 |
rssi = rssi - sc->sc_noise; |
| 3402 |
|
| 3403 |
/* replenish ring for the buffer we're going to feed to the sharks */ |
| 3404 |
if (!stolen && iwm_rx_addbuf(sc, IWM_RBUF_SIZE, sc->rxq.cur) != 0) { |
| 3405 |
device_printf(sc->sc_dev, "%s: unable to add more buffers\n", |
| 3406 |
__func__); |
| 3407 |
return false; |
| 3408 |
} |
| 3409 |
|
| 3410 |
IWM_DPRINTF(sc, IWM_DEBUG_RECV, |
| 3411 |
"%s: rssi=%d, noise=%d\n", __func__, rssi, sc->sc_noise); |
| 3412 |
|
| 3413 |
/* |
| 3414 |
* Populate an RX state struct with the provided information. |
| 3415 |
*/ |
| 3416 |
bzero(&rxs, sizeof(rxs)); |
| 3417 |
rxs.r_flags |= IEEE80211_R_IEEE | IEEE80211_R_FREQ; |
| 3418 |
rxs.r_flags |= IEEE80211_R_NF | IEEE80211_R_RSSI; |
| 3419 |
rxs.c_ieee = channel; |
| 3420 |
rxs.c_freq = ieee80211_ieee2mhz(rxs.c_ieee, |
| 3421 |
channel <= 14 ? IEEE80211_CHAN_2GHZ : IEEE80211_CHAN_5GHZ); |
| 3422 |
|
| 3423 |
/* rssi is in 1/2db units */ |
| 3424 |
rxs.c_rssi = rssi * 2; |
| 3425 |
rxs.c_nf = sc->sc_noise; |
| 3426 |
if (ieee80211_add_rx_params(m, &rxs) == 0) |
| 3427 |
return false; |
| 3428 |
|
| 3429 |
if (ieee80211_radiotap_active_vap(vap)) { |
| 3430 |
struct iwm_rx_radiotap_header *tap = &sc->sc_rxtap; |
| 3431 |
|
| 3432 |
tap->wr_flags = 0; |
| 3433 |
if ((phy_info & IWM_RX_MPDU_PHY_SHORT_PREAMBLE) != 0) |
| 3434 |
tap->wr_flags |= IEEE80211_RADIOTAP_F_SHORTPRE; |
| 3435 |
tap->wr_chan_freq = htole16(rxs.c_freq); |
| 3436 |
/* XXX only if ic->ic_curchan->ic_ieee == rxs.c_ieee */ |
| 3437 |
tap->wr_chan_flags = htole16(ic->ic_curchan->ic_flags); |
| 3438 |
tap->wr_dbm_antsignal = (int8_t)rssi; |
| 3439 |
tap->wr_dbm_antnoise = (int8_t)sc->sc_noise; |
| 3440 |
tap->wr_tsft = desc->v1.gp2_on_air_rise; |
| 3441 |
switch ((rate_n_flags & 0xff)) { |
| 3442 |
/* CCK rates. */ |
| 3443 |
case 10: tap->wr_rate = 2; break; |
| 3444 |
case 20: tap->wr_rate = 4; break; |
| 3445 |
case 55: tap->wr_rate = 11; break; |
| 3446 |
case 110: tap->wr_rate = 22; break; |
| 3447 |
/* OFDM rates. */ |
| 3448 |
case 0xd: tap->wr_rate = 12; break; |
| 3449 |
case 0xf: tap->wr_rate = 18; break; |
| 3450 |
case 0x5: tap->wr_rate = 24; break; |
| 3451 |
case 0x7: tap->wr_rate = 36; break; |
| 3452 |
case 0x9: tap->wr_rate = 48; break; |
| 3453 |
case 0xb: tap->wr_rate = 72; break; |
| 3454 |
case 0x1: tap->wr_rate = 96; break; |
| 3455 |
case 0x3: tap->wr_rate = 108; break; |
| 3456 |
/* Unknown rate: should not happen. */ |
| 3457 |
default: tap->wr_rate = 0; |
| 3458 |
} |
| 3459 |
} |
| 3460 |
|
| 3461 |
return true; |
| 3462 |
} |
| 3463 |
|
| 3464 |
static bool |
| 3465 |
iwm_mvm_rx_mpdu(struct iwm_softc *sc, struct mbuf *m, uint32_t offset, |
| 3466 |
bool stolen) |
| 3467 |
{ |
| 3468 |
struct ieee80211com *ic; |
| 3469 |
struct ieee80211_frame *wh; |
| 3470 |
struct ieee80211_node *ni; |
| 3471 |
bool ret; |
| 3472 |
|
| 3473 |
ic = &sc->sc_ic; |
| 3474 |
|
| 3475 |
ret = sc->cfg->mqrx_supported ? |
| 3476 |
iwm_mvm_rx_mpdu_mq(sc, m, offset, stolen) : |
| 3477 |
iwm_mvm_rx_rx_mpdu(sc, m, offset, stolen); |
| 3478 |
if (!ret) { |
| 3479 |
counter_u64_add(ic->ic_ierrors, 1); |
| 3480 |
return (ret); |
| 3481 |
} |
| 3482 |
|
| 3483 |
wh = mtod(m, struct ieee80211_frame *); |
| 3484 |
ni = ieee80211_find_rxnode(ic, (struct ieee80211_frame_min *)wh); |
| 3485 |
|
| 3242 |
IWM_UNLOCK(sc); |
3486 |
IWM_UNLOCK(sc); |
| 3243 |
if (ni != NULL) { |
3487 |
if (ni != NULL) { |
| 3244 |
IWM_DPRINTF(sc, IWM_DEBUG_RECV, "input m %p\n", m); |
3488 |
IWM_DPRINTF(sc, IWM_DEBUG_RECV, "input m %p\n", m); |
|
Lines 3250-3260
iwm_mvm_rx_rx_mpdu(struct iwm_softc *sc, struct mbuf *m, uint32_t offset,
Link Here
|
| 3250 |
} |
3494 |
} |
| 3251 |
IWM_LOCK(sc); |
3495 |
IWM_LOCK(sc); |
| 3252 |
|
3496 |
|
| 3253 |
return TRUE; |
3497 |
return true; |
| 3254 |
|
|
|
| 3255 |
fail: |
| 3256 |
counter_u64_add(ic->ic_ierrors, 1); |
| 3257 |
return FALSE; |
| 3258 |
} |
3498 |
} |
| 3259 |
|
3499 |
|
| 3260 |
static int |
3500 |
static int |
|
Lines 3338-3350
static void
Link Here
|
| 3338 |
iwm_mvm_rx_tx_cmd(struct iwm_softc *sc, struct iwm_rx_packet *pkt) |
3578 |
iwm_mvm_rx_tx_cmd(struct iwm_softc *sc, struct iwm_rx_packet *pkt) |
| 3339 |
{ |
3579 |
{ |
| 3340 |
struct iwm_cmd_header *cmd_hdr = &pkt->hdr; |
3580 |
struct iwm_cmd_header *cmd_hdr = &pkt->hdr; |
| 3341 |
int idx = cmd_hdr->idx; |
3581 |
struct iwm_tx_ring *ring; |
| 3342 |
int qid = cmd_hdr->qid; |
3582 |
struct iwm_tx_data *txd; |
| 3343 |
struct iwm_tx_ring *ring = &sc->txq[qid]; |
3583 |
struct iwm_node *in; |
| 3344 |
struct iwm_tx_data *txd = &ring->data[idx]; |
3584 |
struct mbuf *m; |
| 3345 |
struct iwm_node *in = txd->in; |
3585 |
int idx, qid, qmsk, status; |
| 3346 |
struct mbuf *m = txd->m; |
3586 |
|
| 3347 |
int status; |
3587 |
idx = cmd_hdr->idx; |
|
|
3588 |
qid = cmd_hdr->qid; |
| 3589 |
qmsk = 1 << qid; |
| 3590 |
|
| 3591 |
ring = &sc->txq[qid]; |
| 3592 |
txd = &ring->data[idx]; |
| 3593 |
in = txd->in; |
| 3594 |
m = txd->m; |
| 3348 |
|
3595 |
|
| 3349 |
KASSERT(txd->done == 0, ("txd not done")); |
3596 |
KASSERT(txd->done == 0, ("txd not done")); |
| 3350 |
KASSERT(txd->in != NULL, ("txd without node")); |
3597 |
KASSERT(txd->in != NULL, ("txd without node")); |
|
Lines 3366-3376
iwm_mvm_rx_tx_cmd(struct iwm_softc *sc, struct iwm_rx_packet *pkt)
Link Here
|
| 3366 |
|
3613 |
|
| 3367 |
ieee80211_tx_complete(&in->in_ni, m, status); |
3614 |
ieee80211_tx_complete(&in->in_ni, m, status); |
| 3368 |
|
3615 |
|
| 3369 |
if (--ring->queued < IWM_TX_RING_LOMARK) { |
3616 |
if (--ring->queued < IWM_TX_RING_LOMARK && (sc->qfullmsk & qmsk) != 0) { |
| 3370 |
sc->qfullmsk &= ~(1 << ring->qid); |
3617 |
sc->qfullmsk &= ~qmsk; |
| 3371 |
if (sc->qfullmsk == 0) { |
3618 |
if (sc->qfullmsk == 0) |
| 3372 |
iwm_start(sc); |
3619 |
iwm_start(sc); |
| 3373 |
} |
|
|
| 3374 |
} |
3620 |
} |
| 3375 |
} |
3621 |
} |
| 3376 |
|
3622 |
|
|
Lines 3531-3537
iwm_tx_fill_cmd(struct iwm_softc *sc, struct iwm_node *in,
Link Here
|
| 3531 |
); |
3777 |
); |
| 3532 |
|
3778 |
|
| 3533 |
/* XXX TODO: hard-coded TX antenna? */ |
3779 |
/* XXX TODO: hard-coded TX antenna? */ |
| 3534 |
rate_flags = 1 << IWM_RATE_MCS_ANT_POS; |
3780 |
if (sc->cfg->device_family == IWM_DEVICE_FAMILY_9000) |
|
|
3781 |
rate_flags = IWM_RATE_MCS_ANT_B_MSK; |
| 3782 |
else |
| 3783 |
rate_flags = IWM_RATE_MCS_ANT_A_MSK; |
| 3535 |
if (IWM_RIDX_IS_CCK(ridx)) |
3784 |
if (IWM_RIDX_IS_CCK(ridx)) |
| 3536 |
rate_flags |= IWM_RATE_MCS_CCK_MSK; |
3785 |
rate_flags |= IWM_RATE_MCS_CCK_MSK; |
| 3537 |
tx->rate_n_flags = htole32(rate_flags | rinfo->plcp); |
3786 |
tx->rate_n_flags = htole32(rate_flags | rinfo->plcp); |
|
Lines 3568-3574
iwm_tx(struct iwm_softc *sc, struct mbuf *m, struct ieee80211_node *ni, int ac)
Link Here
|
| 3568 |
tid = 0; |
3817 |
tid = 0; |
| 3569 |
ring = &sc->txq[ac]; |
3818 |
ring = &sc->txq[ac]; |
| 3570 |
desc = &ring->desc[ring->cur]; |
3819 |
desc = &ring->desc[ring->cur]; |
| 3571 |
memset(desc, 0, sizeof(*desc)); |
|
|
| 3572 |
data = &ring->data[ring->cur]; |
3820 |
data = &ring->data[ring->cur]; |
| 3573 |
|
3821 |
|
| 3574 |
/* Fill out iwm_tx_cmd to send to the firmware */ |
3822 |
/* Fill out iwm_tx_cmd to send to the firmware */ |
|
Lines 3607-3631
iwm_tx(struct iwm_softc *sc, struct mbuf *m, struct ieee80211_node *ni, int ac)
Link Here
|
| 3607 |
ieee80211_radiotap_tx(vap, m); |
3855 |
ieee80211_radiotap_tx(vap, m); |
| 3608 |
} |
3856 |
} |
| 3609 |
|
3857 |
|
| 3610 |
|
|
|
| 3611 |
totlen = m->m_pkthdr.len; |
| 3612 |
|
| 3613 |
flags = 0; |
3858 |
flags = 0; |
|
|
3859 |
totlen = m->m_pkthdr.len; |
| 3614 |
if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) { |
3860 |
if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) { |
| 3615 |
flags |= IWM_TX_CMD_FLG_ACK; |
3861 |
flags |= IWM_TX_CMD_FLG_ACK; |
| 3616 |
} |
3862 |
} |
| 3617 |
|
3863 |
|
| 3618 |
if (type == IEEE80211_FC0_TYPE_DATA |
3864 |
if (type == IEEE80211_FC0_TYPE_DATA && |
| 3619 |
&& (totlen + IEEE80211_CRC_LEN > vap->iv_rtsthreshold) |
3865 |
totlen + IEEE80211_CRC_LEN > vap->iv_rtsthreshold && |
| 3620 |
&& !IEEE80211_IS_MULTICAST(wh->i_addr1)) { |
3866 |
!IEEE80211_IS_MULTICAST(wh->i_addr1)) { |
| 3621 |
flags |= IWM_TX_CMD_FLG_PROT_REQUIRE; |
3867 |
flags |= IWM_TX_CMD_FLG_PROT_REQUIRE; |
| 3622 |
} |
3868 |
} |
| 3623 |
|
3869 |
|
| 3624 |
if (IEEE80211_IS_MULTICAST(wh->i_addr1) || |
3870 |
tx->sta_id = IWM_STATION_ID; |
| 3625 |
type != IEEE80211_FC0_TYPE_DATA) |
|
|
| 3626 |
tx->sta_id = sc->sc_aux_sta.sta_id; |
| 3627 |
else |
| 3628 |
tx->sta_id = IWM_STATION_ID; |
| 3629 |
|
3871 |
|
| 3630 |
if (type == IEEE80211_FC0_TYPE_MGT) { |
3872 |
if (type == IEEE80211_FC0_TYPE_MGT) { |
| 3631 |
uint8_t subtype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK; |
3873 |
uint8_t subtype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK; |
|
Lines 3645-3656
iwm_tx(struct iwm_softc *sc, struct mbuf *m, struct ieee80211_node *ni, int ac)
Link Here
|
| 3645 |
if (hdrlen & 3) { |
3887 |
if (hdrlen & 3) { |
| 3646 |
/* First segment length must be a multiple of 4. */ |
3888 |
/* First segment length must be a multiple of 4. */ |
| 3647 |
flags |= IWM_TX_CMD_FLG_MH_PAD; |
3889 |
flags |= IWM_TX_CMD_FLG_MH_PAD; |
|
|
3890 |
tx->offload_assist |= htole16(1 << IWM_TX_CMD_OFFLD_PAD); |
| 3648 |
pad = 4 - (hdrlen & 3); |
3891 |
pad = 4 - (hdrlen & 3); |
| 3649 |
} else |
3892 |
} else { |
|
|
3893 |
tx->offload_assist = 0; |
| 3650 |
pad = 0; |
3894 |
pad = 0; |
| 3651 |
|
3895 |
} |
| 3652 |
tx->driver_txop = 0; |
|
|
| 3653 |
tx->next_frame_len = 0; |
| 3654 |
|
3896 |
|
| 3655 |
tx->len = htole16(totlen); |
3897 |
tx->len = htole16(totlen); |
| 3656 |
tx->tid_tspec = tid; |
3898 |
tx->tid_tspec = tid; |
|
Lines 3661-3667
iwm_tx(struct iwm_softc *sc, struct mbuf *m, struct ieee80211_node *ni, int ac)
Link Here
|
| 3661 |
tx->dram_msb_ptr = iwm_get_dma_hi_addr(data->scratch_paddr); |
3903 |
tx->dram_msb_ptr = iwm_get_dma_hi_addr(data->scratch_paddr); |
| 3662 |
|
3904 |
|
| 3663 |
/* Copy 802.11 header in TX command. */ |
3905 |
/* Copy 802.11 header in TX command. */ |
| 3664 |
memcpy(((uint8_t *)tx) + sizeof(*tx), wh, hdrlen); |
3906 |
memcpy((uint8_t *)tx + sizeof(*tx), wh, hdrlen); |
| 3665 |
|
3907 |
|
| 3666 |
flags |= IWM_TX_CMD_FLG_BT_DIS | IWM_TX_CMD_FLG_SEQ_CTL; |
3908 |
flags |= IWM_TX_CMD_FLG_BT_DIS | IWM_TX_CMD_FLG_SEQ_CTL; |
| 3667 |
|
3909 |
|
|
Lines 3715-3737
iwm_tx(struct iwm_softc *sc, struct mbuf *m, struct ieee80211_node *ni, int ac)
Link Here
|
| 3715 |
); |
3957 |
); |
| 3716 |
|
3958 |
|
| 3717 |
/* Fill TX descriptor. */ |
3959 |
/* Fill TX descriptor. */ |
|
|
3960 |
memset(desc, 0, sizeof(*desc)); |
| 3718 |
desc->num_tbs = 2 + nsegs; |
3961 |
desc->num_tbs = 2 + nsegs; |
| 3719 |
|
3962 |
|
| 3720 |
desc->tbs[0].lo = htole32(data->cmd_paddr); |
3963 |
desc->tbs[0].lo = htole32(data->cmd_paddr); |
| 3721 |
desc->tbs[0].hi_n_len = htole16(iwm_get_dma_hi_addr(data->cmd_paddr)) | |
3964 |
desc->tbs[0].hi_n_len = htole16(iwm_get_dma_hi_addr(data->cmd_paddr) | |
| 3722 |
(TB0_SIZE << 4); |
3965 |
(TB0_SIZE << 4)); |
| 3723 |
desc->tbs[1].lo = htole32(data->cmd_paddr + TB0_SIZE); |
3966 |
desc->tbs[1].lo = htole32(data->cmd_paddr + TB0_SIZE); |
| 3724 |
desc->tbs[1].hi_n_len = htole16(iwm_get_dma_hi_addr(data->cmd_paddr)) | |
3967 |
desc->tbs[1].hi_n_len = htole16(iwm_get_dma_hi_addr(data->cmd_paddr) | |
| 3725 |
((sizeof(struct iwm_cmd_header) + sizeof(*tx) |
3968 |
((sizeof(struct iwm_cmd_header) + sizeof(*tx) + |
| 3726 |
+ hdrlen + pad - TB0_SIZE) << 4); |
3969 |
hdrlen + pad - TB0_SIZE) << 4)); |
| 3727 |
|
3970 |
|
| 3728 |
/* Other DMA segments are for data payload. */ |
3971 |
/* Other DMA segments are for data payload. */ |
| 3729 |
for (i = 0; i < nsegs; i++) { |
3972 |
for (i = 0; i < nsegs; i++) { |
| 3730 |
seg = &segs[i]; |
3973 |
seg = &segs[i]; |
| 3731 |
desc->tbs[i+2].lo = htole32(seg->ds_addr); |
3974 |
desc->tbs[i + 2].lo = htole32(seg->ds_addr); |
| 3732 |
desc->tbs[i+2].hi_n_len = \ |
3975 |
desc->tbs[i + 2].hi_n_len = |
| 3733 |
htole16(iwm_get_dma_hi_addr(seg->ds_addr)) |
3976 |
htole16(iwm_get_dma_hi_addr(seg->ds_addr)) | |
| 3734 |
| ((seg->ds_len) << 4); |
3977 |
(seg->ds_len << 4); |
| 3735 |
} |
3978 |
} |
| 3736 |
|
3979 |
|
| 3737 |
bus_dmamap_sync(ring->data_dmat, data->map, |
3980 |
bus_dmamap_sync(ring->data_dmat, data->map, |
|
Lines 4444-4451
static boolean_t
Link Here
|
| 4444 |
iwm_mvm_is_lar_supported(struct iwm_softc *sc) |
4687 |
iwm_mvm_is_lar_supported(struct iwm_softc *sc) |
| 4445 |
{ |
4688 |
{ |
| 4446 |
boolean_t nvm_lar = sc->nvm_data->lar_enabled; |
4689 |
boolean_t nvm_lar = sc->nvm_data->lar_enabled; |
| 4447 |
boolean_t tlv_lar = fw_has_capa(&sc->sc_fw.ucode_capa, |
4690 |
boolean_t tlv_lar = iwm_fw_has_capa(sc, IWM_UCODE_TLV_CAPA_LAR_SUPPORT); |
| 4448 |
IWM_UCODE_TLV_CAPA_LAR_SUPPORT); |
|
|
| 4449 |
|
4691 |
|
| 4450 |
if (iwm_lar_disable) |
4692 |
if (iwm_lar_disable) |
| 4451 |
return FALSE; |
4693 |
return FALSE; |
|
Lines 4454-4460
iwm_mvm_is_lar_supported(struct iwm_softc *sc)
Link Here
|
| 4454 |
* Enable LAR only if it is supported by the FW (TLV) && |
4696 |
* Enable LAR only if it is supported by the FW (TLV) && |
| 4455 |
* enabled in the NVM |
4697 |
* enabled in the NVM |
| 4456 |
*/ |
4698 |
*/ |
| 4457 |
if (sc->cfg->device_family == IWM_DEVICE_FAMILY_8000) |
4699 |
if (sc->cfg->device_family >= IWM_DEVICE_FAMILY_8000) |
| 4458 |
return nvm_lar && tlv_lar; |
4700 |
return nvm_lar && tlv_lar; |
| 4459 |
else |
4701 |
else |
| 4460 |
return tlv_lar; |
4702 |
return tlv_lar; |
|
Lines 4463-4472
iwm_mvm_is_lar_supported(struct iwm_softc *sc)
Link Here
|
| 4463 |
static boolean_t |
4705 |
static boolean_t |
| 4464 |
iwm_mvm_is_wifi_mcc_supported(struct iwm_softc *sc) |
4706 |
iwm_mvm_is_wifi_mcc_supported(struct iwm_softc *sc) |
| 4465 |
{ |
4707 |
{ |
| 4466 |
return fw_has_api(&sc->sc_fw.ucode_capa, |
4708 |
return iwm_fw_has_api(sc, IWM_UCODE_TLV_API_WIFI_MCC_UPDATE) || |
| 4467 |
IWM_UCODE_TLV_API_WIFI_MCC_UPDATE) || |
4709 |
iwm_fw_has_capa(sc, IWM_UCODE_TLV_CAPA_LAR_MULTI_MCC); |
| 4468 |
fw_has_capa(&sc->sc_fw.ucode_capa, |
|
|
| 4469 |
IWM_UCODE_TLV_CAPA_LAR_MULTI_MCC); |
| 4470 |
} |
4710 |
} |
| 4471 |
|
4711 |
|
| 4472 |
static int |
4712 |
static int |
|
Lines 4486-4493
iwm_send_update_mcc_cmd(struct iwm_softc *sc, const char *alpha2)
Link Here
|
| 4486 |
int n_channels; |
4726 |
int n_channels; |
| 4487 |
uint16_t mcc; |
4727 |
uint16_t mcc; |
| 4488 |
#endif |
4728 |
#endif |
| 4489 |
int resp_v2 = fw_has_capa(&sc->sc_fw.ucode_capa, |
4729 |
int resp_v2 = iwm_fw_has_capa(sc, IWM_UCODE_TLV_CAPA_LAR_SUPPORT_V2); |
| 4490 |
IWM_UCODE_TLV_CAPA_LAR_SUPPORT_V2); |
|
|
| 4491 |
|
4730 |
|
| 4492 |
if (!iwm_mvm_is_lar_supported(sc)) { |
4731 |
if (!iwm_mvm_is_lar_supported(sc)) { |
| 4493 |
IWM_DPRINTF(sc, IWM_DEBUG_LAR, "%s: no LAR support\n", |
4732 |
IWM_DPRINTF(sc, IWM_DEBUG_LAR, "%s: no LAR support\n", |
|
Lines 4648-4654
iwm_init_hw(struct iwm_softc *sc)
Link Here
|
| 4648 |
if ((error = iwm_send_update_mcc_cmd(sc, "ZZ")) != 0) |
4887 |
if ((error = iwm_send_update_mcc_cmd(sc, "ZZ")) != 0) |
| 4649 |
goto error; |
4888 |
goto error; |
| 4650 |
|
4889 |
|
| 4651 |
if (fw_has_capa(&sc->sc_fw.ucode_capa, IWM_UCODE_TLV_CAPA_UMAC_SCAN)) { |
4890 |
if (iwm_fw_has_capa(sc, IWM_UCODE_TLV_CAPA_UMAC_SCAN)) { |
| 4652 |
if ((error = iwm_mvm_config_umac_scan(sc)) != 0) |
4891 |
if ((error = iwm_mvm_config_umac_scan(sc)) != 0) |
| 4653 |
goto error; |
4892 |
goto error; |
| 4654 |
} |
4893 |
} |
|
Lines 5148-5154
iwm_handle_rxb(struct iwm_softc *sc, struct mbuf *m)
Link Here
|
| 5148 |
nextpkt->hdr.idx == 0) || |
5387 |
nextpkt->hdr.idx == 0) || |
| 5149 |
(nextpkt->len_n_flags == |
5388 |
(nextpkt->len_n_flags == |
| 5150 |
htole32(IWM_FH_RSCSR_FRAME_INVALID))) { |
5389 |
htole32(IWM_FH_RSCSR_FRAME_INVALID))) { |
| 5151 |
if (iwm_mvm_rx_rx_mpdu(sc, m, offset, stolen)) { |
5390 |
if (iwm_mvm_rx_mpdu(sc, m, offset, stolen)) { |
| 5152 |
stolen = FALSE; |
5391 |
stolen = FALSE; |
| 5153 |
/* Make sure we abort the loop */ |
5392 |
/* Make sure we abort the loop */ |
| 5154 |
nextoff = maxoff; |
5393 |
nextoff = maxoff; |
|
Lines 5159-5172
iwm_handle_rxb(struct iwm_softc *sc, struct mbuf *m)
Link Here
|
| 5159 |
/* |
5398 |
/* |
| 5160 |
* Use m_copym instead of m_split, because that |
5399 |
* Use m_copym instead of m_split, because that |
| 5161 |
* makes it easier to keep a valid rx buffer in |
5400 |
* makes it easier to keep a valid rx buffer in |
| 5162 |
* the ring, when iwm_mvm_rx_rx_mpdu() fails. |
5401 |
* the ring, when iwm_mvm_rx_mpdu() fails. |
| 5163 |
* |
5402 |
* |
| 5164 |
* We need to start m_copym() at offset 0, to get the |
5403 |
* We need to start m_copym() at offset 0, to get the |
| 5165 |
* M_PKTHDR flag preserved. |
5404 |
* M_PKTHDR flag preserved. |
| 5166 |
*/ |
5405 |
*/ |
| 5167 |
m1 = m_copym(m, 0, M_COPYALL, M_NOWAIT); |
5406 |
m1 = m_copym(m, 0, M_COPYALL, M_NOWAIT); |
| 5168 |
if (m1) { |
5407 |
if (m1) { |
| 5169 |
if (iwm_mvm_rx_rx_mpdu(sc, m1, offset, stolen)) |
5408 |
if (iwm_mvm_rx_mpdu(sc, m1, offset, stolen)) |
| 5170 |
stolen = TRUE; |
5409 |
stolen = TRUE; |
| 5171 |
else |
5410 |
else |
| 5172 |
m_freem(m1); |
5411 |
m_freem(m1); |
|
Lines 5415-5425
iwm_handle_rxb(struct iwm_softc *sc, struct mbuf *m)
Link Here
|
| 5415 |
static void |
5654 |
static void |
| 5416 |
iwm_notif_intr(struct iwm_softc *sc) |
5655 |
iwm_notif_intr(struct iwm_softc *sc) |
| 5417 |
{ |
5656 |
{ |
|
|
5657 |
int count; |
| 5658 |
uint32_t wreg; |
| 5418 |
uint16_t hw; |
5659 |
uint16_t hw; |
| 5419 |
|
5660 |
|
| 5420 |
bus_dmamap_sync(sc->rxq.stat_dma.tag, sc->rxq.stat_dma.map, |
5661 |
bus_dmamap_sync(sc->rxq.stat_dma.tag, sc->rxq.stat_dma.map, |
| 5421 |
BUS_DMASYNC_POSTREAD); |
5662 |
BUS_DMASYNC_POSTREAD); |
| 5422 |
|
5663 |
|
|
|
5664 |
if (sc->cfg->mqrx_supported) { |
| 5665 |
count = IWM_RX_MQ_RING_COUNT; |
| 5666 |
wreg = IWM_RFH_Q0_FRBDCB_WIDX_TRG; |
| 5667 |
} else { |
| 5668 |
count = IWM_RX_LEGACY_RING_COUNT; |
| 5669 |
wreg = IWM_FH_RSCSR_CHNL0_WPTR; |
| 5670 |
} |
| 5671 |
|
| 5423 |
hw = le16toh(sc->rxq.stat->closed_rb_num) & 0xfff; |
5672 |
hw = le16toh(sc->rxq.stat->closed_rb_num) & 0xfff; |
| 5424 |
|
5673 |
|
| 5425 |
/* |
5674 |
/* |
|
Lines 5436-5442
iwm_notif_intr(struct iwm_softc *sc)
Link Here
|
| 5436 |
"%s: hw = %d cur = %d\n", __func__, hw, ring->cur); |
5685 |
"%s: hw = %d cur = %d\n", __func__, hw, ring->cur); |
| 5437 |
iwm_handle_rxb(sc, data->m); |
5686 |
iwm_handle_rxb(sc, data->m); |
| 5438 |
|
5687 |
|
| 5439 |
ring->cur = (ring->cur + 1) % IWM_RX_RING_COUNT; |
5688 |
ring->cur = (ring->cur + 1) % count; |
| 5440 |
} |
5689 |
} |
| 5441 |
|
5690 |
|
| 5442 |
/* |
5691 |
/* |
|
Lines 5445-5452
iwm_notif_intr(struct iwm_softc *sc)
Link Here
|
| 5445 |
* Seems like the hardware gets upset unless we align |
5694 |
* Seems like the hardware gets upset unless we align |
| 5446 |
* the write by 8?? |
5695 |
* the write by 8?? |
| 5447 |
*/ |
5696 |
*/ |
| 5448 |
hw = (hw == 0) ? IWM_RX_RING_COUNT - 1 : hw - 1; |
5697 |
hw = (hw == 0) ? count - 1 : hw - 1; |
| 5449 |
IWM_WRITE(sc, IWM_FH_RSCSR_CHNL0_WPTR, rounddown2(hw, 8)); |
5698 |
IWM_WRITE(sc, wreg, rounddown2(hw, 8)); |
| 5450 |
} |
5699 |
} |
| 5451 |
|
5700 |
|
| 5452 |
static void |
5701 |
static void |
|
Lines 5621-5626
iwm_intr(void *arg)
Link Here
|
| 5621 |
#define PCI_PRODUCT_INTEL_WL_8260_1 0x24f3 |
5870 |
#define PCI_PRODUCT_INTEL_WL_8260_1 0x24f3 |
| 5622 |
#define PCI_PRODUCT_INTEL_WL_8260_2 0x24f4 |
5871 |
#define PCI_PRODUCT_INTEL_WL_8260_2 0x24f4 |
| 5623 |
#define PCI_PRODUCT_INTEL_WL_8265_1 0x24fd |
5872 |
#define PCI_PRODUCT_INTEL_WL_8265_1 0x24fd |
|
|
5873 |
#define PCI_PRODUCT_INTEL_WL_9560_1 0x9df0 |
| 5874 |
#define PCI_PRODUCT_INTEL_WL_9260_1 0x2526 |
| 5624 |
|
5875 |
|
| 5625 |
static const struct iwm_devices { |
5876 |
static const struct iwm_devices { |
| 5626 |
uint16_t device; |
5877 |
uint16_t device; |
|
Lines 5638-5643
static const struct iwm_devices {
Link Here
|
| 5638 |
{ PCI_PRODUCT_INTEL_WL_8260_1, &iwm8260_cfg }, |
5889 |
{ PCI_PRODUCT_INTEL_WL_8260_1, &iwm8260_cfg }, |
| 5639 |
{ PCI_PRODUCT_INTEL_WL_8260_2, &iwm8260_cfg }, |
5890 |
{ PCI_PRODUCT_INTEL_WL_8260_2, &iwm8260_cfg }, |
| 5640 |
{ PCI_PRODUCT_INTEL_WL_8265_1, &iwm8265_cfg }, |
5891 |
{ PCI_PRODUCT_INTEL_WL_8265_1, &iwm8265_cfg }, |
|
|
5892 |
{ PCI_PRODUCT_INTEL_WL_9560_1, &iwm9560_cfg }, |
| 5893 |
{ PCI_PRODUCT_INTEL_WL_9260_1, &iwm9260_cfg }, |
| 5641 |
}; |
5894 |
}; |
| 5642 |
|
5895 |
|
| 5643 |
static int |
5896 |
static int |
|
Lines 5749-5756
iwm_pci_detach(device_t dev)
Link Here
|
| 5749 |
rman_get_rid(sc->sc_mem), sc->sc_mem); |
6002 |
rman_get_rid(sc->sc_mem), sc->sc_mem); |
| 5750 |
} |
6003 |
} |
| 5751 |
|
6004 |
|
| 5752 |
|
|
|
| 5753 |
|
| 5754 |
static int |
6005 |
static int |
| 5755 |
iwm_attach(device_t dev) |
6006 |
iwm_attach(device_t dev) |
| 5756 |
{ |
6007 |
{ |
|
Lines 5761-5772
iwm_attach(device_t dev)
Link Here
|
| 5761 |
|
6012 |
|
| 5762 |
sc->sc_dev = dev; |
6013 |
sc->sc_dev = dev; |
| 5763 |
sc->sc_attached = 1; |
6014 |
sc->sc_attached = 1; |
|
|
6015 |
sc->sc_debug = (sc->sc_debug | IWM_DEBUG_ANY); |
| 5764 |
IWM_LOCK_INIT(sc); |
6016 |
IWM_LOCK_INIT(sc); |
| 5765 |
mbufq_init(&sc->sc_snd, ifqmaxlen); |
6017 |
mbufq_init(&sc->sc_snd, ifqmaxlen); |
| 5766 |
callout_init_mtx(&sc->sc_watchdog_to, &sc->sc_mtx, 0); |
6018 |
callout_init_mtx(&sc->sc_watchdog_to, &sc->sc_mtx, 0); |
| 5767 |
callout_init_mtx(&sc->sc_led_blink_to, &sc->sc_mtx, 0); |
6019 |
callout_init_mtx(&sc->sc_led_blink_to, &sc->sc_mtx, 0); |
| 5768 |
TASK_INIT(&sc->sc_es_task, 0, iwm_endscan_cb, sc); |
6020 |
TASK_INIT(&sc->sc_es_task, 0, iwm_endscan_cb, sc); |
| 5769 |
|
6021 |
|
|
|
6022 |
error = iwm_dev_check(dev); |
| 6023 |
if (error != 0) |
| 6024 |
goto fail; |
| 6025 |
|
| 5770 |
sc->sc_notif_wait = iwm_notification_wait_init(sc); |
6026 |
sc->sc_notif_wait = iwm_notification_wait_init(sc); |
| 5771 |
if (sc->sc_notif_wait == NULL) { |
6027 |
if (sc->sc_notif_wait == NULL) { |
| 5772 |
device_printf(dev, "failed to init notification wait struct\n"); |
6028 |
device_printf(dev, "failed to init notification wait struct\n"); |
|
Lines 5792-5802
iwm_attach(device_t dev)
Link Here
|
| 5792 |
|
6048 |
|
| 5793 |
sc->sc_wantresp = -1; |
6049 |
sc->sc_wantresp = -1; |
| 5794 |
|
6050 |
|
| 5795 |
/* Match device id */ |
|
|
| 5796 |
error = iwm_dev_check(dev); |
| 5797 |
if (error != 0) |
| 5798 |
goto fail; |
| 5799 |
|
| 5800 |
sc->sc_hw_rev = IWM_READ(sc, IWM_CSR_HW_REV); |
6051 |
sc->sc_hw_rev = IWM_READ(sc, IWM_CSR_HW_REV); |
| 5801 |
/* |
6052 |
/* |
| 5802 |
* In the 8000 HW family the format of the 4 bytes of CSR_HW_REV have |
6053 |
* In the 8000 HW family the format of the 4 bytes of CSR_HW_REV have |
|
Lines 5804-5810
iwm_attach(device_t dev)
Link Here
|
| 5804 |
* "dash" value). To keep hw_rev backwards compatible - we'll store it |
6055 |
* "dash" value). To keep hw_rev backwards compatible - we'll store it |
| 5805 |
* in the old format. |
6056 |
* in the old format. |
| 5806 |
*/ |
6057 |
*/ |
| 5807 |
if (sc->cfg->device_family == IWM_DEVICE_FAMILY_8000) { |
6058 |
if (sc->cfg->device_family >= IWM_DEVICE_FAMILY_8000) { |
| 5808 |
int ret; |
6059 |
int ret; |
| 5809 |
uint32_t hw_step; |
6060 |
uint32_t hw_step; |
| 5810 |
|
6061 |
|
|
Lines 6185-6191
iwm_scan_start(struct ieee80211com *ic)
Link Here
|
| 6185 |
device_printf(sc->sc_dev, |
6436 |
device_printf(sc->sc_dev, |
| 6186 |
"%s: Previous scan not completed yet\n", __func__); |
6437 |
"%s: Previous scan not completed yet\n", __func__); |
| 6187 |
} |
6438 |
} |
| 6188 |
if (fw_has_capa(&sc->sc_fw.ucode_capa, IWM_UCODE_TLV_CAPA_UMAC_SCAN)) |
6439 |
if (iwm_fw_has_capa(sc, IWM_UCODE_TLV_CAPA_UMAC_SCAN)) |
| 6189 |
error = iwm_mvm_umac_scan(sc); |
6440 |
error = iwm_mvm_umac_scan(sc); |
| 6190 |
else |
6441 |
else |
| 6191 |
error = iwm_mvm_lmac_scan(sc); |
6442 |
error = iwm_mvm_lmac_scan(sc); |