mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-09-18 22:14:16 +00:00

Currently it takes almost 6 seconds to upload the firmware for RTL8192CU
(and 11 seconds for RTL8192DU). That's because the firmware is uploaded
one byte at a time.
Also, after plugging the device, the firmware gets uploaded three times
before a connection to the AP is established.
Maybe this is fine for most users, but when testing changes to the
driver it's really annoying to wait so long.
Speed up the firmware upload by writing chunks of 64 bytes at a time.
This way it takes about 110 ms for RTL8192CU (and about 210 ms for
RTL8192DU).
PCI devices could upload it in chunks of 4 bytes, but I don't have any
to test and commit 89d32c9071
("rtlwifi: Download firmware as bytes
rather than as dwords") decided otherwise anyway.
Allocate memory for the firmware image with kmalloc instead of vzalloc
because this memory is passed directly to usb_control_msg(), which
can't take memory allocated by vmalloc.
Signed-off-by: Bitterblue Smith <rtl8821cerfe2@gmail.com>
Acked-by: Ping-Ke Shih <pkshih@realtek.com>
Signed-off-by: Kalle Valo <kvalo@kernel.org>
Link: https://msgid.link/d9bd4949-6e92-4f35-8b60-3b45f9ad74ab@gmail.com
98 lines
2.5 KiB
C
98 lines
2.5 KiB
C
/* SPDX-License-Identifier: GPL-2.0 */
|
|
/* Copyright(c) 2009-2012 Realtek Corporation.*/
|
|
|
|
#ifndef __RTL_EFUSE_H_
|
|
#define __RTL_EFUSE_H_
|
|
|
|
#define EFUSE_IC_ID_OFFSET 506
|
|
|
|
#define EFUSE_MAX_WORD_UNIT 4
|
|
|
|
#define EFUSE_INIT_MAP 0
|
|
#define EFUSE_MODIFY_MAP 1
|
|
|
|
#define PG_STATE_HEADER 0x01
|
|
#define PG_STATE_WORD_0 0x02
|
|
#define PG_STATE_WORD_1 0x04
|
|
#define PG_STATE_WORD_2 0x08
|
|
#define PG_STATE_WORD_3 0x10
|
|
#define PG_STATE_DATA 0x20
|
|
|
|
#define EFUSE_REPEAT_THRESHOLD_ 3
|
|
#define EFUSE_ERROE_HANDLE 1
|
|
|
|
struct efuse_map {
|
|
u8 offset;
|
|
u8 word_start;
|
|
u8 byte_start;
|
|
u8 byte_cnts;
|
|
};
|
|
|
|
struct pgpkt_struct {
|
|
u8 offset;
|
|
u8 word_en;
|
|
u8 data[8];
|
|
};
|
|
|
|
enum efuse_data_item {
|
|
EFUSE_CHIP_ID = 0,
|
|
EFUSE_LDO_SETTING,
|
|
EFUSE_CLK_SETTING,
|
|
EFUSE_SDIO_SETTING,
|
|
EFUSE_CCCR,
|
|
EFUSE_SDIO_MODE,
|
|
EFUSE_OCR,
|
|
EFUSE_F0CIS,
|
|
EFUSE_F1CIS,
|
|
EFUSE_MAC_ADDR,
|
|
EFUSE_EEPROM_VER,
|
|
EFUSE_CHAN_PLAN,
|
|
EFUSE_TXPW_TAB
|
|
};
|
|
|
|
enum {
|
|
VOLTAGE_V25 = 0x03,
|
|
LDOE25_SHIFT = 28,
|
|
};
|
|
|
|
struct efuse_priv {
|
|
u8 id[2];
|
|
u8 ldo_setting[2];
|
|
u8 clk_setting[2];
|
|
u8 cccr;
|
|
u8 sdio_mode;
|
|
u8 ocr[3];
|
|
u8 cis0[17];
|
|
u8 cis1[48];
|
|
u8 mac_addr[6];
|
|
u8 eeprom_verno;
|
|
u8 channel_plan;
|
|
u8 tx_power_b[14];
|
|
u8 tx_power_g[14];
|
|
};
|
|
|
|
void read_efuse_byte(struct ieee80211_hw *hw, u16 _offset, u8 *pbuf);
|
|
void efuse_initialize(struct ieee80211_hw *hw);
|
|
u8 efuse_read_1byte(struct ieee80211_hw *hw, u16 address);
|
|
int efuse_one_byte_read(struct ieee80211_hw *hw, u16 addr, u8 *data);
|
|
void efuse_write_1byte(struct ieee80211_hw *hw, u16 address, u8 value);
|
|
void read_efuse(struct ieee80211_hw *hw, u16 _offset,
|
|
u16 _size_byte, u8 *pbuf);
|
|
void efuse_shadow_read(struct ieee80211_hw *hw, u8 type,
|
|
u16 offset, u32 *value);
|
|
void efuse_shadow_write(struct ieee80211_hw *hw, u8 type,
|
|
u16 offset, u32 value);
|
|
bool efuse_shadow_update(struct ieee80211_hw *hw);
|
|
bool efuse_shadow_update_chk(struct ieee80211_hw *hw);
|
|
void rtl_efuse_shadow_map_update(struct ieee80211_hw *hw);
|
|
void efuse_force_write_vendor_id(struct ieee80211_hw *hw);
|
|
void efuse_re_pg_section(struct ieee80211_hw *hw, u8 section_idx);
|
|
void efuse_power_switch(struct ieee80211_hw *hw, u8 write, u8 pwrstate);
|
|
int rtl_get_hwinfo(struct ieee80211_hw *hw, struct rtl_priv *rtlpriv,
|
|
int max_size, u8 *hwinfo, int *params);
|
|
void rtl_fill_dummy(u8 *pfwbuf, u32 *pfwlen);
|
|
void rtl_fw_page_write(struct ieee80211_hw *hw, u32 page, u8 *buffer,
|
|
u32 size);
|
|
void rtl_fw_block_write(struct ieee80211_hw *hw, u8 *buffer, u32 size);
|
|
void rtl_efuse_ops_init(struct ieee80211_hw *hw);
|
|
#endif
|