// SPDX-License-Identifier: GPL-2.0+ /* * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. * All rights reserved. * * Purpose: MAC routines * * Author: Tevin Chen * * Date: May 21, 1996 * * Functions: * vt6655_mac_is_reg_bits_off - Test if All test Bits Off * vt6655_mac_set_short_retry_limit - Set 802.11 Short Retry limit * MACvSetLongRetryLimit - Set 802.11 Long Retry limit * vt6655_mac_set_loopback_mode - Set MAC Loopback Mode * vt6655_mac_save_context - Save Context of MAC Registers * vt6655_mac_restore_context - Restore Context of MAC Registers * MACbSoftwareReset - Software Reset MAC * vt6655_mac_safe_rx_off - Turn Off MAC Rx * vt6655_mac_safe_tx_off - Turn Off MAC Tx * vt6655_mac_safe_stop - Stop MAC function * MACbShutdown - Shut down MAC * MACvInitialize - Initialize MAC * MACvSetCurrRxDescAddr - Set Rx Descriptors Address * MACvSetCurrTx0DescAddr - Set Tx0 Descriptors Address * MACvSetCurrTx1DescAddr - Set Tx1 Descriptors Address * MACvTimer0MicroSDelay - Micro Second Delay Loop by MAC * * Revision History: * 08-22-2003 Kyle Hsu : Porting MAC functions from sim53 * 09-03-2003 Bryan YC Fan : Add MACvClearBusSusInd()& * MACvEnableBusSusEn() * 09-18-2003 Jerry Chen : Add MACvSetKeyEntry & MACvDisableKeyEntry * */ #include "mac.h" void vt6655_mac_reg_bits_on(void __iomem *iobase, const u8 reg_offset, const u8 bit_mask) { unsigned char reg_value; reg_value = ioread8(iobase + reg_offset); iowrite8(reg_value | bit_mask, iobase + reg_offset); } void vt6655_mac_word_reg_bits_on(void __iomem *iobase, const u8 reg_offset, const u16 bit_mask) { unsigned short reg_value; reg_value = ioread16(iobase + reg_offset); iowrite16(reg_value | (bit_mask), iobase + reg_offset); } void vt6655_mac_reg_bits_off(void __iomem *iobase, const u8 reg_offset, const u8 bit_mask) { unsigned char reg_value; reg_value = ioread8(iobase + reg_offset); iowrite8(reg_value & ~(bit_mask), iobase + reg_offset); } void vt6655_mac_word_reg_bits_off(void __iomem *iobase, const u8 reg_offset, const u16 bit_mask) { unsigned short reg_value; reg_value = ioread16(iobase + reg_offset); iowrite16(reg_value & ~(bit_mask), iobase + reg_offset); } static void vt6655_mac_clear_stck_ds(void __iomem *iobase) { u8 reg_value; reg_value = ioread8(iobase + MAC_REG_STICKHW); reg_value = reg_value & 0xFC; iowrite8(reg_value, iobase + MAC_REG_STICKHW); } /* * Description: * Test if all test bits off * * Parameters: * In: * io_base - Base Address for MAC * reg_offset - Offset of MAC Register * mask - Test bits * Out: * none * * Return Value: true if all test bits Off; otherwise false * */ static bool vt6655_mac_is_reg_bits_off(struct vnt_private *priv, unsigned char reg_offset, unsigned char mask) { void __iomem *io_base = priv->port_offset; return !(ioread8(io_base + reg_offset) & mask); } /* * Description: * Set 802.11 Short Retry Limit * * Parameters: * In: * io_base - Base Address for MAC * retry_limit - Retry Limit * Out: * none * * Return Value: none * */ void vt6655_mac_set_short_retry_limit(struct vnt_private *priv, unsigned char retry_limit) { void __iomem *io_base = priv->port_offset; /* set SRT */ iowrite8(retry_limit, io_base + MAC_REG_SRT); } /* * Description: * Set 802.11 Long Retry Limit * * Parameters: * In: * io_base - Base Address for MAC * byRetryLimit- Retry Limit * Out: * none * * Return Value: none * */ void MACvSetLongRetryLimit(struct vnt_private *priv, unsigned char byRetryLimit) { void __iomem *io_base = priv->port_offset; /* set LRT */ iowrite8(byRetryLimit, io_base + MAC_REG_LRT); } /* * Description: * Set MAC Loopback mode * * Parameters: * In: * io_base - Base Address for MAC * loopback_mode - Loopback Mode * Out: * none * * Return Value: none * */ static void vt6655_mac_set_loopback_mode(struct vnt_private *priv, u8 loopback_mode) { void __iomem *io_base = priv->port_offset; loopback_mode <<= 6; /* set TCR */ iowrite8((ioread8(io_base + MAC_REG_TEST) & 0x3f) | loopback_mode, io_base + MAC_REG_TEST); } /* * Description: * Save MAC registers to context buffer * * Parameters: * In: * io_base - Base Address for MAC * Out: * cxt_buf - Context buffer * * Return Value: none * */ static void vt6655_mac_save_context(struct vnt_private *priv, u8 *cxt_buf) { void __iomem *io_base = priv->port_offset; /* read page0 register */ memcpy_fromio(cxt_buf, io_base, MAC_MAX_CONTEXT_SIZE_PAGE0); VT6655_MAC_SELECT_PAGE1(io_base); /* read page1 register */ memcpy_fromio(cxt_buf + MAC_MAX_CONTEXT_SIZE_PAGE0, io_base, MAC_MAX_CONTEXT_SIZE_PAGE1); VT6655_MAC_SELECT_PAGE0(io_base); } /* * Description: * Restore MAC registers from context buffer * * Parameters: * In: * io_base - Base Address for MAC * cxt_buf - Context buffer * Out: * none * * Return Value: none * */ static void vt6655_mac_restore_context(struct vnt_private *priv, u8 *cxt_buf) { void __iomem *io_base = priv->port_offset; VT6655_MAC_SELECT_PAGE1(io_base); /* restore page1 */ memcpy_toio(io_base, cxt_buf + MAC_MAX_CONTEXT_SIZE_PAGE0, MAC_MAX_CONTEXT_SIZE_PAGE1); VT6655_MAC_SELECT_PAGE0(io_base); /* restore RCR,TCR,IMR... */ memcpy_toio(io_base + MAC_REG_RCR, cxt_buf + MAC_REG_RCR, MAC_REG_ISR - MAC_REG_RCR); /* restore MAC Config. */ memcpy_toio(io_base + MAC_REG_LRT, cxt_buf + MAC_REG_LRT, MAC_REG_PAGE1SEL - MAC_REG_LRT); iowrite8(*(cxt_buf + MAC_REG_CFG), io_base + MAC_REG_CFG); /* restore PS Config. */ memcpy_toio(io_base + MAC_REG_PSCFG, cxt_buf + MAC_REG_PSCFG, MAC_REG_BBREGCTL - MAC_REG_PSCFG); /* restore CURR_RX_DESC_ADDR, CURR_TX_DESC_ADDR */ iowrite32(*(u32 *)(cxt_buf + MAC_REG_TXDMAPTR0), io_base + MAC_REG_TXDMAPTR0); iowrite32(*(u32 *)(cxt_buf + MAC_REG_AC0DMAPTR), io_base + MAC_REG_AC0DMAPTR); iowrite32(*(u32 *)(cxt_buf + MAC_REG_BCNDMAPTR), io_base + MAC_REG_BCNDMAPTR); iowrite32(*(u32 *)(cxt_buf + MAC_REG_RXDMAPTR0), io_base + MAC_REG_RXDMAPTR0); iowrite32(*(u32 *)(cxt_buf + MAC_REG_RXDMAPTR1), io_base + MAC_REG_RXDMAPTR1); } /* * Description: * Software Reset MAC * * Parameters: * In: * io_base - Base Address for MAC * Out: * none * * Return Value: true if Reset Success; otherwise false * */ bool MACbSoftwareReset(struct vnt_private *priv) { void __iomem *io_base = priv->port_offset; unsigned short ww; /* turn on HOSTCR_SOFTRST, just write 0x01 to reset */ iowrite8(0x01, io_base + MAC_REG_HOSTCR); for (ww = 0; ww < W_MAX_TIMEOUT; ww++) { if (!(ioread8(io_base + MAC_REG_HOSTCR) & HOSTCR_SOFTRST)) break; } if (ww == W_MAX_TIMEOUT) return false; return true; } /* * Description: * save some important register's value, then do reset, then restore * register's value * * Parameters: * In: * io_base - Base Address for MAC * Out: * none * * Return Value: true if success; otherwise false * */ static void vt6655_mac_save_soft_reset(struct vnt_private *priv) { u8 tmp_reg_data[MAC_MAX_CONTEXT_SIZE_PAGE0 + MAC_MAX_CONTEXT_SIZE_PAGE1]; /* PATCH.... * save some important register's value, then do * reset, then restore register's value */ /* save MAC context */ vt6655_mac_save_context(priv, tmp_reg_data); /* do reset */ MACbSoftwareReset(priv); /* restore MAC context, except CR0 */ vt6655_mac_restore_context(priv, tmp_reg_data); } /* * Description: * Turn Off MAC Rx * * Parameters: * In: * io_base - Base Address for MAC * Out: * none * * Return Value: true if success; otherwise false * */ static bool vt6655_mac_safe_rx_off(struct vnt_private *priv) { void __iomem *io_base = priv->port_offset; unsigned short ww; /* turn off wow temp for turn off Rx safely */ /* Clear RX DMA0,1 */ iowrite32(DMACTL_CLRRUN, io_base + MAC_REG_RXDMACTL0); iowrite32(DMACTL_CLRRUN, io_base + MAC_REG_RXDMACTL1); for (ww = 0; ww < W_MAX_TIMEOUT; ww++) { if (!(ioread32(io_base + MAC_REG_RXDMACTL0) & DMACTL_RUN)) break; } if (ww == W_MAX_TIMEOUT) { pr_debug(" DBG_PORT80(0x10)\n"); return false; } for (ww = 0; ww < W_MAX_TIMEOUT; ww++) { if (!(ioread32(io_base + MAC_REG_RXDMACTL1) & DMACTL_RUN)) break; } if (ww == W_MAX_TIMEOUT) { pr_debug(" DBG_PORT80(0x11)\n"); return false; } /* try to safe shutdown RX */ vt6655_mac_reg_bits_off(io_base, MAC_REG_HOSTCR, HOSTCR_RXON); /* W_MAX_TIMEOUT is the timeout period */ for (ww = 0; ww < W_MAX_TIMEOUT; ww++) { if (!(ioread8(io_base + MAC_REG_HOSTCR) & HOSTCR_RXONST)) break; } if (ww == W_MAX_TIMEOUT) { pr_debug(" DBG_PORT80(0x12)\n"); return false; } return true; } /* * Description: * Turn Off MAC Tx * * Parameters: * In: * io_base - Base Address for MAC * Out: * none * * Return Value: true if success; otherwise false * */ static bool vt6655_mac_safe_tx_off(struct vnt_private *priv) { void __iomem *io_base = priv->port_offset; unsigned short ww; /* Clear TX DMA */ /* Tx0 */ iowrite32(DMACTL_CLRRUN, io_base + MAC_REG_TXDMACTL0); /* AC0 */ iowrite32(DMACTL_CLRRUN, io_base + MAC_REG_AC0DMACTL); for (ww = 0; ww < W_MAX_TIMEOUT; ww++) { if (!(ioread32(io_base + MAC_REG_TXDMACTL0) & DMACTL_RUN)) break; } if (ww == W_MAX_TIMEOUT) { pr_debug(" DBG_PORT80(0x20)\n"); return false; } for (ww = 0; ww < W_MAX_TIMEOUT; ww++) { if (!(ioread32(io_base + MAC_REG_AC0DMACTL) & DMACTL_RUN)) break; } if (ww == W_MAX_TIMEOUT) { pr_debug(" DBG_PORT80(0x21)\n"); return false; } /* try to safe shutdown TX */ vt6655_mac_reg_bits_off(io_base, MAC_REG_HOSTCR, HOSTCR_TXON); /* W_MAX_TIMEOUT is the timeout period */ for (ww = 0; ww < W_MAX_TIMEOUT; ww++) { if (!(ioread8(io_base + MAC_REG_HOSTCR) & HOSTCR_TXONST)) break; } if (ww == W_MAX_TIMEOUT) { pr_debug(" DBG_PORT80(0x24)\n"); return false; } return true; } /* * Description: * Stop MAC function * * Parameters: * In: * io_base - Base Address for MAC * Out: * none * * Return Value: true if success; otherwise false * */ static bool vt6655_mac_safe_stop(struct vnt_private *priv) { void __iomem *io_base = priv->port_offset; vt6655_mac_reg_bits_off(io_base, MAC_REG_TCR, TCR_AUTOBCNTX); if (!vt6655_mac_safe_rx_off(priv)) { pr_debug(" vt6655_mac_safe_rx_off == false)\n"); vt6655_mac_save_soft_reset(priv); return false; } if (!vt6655_mac_safe_tx_off(priv)) { pr_debug(" vt6655_mac_safe_tx_off == false)\n"); vt6655_mac_save_soft_reset(priv); return false; } vt6655_mac_reg_bits_off(io_base, MAC_REG_HOSTCR, HOSTCR_MACEN); return true; } /* * Description: * Shut Down MAC * * Parameters: * In: * io_base - Base Address for MAC * Out: * none * * Return Value: true if success; otherwise false * */ bool MACbShutdown(struct vnt_private *priv) { void __iomem *io_base = priv->port_offset; /* disable MAC IMR */ iowrite32(0, io_base + MAC_REG_IMR); vt6655_mac_set_loopback_mode(priv, MAC_LB_INTERNAL); /* stop the adapter */ if (!vt6655_mac_safe_stop(priv)) { vt6655_mac_set_loopback_mode(priv, MAC_LB_NONE); return false; } vt6655_mac_set_loopback_mode(priv, MAC_LB_NONE); return true; } /* * Description: * Initialize MAC * * Parameters: * In: * io_base - Base Address for MAC * Out: * none * * Return Value: none * */ void MACvInitialize(struct vnt_private *priv) { void __iomem *io_base = priv->port_offset; /* clear sticky bits */ vt6655_mac_clear_stck_ds(io_base); /* disable force PME-enable */ iowrite8(PME_OVR, io_base + MAC_REG_PMC1); /* only 3253 A */ /* do reset */ MACbSoftwareReset(priv); /* reset TSF counter */ iowrite8(TFTCTL_TSFCNTRST, io_base + MAC_REG_TFTCTL); /* enable TSF counter */ iowrite8(TFTCTL_TSFCNTREN, io_base + MAC_REG_TFTCTL); } /* * Description: * Set the chip with current rx descriptor address * * Parameters: * In: * io_base - Base Address for MAC * curr_desc_addr - Descriptor Address * Out: * none * * Return Value: none * */ void vt6655_mac_set_curr_rx_0_desc_addr(struct vnt_private *priv, u32 curr_desc_addr) { void __iomem *io_base = priv->port_offset; unsigned short ww; unsigned char org_dma_ctl; org_dma_ctl = ioread8(io_base + MAC_REG_RXDMACTL0); if (org_dma_ctl & DMACTL_RUN) iowrite8(DMACTL_RUN, io_base + MAC_REG_RXDMACTL0 + 2); for (ww = 0; ww < W_MAX_TIMEOUT; ww++) { if (!(ioread8(io_base + MAC_REG_RXDMACTL0) & DMACTL_RUN)) break; } iowrite32(curr_desc_addr, io_base + MAC_REG_RXDMAPTR0); if (org_dma_ctl & DMACTL_RUN) iowrite8(DMACTL_RUN, io_base + MAC_REG_RXDMACTL0); } /* * Description: * Set the chip with current rx descriptor address * * Parameters: * In: * io_base - Base Address for MAC * curr_desc_addr - Descriptor Address * Out: * none * * Return Value: none * */ void vt6655_mac_set_curr_rx_1_desc_addr(struct vnt_private *priv, u32 curr_desc_addr) { void __iomem *io_base = priv->port_offset; unsigned short ww; unsigned char org_dma_ctl; org_dma_ctl = ioread8(io_base + MAC_REG_RXDMACTL1); if (org_dma_ctl & DMACTL_RUN) iowrite8(DMACTL_RUN, io_base + MAC_REG_RXDMACTL1 + 2); for (ww = 0; ww < W_MAX_TIMEOUT; ww++) { if (!(ioread8(io_base + MAC_REG_RXDMACTL1) & DMACTL_RUN)) break; } iowrite32(curr_desc_addr, io_base + MAC_REG_RXDMAPTR1); if (org_dma_ctl & DMACTL_RUN) iowrite8(DMACTL_RUN, io_base + MAC_REG_RXDMACTL1); } /* * Description: * Set the chip with current tx0 descriptor address * * Parameters: * In: * io_base - Base Address for MAC * curr_desc_addr - Descriptor Address * Out: * none * * Return Value: none * */ static void vt6655_mac_set_curr_tx_0_desc_addr_ex(struct vnt_private *priv, u32 curr_desc_addr) { void __iomem *io_base = priv->port_offset; unsigned short ww; unsigned char org_dma_ctl; org_dma_ctl = ioread8(io_base + MAC_REG_TXDMACTL0); if (org_dma_ctl & DMACTL_RUN) iowrite8(DMACTL_RUN, io_base + MAC_REG_TXDMACTL0 + 2); for (ww = 0; ww < W_MAX_TIMEOUT; ww++) { if (!(ioread8(io_base + MAC_REG_TXDMACTL0) & DMACTL_RUN)) break; } iowrite32(curr_desc_addr, io_base + MAC_REG_TXDMAPTR0); if (org_dma_ctl & DMACTL_RUN) iowrite8(DMACTL_RUN, io_base + MAC_REG_TXDMACTL0); } /* * Description: * Set the chip with current AC0 descriptor address * * Parameters: * In: * io_base - Base Address for MAC * curr_desc_addr - Descriptor Address * Out: * none * * Return Value: none * */ /* TxDMA1 = AC0DMA */ static void vt6655_mac_set_curr_ac_0_desc_addr_ex(struct vnt_private *priv, u32 curr_desc_addr) { void __iomem *io_base = priv->port_offset; unsigned short ww; unsigned char org_dma_ctl; org_dma_ctl = ioread8(io_base + MAC_REG_AC0DMACTL); if (org_dma_ctl & DMACTL_RUN) iowrite8(DMACTL_RUN, io_base + MAC_REG_AC0DMACTL + 2); for (ww = 0; ww < W_MAX_TIMEOUT; ww++) { if (!(ioread8(io_base + MAC_REG_AC0DMACTL) & DMACTL_RUN)) break; } if (ww == W_MAX_TIMEOUT) pr_debug(" DBG_PORT80(0x26)\n"); iowrite32(curr_desc_addr, io_base + MAC_REG_AC0DMAPTR); if (org_dma_ctl & DMACTL_RUN) iowrite8(DMACTL_RUN, io_base + MAC_REG_AC0DMACTL); } void vt6655_mac_set_curr_tx_desc_addr(int tx_type, struct vnt_private *priv, u32 curr_desc_addr) { if (tx_type == TYPE_AC0DMA) vt6655_mac_set_curr_ac_0_desc_addr_ex(priv, curr_desc_addr); else if (tx_type == TYPE_TXDMA0) vt6655_mac_set_curr_tx_0_desc_addr_ex(priv, curr_desc_addr); } /* * Description: * Micro Second Delay via MAC * * Parameters: * In: * io_base - Base Address for MAC * uDelay - Delay time (timer resolution is 4 us) * Out: * none * * Return Value: none * */ void MACvTimer0MicroSDelay(struct vnt_private *priv, unsigned int uDelay) { void __iomem *io_base = priv->port_offset; unsigned char byValue; unsigned int uu, ii; iowrite8(0, io_base + MAC_REG_TMCTL0); iowrite32(uDelay, io_base + MAC_REG_TMDATA0); iowrite8((TMCTL_TMD | TMCTL_TE), io_base + MAC_REG_TMCTL0); for (ii = 0; ii < 66; ii++) { /* assume max PCI clock is 66Mhz */ for (uu = 0; uu < uDelay; uu++) { byValue = ioread8(io_base + MAC_REG_TMCTL0); if ((byValue == 0) || (byValue & TMCTL_TSUSP)) { iowrite8(0, io_base + MAC_REG_TMCTL0); return; } } } iowrite8(0, io_base + MAC_REG_TMCTL0); } /* * Description: * Micro Second One shot timer via MAC * * Parameters: * In: * io_base - Base Address for MAC * uDelay - Delay time * Out: * none * * Return Value: none * */ void MACvOneShotTimer1MicroSec(struct vnt_private *priv, unsigned int uDelayTime) { void __iomem *io_base = priv->port_offset; iowrite8(0, io_base + MAC_REG_TMCTL1); iowrite32(uDelayTime, io_base + MAC_REG_TMDATA1); iowrite8((TMCTL_TMD | TMCTL_TE), io_base + MAC_REG_TMCTL1); } void MACvSetMISCFifo(struct vnt_private *priv, unsigned short offset, u32 data) { void __iomem *io_base = priv->port_offset; if (offset > 273) return; iowrite16(offset, io_base + MAC_REG_MISCFFNDEX); iowrite32(data, io_base + MAC_REG_MISCFFDATA); iowrite16(MISCFFCTL_WRITE, io_base + MAC_REG_MISCFFCTL); } bool MACbPSWakeup(struct vnt_private *priv) { void __iomem *io_base = priv->port_offset; unsigned int ww; /* Read PSCTL */ if (vt6655_mac_is_reg_bits_off(priv, MAC_REG_PSCTL, PSCTL_PS)) return true; /* Disable PS */ vt6655_mac_reg_bits_off(io_base, MAC_REG_PSCTL, PSCTL_PSEN); /* Check if SyncFlushOK */ for (ww = 0; ww < W_MAX_TIMEOUT; ww++) { if (ioread8(io_base + MAC_REG_PSCTL) & PSCTL_WAKEDONE) break; } if (ww == W_MAX_TIMEOUT) { pr_debug(" DBG_PORT80(0x33)\n"); return false; } return true; } /* * Description: * Set the Key by MISCFIFO * * Parameters: * In: * io_base - Base Address for MAC * * Out: * none * * Return Value: none * */ void MACvSetKeyEntry(struct vnt_private *priv, unsigned short wKeyCtl, unsigned int uEntryIdx, unsigned int uKeyIdx, unsigned char *pbyAddr, u32 *pdwKey, unsigned char local_id) { void __iomem *io_base = priv->port_offset; unsigned short offset; u32 data; int ii; if (local_id <= 1) return; offset = MISCFIFO_KEYETRY0; offset += (uEntryIdx * MISCFIFO_KEYENTRYSIZE); data = 0; data |= wKeyCtl; data <<= 16; data |= MAKEWORD(*(pbyAddr + 4), *(pbyAddr + 5)); pr_debug("1. offset: %d, Data: %X, KeyCtl:%X\n", offset, data, wKeyCtl); iowrite16(offset, io_base + MAC_REG_MISCFFNDEX); iowrite32(data, io_base + MAC_REG_MISCFFDATA); iowrite16(MISCFFCTL_WRITE, io_base + MAC_REG_MISCFFCTL); offset++; data = 0; data |= *(pbyAddr + 3); data <<= 8; data |= *(pbyAddr + 2); data <<= 8; data |= *(pbyAddr + 1); data <<= 8; data |= *pbyAddr; pr_debug("2. offset: %d, Data: %X\n", offset, data); iowrite16(offset, io_base + MAC_REG_MISCFFNDEX); iowrite32(data, io_base + MAC_REG_MISCFFDATA); iowrite16(MISCFFCTL_WRITE, io_base + MAC_REG_MISCFFCTL); offset++; offset += (uKeyIdx * 4); for (ii = 0; ii < 4; ii++) { /* always push 128 bits */ pr_debug("3.(%d) offset: %d, Data: %X\n", ii, offset + ii, *pdwKey); iowrite16(offset + ii, io_base + MAC_REG_MISCFFNDEX); iowrite32(*pdwKey++, io_base + MAC_REG_MISCFFDATA); iowrite16(MISCFFCTL_WRITE, io_base + MAC_REG_MISCFFCTL); } } /* * Description: * Disable the Key Entry by MISCFIFO * * Parameters: * In: * io_base - Base Address for MAC * * Out: * none * * Return Value: none * */ void MACvDisableKeyEntry(struct vnt_private *priv, unsigned int uEntryIdx) { void __iomem *io_base = priv->port_offset; unsigned short offset; offset = MISCFIFO_KEYETRY0; offset += (uEntryIdx * MISCFIFO_KEYENTRYSIZE); iowrite16(offset, io_base + MAC_REG_MISCFFNDEX); iowrite32(0, io_base + MAC_REG_MISCFFDATA); iowrite16(MISCFFCTL_WRITE, io_base + MAC_REG_MISCFFCTL); }