X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=lib%2Flibrte_pmd_ixgbe%2Fixgbe_ethdev.c;h=a147d46245c1b13b03b0c7c09f19390be1fe585c;hb=835647548d783ef368dd682bc288e2af2979ab9c;hp=618488a6a489826c4cf74b60eeceaab38e9a56c8;hpb=8ef32003772a14c61c70b540e41c259c482c2fb6;p=dpdk.git diff --git a/lib/librte_pmd_ixgbe/ixgbe_ethdev.c b/lib/librte_pmd_ixgbe/ixgbe_ethdev.c index 618488a6a4..a147d46245 100644 --- a/lib/librte_pmd_ixgbe/ixgbe_ethdev.c +++ b/lib/librte_pmd_ixgbe/ixgbe_ethdev.c @@ -547,12 +547,13 @@ ixgbe_dev_queue_stats_mapping_set(struct rte_eth_dev *eth_dev, if ((hw->mac.type != ixgbe_mac_82599EB) && (hw->mac.type != ixgbe_mac_X540)) return -ENOSYS; - PMD_INIT_LOG(INFO, "Setting port %d, %s queue_id %d to stat index %d\n", - (int)(eth_dev->data->port_id), is_rx ? "RX" : "TX", queue_id, stat_idx); + PMD_INIT_LOG(INFO, "Setting port %d, %s queue_id %d to stat index %d", + (int)(eth_dev->data->port_id), is_rx ? "RX" : "TX", + queue_id, stat_idx); n = (uint8_t)(queue_id / NB_QMAP_FIELDS_PER_QSM_REG); if (n >= IXGBE_NB_STAT_MAPPING_REGS) { - PMD_INIT_LOG(ERR, "Nb of stat mapping registers exceeded\n"); + PMD_INIT_LOG(ERR, "Nb of stat mapping registers exceeded"); return -EIO; } offset = (uint8_t)(queue_id % NB_QMAP_FIELDS_PER_QSM_REG); @@ -572,19 +573,20 @@ ixgbe_dev_queue_stats_mapping_set(struct rte_eth_dev *eth_dev, else stat_mappings->rqsmr[n] |= qsmr_mask; - PMD_INIT_LOG(INFO, "Set port %d, %s queue_id %d to stat index %d\n" - "%s[%d] = 0x%08x\n", - (int)(eth_dev->data->port_id), is_rx ? "RX" : "TX", queue_id, stat_idx, - is_rx ? "RQSMR" : "TQSM",n, is_rx ? stat_mappings->rqsmr[n] : stat_mappings->tqsm[n]); + PMD_INIT_LOG(INFO, "Set port %d, %s queue_id %d to stat index %d", + (int)(eth_dev->data->port_id), is_rx ? "RX" : "TX", + queue_id, stat_idx); + PMD_INIT_LOG(INFO, "%s[%d] = 0x%08x", is_rx ? "RQSMR" : "TQSM", n, + is_rx ? stat_mappings->rqsmr[n] : stat_mappings->tqsm[n]); /* Now write the mapping in the appropriate register */ if (is_rx) { - PMD_INIT_LOG(INFO, "Write 0x%x to RX IXGBE stat mapping reg:%d\n", + PMD_INIT_LOG(INFO, "Write 0x%x to RX IXGBE stat mapping reg:%d", stat_mappings->rqsmr[n], n); IXGBE_WRITE_REG(hw, IXGBE_RQSMR(n), stat_mappings->rqsmr[n]); } else { - PMD_INIT_LOG(INFO, "Write 0x%x to TX IXGBE stat mapping reg:%d\n", + PMD_INIT_LOG(INFO, "Write 0x%x to TX IXGBE stat mapping reg:%d", stat_mappings->tqsm[n], n); IXGBE_WRITE_REG(hw, IXGBE_TQSM(n), stat_mappings->tqsm[n]); } @@ -667,7 +669,7 @@ ixgbe_swfw_lock_reset(struct ixgbe_hw *hw) */ mask = IXGBE_GSSR_PHY0_SM << hw->bus.func; if (ixgbe_acquire_swfw_semaphore(hw, mask) < 0) { - DEBUGOUT1("SWFW phy%d lock released", hw->bus.func); + PMD_DRV_LOG(DEBUG, "SWFW phy%d lock released", hw->bus.func); } ixgbe_release_swfw_semaphore(hw, mask); @@ -679,7 +681,7 @@ ixgbe_swfw_lock_reset(struct ixgbe_hw *hw) */ mask = IXGBE_GSSR_EEP_SM | IXGBE_GSSR_MAC_CSR_SM | IXGBE_GSSR_SW_MNG_SM; if (ixgbe_acquire_swfw_semaphore(hw, mask) < 0) { - DEBUGOUT("SWFW common locks released"); + PMD_DRV_LOG(DEBUG, "SWFW common locks released"); } ixgbe_release_swfw_semaphore(hw, mask); } @@ -725,11 +727,9 @@ eth_ixgbe_dev_init(__attribute__((unused)) struct eth_driver *eth_drv, hw->device_id = pci_dev->id.device_id; hw->vendor_id = pci_dev->id.vendor_id; hw->hw_addr = (void *)pci_dev->mem_resource[0].addr; -#ifdef RTE_LIBRTE_IXGBE_ALLOW_UNSUPPORTED_SFP hw->allow_unsupported_sfp = 1; -#endif - /* Initialize the shared code */ + /* Initialize the shared code (base driver) */ #ifdef RTE_NIC_BYPASS diag = ixgbe_bypass_init_shared_code(hw); #else @@ -791,11 +791,12 @@ eth_ixgbe_dev_init(__attribute__((unused)) struct eth_driver *eth_drv, if (diag == IXGBE_ERR_EEPROM_VERSION) { PMD_INIT_LOG(ERR, "This device is a pre-production adapter/" "LOM. Please be aware there may be issues associated " - "with your hardware.\n If you are experiencing problems " + "with your hardware."); + PMD_INIT_LOG(ERR, "If you are experiencing problems " "please contact your Intel or hardware representative " - "who provided you with this hardware.\n"); + "who provided you with this hardware."); } else if (diag == IXGBE_ERR_SFP_NOT_SUPPORTED) - PMD_INIT_LOG(ERR, "Unsupported SFP+ Module\n"); + PMD_INIT_LOG(ERR, "Unsupported SFP+ Module"); if (diag) { PMD_INIT_LOG(ERR, "Hardware Initialization Failure: %d", diag); return -EIO; @@ -849,12 +850,11 @@ eth_ixgbe_dev_init(__attribute__((unused)) struct eth_driver *eth_drv, IXGBE_WRITE_FLUSH(hw); if (ixgbe_is_sfp(hw) && hw->phy.sfp_type != ixgbe_sfp_type_not_present) - PMD_INIT_LOG(DEBUG, - "MAC: %d, PHY: %d, SFP+: %dmac.type, (int) hw->phy.type, (int) hw->phy.sfp_type); else - PMD_INIT_LOG(DEBUG, "MAC: %d, PHY: %d\n", + PMD_INIT_LOG(DEBUG, "MAC: %d, PHY: %d", (int) hw->mac.type, (int) hw->phy.type); PMD_INIT_LOG(DEBUG, "port %d vendorID=0x%x deviceID=0x%x", @@ -933,7 +933,7 @@ eth_ixgbevf_dev_init(__attribute__((unused)) struct eth_driver *eth_drv, IXGBE_DEV_PRIVATE_TO_HWSTRIP_BITMAP(eth_dev->data->dev_private); struct ether_addr *perm_addr = (struct ether_addr *) hw->mac.perm_addr; - PMD_INIT_LOG(DEBUG, "eth_ixgbevf_dev_init"); + PMD_INIT_FUNC_TRACE(); eth_dev->dev_ops = &ixgbevf_eth_dev_ops; eth_dev->rx_pkt_burst = &ixgbe_recv_pkts; @@ -960,7 +960,7 @@ eth_ixgbevf_dev_init(__attribute__((unused)) struct eth_driver *eth_drv, /* initialize the hw strip bitmap*/ memset(hwstrip, 0, sizeof(*hwstrip)); - /* Initialize the shared code */ + /* Initialize the shared code (base driver) */ diag = ixgbe_init_shared_code(hw); if (diag != IXGBE_SUCCESS) { PMD_INIT_LOG(ERR, "Shared code init failed for ixgbevf: %d", diag); @@ -1012,16 +1012,15 @@ eth_ixgbevf_dev_init(__attribute__((unused)) struct eth_driver *eth_drv, eth_dev->data->mac_addrs = NULL; return diag; } - RTE_LOG(INFO, PMD, - "\tVF MAC address not assigned by Host PF\n" - "\tAssign randomly generated MAC address " - "%02x:%02x:%02x:%02x:%02x:%02x\n", - perm_addr->addr_bytes[0], - perm_addr->addr_bytes[1], - perm_addr->addr_bytes[2], - perm_addr->addr_bytes[3], - perm_addr->addr_bytes[4], - perm_addr->addr_bytes[5]); + PMD_INIT_LOG(INFO, "\tVF MAC address not assigned by Host PF"); + PMD_INIT_LOG(INFO, "\tAssign randomly generated MAC address " + "%02x:%02x:%02x:%02x:%02x:%02x", + perm_addr->addr_bytes[0], + perm_addr->addr_bytes[1], + perm_addr->addr_bytes[2], + perm_addr->addr_bytes[3], + perm_addr->addr_bytes[4], + perm_addr->addr_bytes[5]); } /* Copy the permanent MAC address */ @@ -1038,9 +1037,9 @@ eth_ixgbevf_dev_init(__attribute__((unused)) struct eth_driver *eth_drv, return (-EIO); } - PMD_INIT_LOG(DEBUG, "\nport %d vendorID=0x%x deviceID=0x%x mac.type=%s\n", - eth_dev->data->port_id, pci_dev->id.vendor_id, pci_dev->id.device_id, - "ixgbe_mac_82599_vf"); + PMD_INIT_LOG(DEBUG, "port %d vendorID=0x%x deviceID=0x%x mac.type=%s", + eth_dev->data->port_id, pci_dev->id.vendor_id, + pci_dev->id.device_id, "ixgbe_mac_82599_vf"); return 0; } @@ -1049,7 +1048,7 @@ static struct eth_driver rte_ixgbe_pmd = { { .name = "rte_ixgbe_pmd", .id_table = pci_id_ixgbe_map, - .drv_flags = RTE_PCI_DRV_NEED_MAPPING, + .drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_INTR_LSC, }, .eth_dev_init = eth_ixgbe_dev_init, .dev_private_size = sizeof(struct ixgbe_adapter), @@ -1090,7 +1089,7 @@ rte_ixgbe_pmd_init(const char *name __rte_unused, const char *params __rte_unuse static int rte_ixgbevf_pmd_init(const char *name __rte_unused, const char *param __rte_unused) { - DEBUGFUNC("rte_ixgbevf_pmd_init"); + PMD_INIT_FUNC_TRACE(); rte_eth_driver_register(&rte_ixgbevf_pmd); return (0); @@ -1418,9 +1417,9 @@ ixgbe_dev_start(struct rte_eth_dev *dev) /* IXGBE devices don't support half duplex */ if ((dev->data->dev_conf.link_duplex != ETH_LINK_AUTONEG_DUPLEX) && (dev->data->dev_conf.link_duplex != ETH_LINK_FULL_DUPLEX)) { - PMD_INIT_LOG(ERR, "Invalid link_duplex (%hu) for port %hhu\n", - dev->data->dev_conf.link_duplex, - dev->data->port_id); + PMD_INIT_LOG(ERR, "Invalid link_duplex (%hu) for port %hhu", + dev->data->dev_conf.link_duplex, + dev->data->port_id); return -EINVAL; } @@ -1444,7 +1443,7 @@ ixgbe_dev_start(struct rte_eth_dev *dev) /* This can fail when allocating mbufs for descriptor rings */ err = ixgbe_dev_rx_init(dev); if (err) { - PMD_INIT_LOG(ERR, "Unable to initialize RX hardware\n"); + PMD_INIT_LOG(ERR, "Unable to initialize RX hardware"); goto error; } @@ -1491,9 +1490,9 @@ ixgbe_dev_start(struct rte_eth_dev *dev) speed = IXGBE_LINK_SPEED_10GB_FULL; break; default: - PMD_INIT_LOG(ERR, "Invalid link_speed (%hu) for port %hhu\n", - dev->data->dev_conf.link_speed, - dev->data->port_id); + PMD_INIT_LOG(ERR, "Invalid link_speed (%hu) for port %hhu", + dev->data->dev_conf.link_speed, + dev->data->port_id); goto error; } @@ -1599,10 +1598,8 @@ ixgbe_dev_set_link_up(struct rte_eth_dev *dev) #ifdef RTE_NIC_BYPASS if (hw->device_id == IXGBE_DEV_ID_82599_BYPASS) { /* Not suported in bypass mode */ - PMD_INIT_LOG(ERR, - "\nSet link up is not supported " - "by device id 0x%x\n", - hw->device_id); + PMD_INIT_LOG(ERR, "Set link up is not supported " + "by device id 0x%x", hw->device_id); return -ENOTSUP; } #endif @@ -1611,8 +1608,8 @@ ixgbe_dev_set_link_up(struct rte_eth_dev *dev) return 0; } - PMD_INIT_LOG(ERR, "\nSet link up is not supported by device id 0x%x\n", - hw->device_id); + PMD_INIT_LOG(ERR, "Set link up is not supported by device id 0x%x", + hw->device_id); return -ENOTSUP; } @@ -1628,10 +1625,8 @@ ixgbe_dev_set_link_down(struct rte_eth_dev *dev) #ifdef RTE_NIC_BYPASS if (hw->device_id == IXGBE_DEV_ID_82599_BYPASS) { /* Not suported in bypass mode */ - PMD_INIT_LOG(ERR, - "\nSet link down is not supported " - "by device id 0x%x\n", - hw->device_id); + PMD_INIT_LOG(ERR, "Set link down is not supported " + "by device id 0x%x", hw->device_id); return -ENOTSUP; } #endif @@ -1640,9 +1635,8 @@ ixgbe_dev_set_link_down(struct rte_eth_dev *dev) return 0; } - PMD_INIT_LOG(ERR, - "\nSet link down is not supported by device id 0x%x\n", - hw->device_id); + PMD_INIT_LOG(ERR, "Set link down is not supported by device id 0x%x", + hw->device_id); return -ENOTSUP; } @@ -2180,7 +2174,7 @@ ixgbe_dev_interrupt_action(struct rte_eth_dev *dev) struct rte_eth_link link; int intr_enable_delay = false; - PMD_DRV_LOG(DEBUG, "intr action type %d\n", intr->flags); + PMD_DRV_LOG(DEBUG, "intr action type %d", intr->flags); if (intr->flags & IXGBE_FLAG_MAILBOX) { ixgbe_pf_mbx_process(dev); @@ -2257,7 +2251,7 @@ ixgbe_dev_interrupt_delayed_handler(void *param) _rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_LSC); } - PMD_DRV_LOG(DEBUG, "enable intr in delayed handler S[%08x]\n", eicr); + PMD_DRV_LOG(DEBUG, "enable intr in delayed handler S[%08x]", eicr); ixgbe_enable_intr(dev); rte_intr_enable(&(dev->pci_dev->intr_handle)); } @@ -2371,7 +2365,7 @@ ixgbe_flow_ctrl_set(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf) if (fc_conf->autoneg != !hw->fc.disable_fc_autoneg) return -ENOTSUP; rx_buf_size = IXGBE_READ_REG(hw, IXGBE_RXPBSIZE(0)); - PMD_INIT_LOG(DEBUG, "Rx packet buffer size = 0x%x \n", rx_buf_size); + PMD_INIT_LOG(DEBUG, "Rx packet buffer size = 0x%x", rx_buf_size); /* * At least reserve one Ethernet frame for watermark @@ -2380,8 +2374,8 @@ ixgbe_flow_ctrl_set(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf) max_high_water = (rx_buf_size - ETHER_MAX_LEN) >> IXGBE_RXPBSIZE_SHIFT; if ((fc_conf->high_water > max_high_water) || (fc_conf->high_water < fc_conf->low_water)) { - PMD_INIT_LOG(ERR, "Invalid high/low water setup value in KB\n"); - PMD_INIT_LOG(ERR, "High_water must <= 0x%x\n", max_high_water); + PMD_INIT_LOG(ERR, "Invalid high/low water setup value in KB"); + PMD_INIT_LOG(ERR, "High_water must <= 0x%x", max_high_water); return (-EINVAL); } @@ -2413,7 +2407,7 @@ ixgbe_flow_ctrl_set(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf) return 0; } - PMD_INIT_LOG(ERR, "ixgbe_fc_enable = 0x%x \n", err); + PMD_INIT_LOG(ERR, "ixgbe_fc_enable = 0x%x", err); return -EIO; } @@ -2443,13 +2437,13 @@ ixgbe_dcb_pfc_enable_generic(struct ixgbe_hw *hw,uint8_t tc_num) if (hw->fc.current_mode & ixgbe_fc_tx_pause) { /* High/Low water can not be 0 */ if( (!hw->fc.high_water[tc_num])|| (!hw->fc.low_water[tc_num])) { - PMD_INIT_LOG(ERR,"Invalid water mark configuration\n"); + PMD_INIT_LOG(ERR, "Invalid water mark configuration"); ret_val = IXGBE_ERR_INVALID_LINK_SETTINGS; goto out; } if(hw->fc.low_water[tc_num] >= hw->fc.high_water[tc_num]) { - PMD_INIT_LOG(ERR,"Invalid water mark configuration\n"); + PMD_INIT_LOG(ERR, "Invalid water mark configuration"); ret_val = IXGBE_ERR_INVALID_LINK_SETTINGS; goto out; } @@ -2515,7 +2509,7 @@ ixgbe_dcb_pfc_enable_generic(struct ixgbe_hw *hw,uint8_t tc_num) fccfg_reg |= IXGBE_FCCFG_TFCE_PRIORITY; break; default: - DEBUGOUT("Flow control param set incorrectly\n"); + PMD_DRV_LOG(DEBUG, "Flow control param set incorrectly"); ret_val = IXGBE_ERR_CONFIG; goto out; break; @@ -2593,16 +2587,16 @@ ixgbe_priority_flow_ctrl_set(struct rte_eth_dev *dev, struct rte_eth_pfc_conf *p ixgbe_dcb_unpack_map_cee(dcb_config, IXGBE_DCB_RX_CONFIG, map); tc_num = map[pfc_conf->priority]; rx_buf_size = IXGBE_READ_REG(hw, IXGBE_RXPBSIZE(tc_num)); - PMD_INIT_LOG(DEBUG, "Rx packet buffer size = 0x%x \n", rx_buf_size); + PMD_INIT_LOG(DEBUG, "Rx packet buffer size = 0x%x", rx_buf_size); /* * At least reserve one Ethernet frame for watermark * high_water/low_water in kilo bytes for ixgbe */ max_high_water = (rx_buf_size - ETHER_MAX_LEN) >> IXGBE_RXPBSIZE_SHIFT; if ((pfc_conf->fc.high_water > max_high_water) || - (pfc_conf->fc.high_water <= pfc_conf->fc.low_water)) { - PMD_INIT_LOG(ERR, "Invalid high/low water setup value in KB\n"); - PMD_INIT_LOG(ERR, "High_water must <= 0x%x\n", max_high_water); + (pfc_conf->fc.high_water <= pfc_conf->fc.low_water)) { + PMD_INIT_LOG(ERR, "Invalid high/low water setup value in KB"); + PMD_INIT_LOG(ERR, "High_water must <= 0x%x", max_high_water); return (-EINVAL); } @@ -2618,7 +2612,7 @@ ixgbe_priority_flow_ctrl_set(struct rte_eth_dev *dev, struct rte_eth_pfc_conf *p if ((err == IXGBE_SUCCESS) || (err == IXGBE_ERR_FC_NOT_NEGOTIATED)) return 0; - PMD_INIT_LOG(ERR, "ixgbe_dcb_pfc_enable = 0x%x \n", err); + PMD_INIT_LOG(ERR, "ixgbe_dcb_pfc_enable = 0x%x", err); return -EIO; } @@ -2765,7 +2759,7 @@ ixgbe_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu) static void ixgbevf_intr_disable(struct ixgbe_hw *hw) { - PMD_INIT_LOG(DEBUG, "ixgbevf_intr_disable"); + PMD_INIT_FUNC_TRACE(); /* Clear interrupt mask to stop from interrupts being generated */ IXGBE_WRITE_REG(hw, IXGBE_VTEIMC, IXGBE_VF_IRQ_CLEAR_MASK); @@ -2778,8 +2772,8 @@ ixgbevf_dev_configure(struct rte_eth_dev *dev) { struct rte_eth_conf* conf = &dev->data->dev_conf; - PMD_INIT_LOG(DEBUG, "\nConfigured Virtual Function port id: %d\n", - dev->data->port_id); + PMD_INIT_LOG(DEBUG, "Configured Virtual Function port id: %d", + dev->data->port_id); /* * VF has no ability to enable/disable HW CRC @@ -2787,12 +2781,12 @@ ixgbevf_dev_configure(struct rte_eth_dev *dev) */ #ifndef RTE_LIBRTE_IXGBE_PF_DISABLE_STRIP_CRC if (!conf->rxmode.hw_strip_crc) { - PMD_INIT_LOG(INFO, "VF can't disable HW CRC Strip\n"); + PMD_INIT_LOG(INFO, "VF can't disable HW CRC Strip"); conf->rxmode.hw_strip_crc = 1; } #else if (conf->rxmode.hw_strip_crc) { - PMD_INIT_LOG(INFO, "VF can't enable HW CRC Strip\n"); + PMD_INIT_LOG(INFO, "VF can't enable HW CRC Strip"); conf->rxmode.hw_strip_crc = 0; } #endif @@ -2807,7 +2801,7 @@ ixgbevf_dev_start(struct rte_eth_dev *dev) IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private); int err, mask = 0; - PMD_INIT_LOG(DEBUG, "ixgbevf_dev_start"); + PMD_INIT_FUNC_TRACE(); hw->mac.ops.reset_hw(hw); @@ -2819,7 +2813,7 @@ ixgbevf_dev_start(struct rte_eth_dev *dev) /* This can fail when allocating mbufs for descriptor rings */ err = ixgbevf_dev_rx_init(dev); if (err) { - PMD_INIT_LOG(ERR, "Unable to initialize RX hardware (%d)\n", err); + PMD_INIT_LOG(ERR, "Unable to initialize RX hardware (%d)", err); ixgbe_dev_clear_queues(dev); return err; } @@ -2842,7 +2836,7 @@ ixgbevf_dev_stop(struct rte_eth_dev *dev) { struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private); - PMD_INIT_LOG(DEBUG, "ixgbevf_dev_stop"); + PMD_INIT_FUNC_TRACE(); hw->adapter_stopped = TRUE; ixgbe_stop_adapter(hw); @@ -2861,7 +2855,7 @@ ixgbevf_dev_close(struct rte_eth_dev *dev) { struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private); - PMD_INIT_LOG(DEBUG, "ixgbevf_dev_close"); + PMD_INIT_FUNC_TRACE(); ixgbe_reset_hw(hw); @@ -2970,7 +2964,7 @@ ixgbe_vmdq_mode_check(struct ixgbe_hw *hw) /* we only need to do this if VMDq is enabled */ reg_val = IXGBE_READ_REG(hw, IXGBE_VT_CTL); if (!(reg_val & IXGBE_VT_CTL_VT_ENABLE)) { - PMD_INIT_LOG(ERR, "VMDq must be enabled for this setting\n"); + PMD_INIT_LOG(ERR, "VMDq must be enabled for this setting"); return (-1); } @@ -3099,7 +3093,7 @@ ixgbe_set_pool_rx_mode(struct rte_eth_dev *dev, uint16_t pool, if (hw->mac.type == ixgbe_mac_82598EB) { PMD_INIT_LOG(ERR, "setting VF receive mode set should be done" - " on 82599 hardware and newer\n"); + " on 82599 hardware and newer"); return (-ENOTSUP); } if (ixgbe_vmdq_mode_check(hw) < 0)