static bool _rtl92s_firmware_enable_cpu( struct ieee80211_hw *hw ) { struct rtl_priv *rtlpriv = rtl_priv( hw ); u32 ichecktime = 200; u16 tmpu2b; u8 tmpu1b, cpustatus = 0; _rtl92s_fw_set_rqpn( hw ); /* Enable CPU. */ tmpu1b = rtl_read_byte( rtlpriv, SYS_CLKR ); /* AFE source */ rtl_write_byte( rtlpriv, SYS_CLKR, ( tmpu1b | SYS_CPU_CLKSEL ) ); tmpu2b = rtl_read_word( rtlpriv, REG_SYS_FUNC_EN ); rtl_write_word( rtlpriv, REG_SYS_FUNC_EN, ( tmpu2b | FEN_CPUEN ) ); /* Polling IMEM Ready after CPU has refilled. */ do { cpustatus = rtl_read_byte( rtlpriv, TCR ); if ( cpustatus & IMEM_RDY ) { RT_TRACE( COMP_INIT, DBG_LOUD, ( "IMEM Ready after CPU has refilled.\n" ) ); break; } udelay( 100 ); } while ( ichecktime-- ); if ( !( cpustatus & IMEM_RDY ) ) return false; return true; }
static bool _rtl92s_firmware_downloadcode(struct ieee80211_hw *hw, u8 *code_virtual_address, u32 buffer_len) { struct rtl_priv *rtlpriv = rtl_priv(hw); struct sk_buff *skb; struct rtl_tcb_desc *tcb_desc; unsigned char *seg_ptr; u16 frag_threshold = MAX_FIRMWARE_CODE_SIZE; u16 frag_length, frag_offset = 0; u16 extra_descoffset = 0; u8 blast_inipkt = 0; _rtl92s_fw_set_rqpn(hw); if (buffer_len >= MAX_FIRMWARE_CODE_SIZE) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Size over FIRMWARE_CODE_SIZE!\n"); return false; } extra_descoffset = 0; do { if ((buffer_len - frag_offset) > frag_threshold) { frag_length = frag_threshold + extra_descoffset; } else { frag_length = (u16)(buffer_len - frag_offset + extra_descoffset); blast_inipkt = 1; } /* Allocate skb buffer to contain firmware */ /* info and tx descriptor info. */ skb = dev_alloc_skb(frag_length); skb_reserve(skb, extra_descoffset); seg_ptr = (u8 *)skb_put(skb, (u32)(frag_length - extra_descoffset)); memcpy(seg_ptr, code_virtual_address + frag_offset, (u32)(frag_length - extra_descoffset)); tcb_desc = (struct rtl_tcb_desc *)(skb->cb); tcb_desc->queue_index = TXCMD_QUEUE; tcb_desc->cmd_or_init = DESC_PACKET_TYPE_INIT; tcb_desc->last_inipkt = blast_inipkt; _rtl92s_cmd_send_packet(hw, skb, blast_inipkt); frag_offset += (frag_length - extra_descoffset); } while (frag_offset < buffer_len); rtl_write_byte(rtlpriv, TP_POLL, TPPOLL_CQ); return true; }