12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378 |
- drivers/net/wireless/realtek/rtw88/Kconfig | 47 +++++++++
- drivers/net/wireless/realtek/rtw88/Makefile | 15 +++
- drivers/net/wireless/realtek/rtw88/coex.c | 3
- drivers/net/wireless/realtek/rtw88/debug.c | 15 +++
- drivers/net/wireless/realtek/rtw88/fw.c | 31 +++---
- drivers/net/wireless/realtek/rtw88/fw.h | 11 ++
- drivers/net/wireless/realtek/rtw88/hci.h | 9 -
- drivers/net/wireless/realtek/rtw88/mac.c | 21 ++++
- drivers/net/wireless/realtek/rtw88/mac80211.c | 2
- drivers/net/wireless/realtek/rtw88/main.c | 12 +-
- drivers/net/wireless/realtek/rtw88/main.h | 12 +-
- drivers/net/wireless/realtek/rtw88/phy.c | 6 -
- drivers/net/wireless/realtek/rtw88/ps.c | 2
- drivers/net/wireless/realtek/rtw88/reg.h | 1
- drivers/net/wireless/realtek/rtw88/rtw8723d.c | 28 +++++
- drivers/net/wireless/realtek/rtw88/rtw8723d.h | 13 ++
- drivers/net/wireless/realtek/rtw88/rtw8723du.c | 36 +++++++
- drivers/net/wireless/realtek/rtw88/rtw8821c.c | 18 +++
- drivers/net/wireless/realtek/rtw88/rtw8821c.h | 21 ++++
- drivers/net/wireless/realtek/rtw88/rtw8821cu.c | 50 ++++++++++
- drivers/net/wireless/realtek/rtw88/rtw8822b.c | 19 +++
- drivers/net/wireless/realtek/rtw88/rtw8822bu.c | 90 ++++++++++++++++++
- drivers/net/wireless/realtek/rtw88/rtw8822c.c | 24 ++++
- drivers/net/wireless/realtek/rtw88/rtw8822cu.c | 44 ++++++++
- drivers/net/wireless/realtek/rtw88/tx.h | 31 ++++++
- drivers/net/wireless/realtek/rtw88/usb.c | 911 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- drivers/net/wireless/realtek/rtw88/usb.h | 107 +++++++++++++++++++++
- drivers/net/wireless/realtek/rtw88/util.c | 103 ++++++++++++++++++++
- drivers/net/wireless/realtek/rtw88/util.h | 12 +-
- 29 files changed, 1650 insertions(+), 44 deletions(-)
- diff -Nurp linux-6.1/drivers/net/wireless/realtek/rtw88/coex.c linux-6.2/drivers/net/wireless/realtek/rtw88/coex.c
- --- linux-6.1/drivers/net/wireless/realtek/rtw88/coex.c 2022-12-12 00:15:18.000000000 +0200
- +++ linux-6.2/drivers/net/wireless/realtek/rtw88/coex.c 2022-12-24 00:49:25.771376835 +0200
- @@ -633,7 +633,7 @@ static struct sk_buff *rtw_coex_info_req
- struct rtw_coex *coex = &rtwdev->coex;
- struct sk_buff *skb_resp = NULL;
-
- - mutex_lock(&coex->mutex);
- + lockdep_assert_held(&rtwdev->mutex);
-
- rtw_fw_query_bt_mp_info(rtwdev, req);
-
- @@ -650,7 +650,6 @@ static struct sk_buff *rtw_coex_info_req
- }
-
- out:
- - mutex_unlock(&coex->mutex);
- return skb_resp;
- }
-
- diff -Nurp linux-6.1/drivers/net/wireless/realtek/rtw88/debug.c linux-6.2/drivers/net/wireless/realtek/rtw88/debug.c
- --- linux-6.1/drivers/net/wireless/realtek/rtw88/debug.c 2022-12-12 00:15:18.000000000 +0200
- +++ linux-6.2/drivers/net/wireless/realtek/rtw88/debug.c 2022-12-24 00:49:25.771376835 +0200
- @@ -144,7 +144,9 @@ static int rtw_debugfs_get_rf_read(struc
- addr = debugfs_priv->rf_addr;
- mask = debugfs_priv->rf_mask;
-
- + mutex_lock(&rtwdev->mutex);
- val = rtw_read_rf(rtwdev, path, addr, mask);
- + mutex_unlock(&rtwdev->mutex);
-
- seq_printf(m, "rf_read path:%d addr:0x%08x mask:0x%08x val=0x%08x\n",
- path, addr, mask, val);
- @@ -390,7 +392,9 @@ static ssize_t rtw_debugfs_set_h2c(struc
- return -EINVAL;
- }
-
- + mutex_lock(&rtwdev->mutex);
- rtw_fw_h2c_cmd_dbg(rtwdev, param);
- + mutex_unlock(&rtwdev->mutex);
-
- return count;
- }
- @@ -414,7 +418,9 @@ static ssize_t rtw_debugfs_set_rf_write(
- return count;
- }
-
- + mutex_lock(&rtwdev->mutex);
- rtw_write_rf(rtwdev, path, addr, mask, val);
- + mutex_unlock(&rtwdev->mutex);
- rtw_dbg(rtwdev, RTW_DBG_DEBUGFS,
- "write_rf path:%d addr:0x%08x mask:0x%08x, val:0x%08x\n",
- path, addr, mask, val);
- @@ -519,6 +525,8 @@ static int rtw_debug_get_rf_dump(struct
- u32 addr, offset, data;
- u8 path;
-
- + mutex_lock(&rtwdev->mutex);
- +
- for (path = 0; path < rtwdev->hal.rf_path_num; path++) {
- seq_printf(m, "RF path:%d\n", path);
- for (addr = 0; addr < 0x100; addr += 4) {
- @@ -533,6 +541,8 @@ static int rtw_debug_get_rf_dump(struct
- seq_puts(m, "\n");
- }
-
- + mutex_unlock(&rtwdev->mutex);
- +
- return 0;
- }
-
- @@ -831,7 +841,9 @@ static int rtw_debugfs_get_coex_info(str
- struct rtw_debugfs_priv *debugfs_priv = m->private;
- struct rtw_dev *rtwdev = debugfs_priv->rtwdev;
-
- + mutex_lock(&rtwdev->mutex);
- rtw_coex_display_coex_info(rtwdev, m);
- + mutex_unlock(&rtwdev->mutex);
-
- return 0;
- }
- @@ -1026,6 +1038,8 @@ static void dump_gapk_status(struct rtw_
- dm_info->dm_flags & BIT(RTW_DM_CAP_TXGAPK) ? '-' : '+',
- rtw_dm_cap_strs[RTW_DM_CAP_TXGAPK]);
-
- + mutex_lock(&rtwdev->mutex);
- +
- for (path = 0; path < rtwdev->hal.rf_path_num; path++) {
- val = rtw_read_rf(rtwdev, path, RF_GAINTX, RFREG_MASK);
- seq_printf(m, "path %d:\n0x%x = 0x%x\n", path, RF_GAINTX, val);
- @@ -1035,6 +1049,7 @@ static void dump_gapk_status(struct rtw_
- txgapk->rf3f_fs[path][i], i);
- seq_puts(m, "\n");
- }
- + mutex_unlock(&rtwdev->mutex);
- }
-
- static int rtw_debugfs_get_dm_cap(struct seq_file *m, void *v)
- diff -Nurp linux-6.1/drivers/net/wireless/realtek/rtw88/fw.c linux-6.2/drivers/net/wireless/realtek/rtw88/fw.c
- --- linux-6.1/drivers/net/wireless/realtek/rtw88/fw.c 2022-12-12 00:15:18.000000000 +0200
- +++ linux-6.2/drivers/net/wireless/realtek/rtw88/fw.c 2022-12-24 00:49:25.771376835 +0200
- @@ -311,10 +311,10 @@ EXPORT_SYMBOL(rtw_fw_c2h_cmd_isr);
- static void rtw_fw_send_h2c_command(struct rtw_dev *rtwdev,
- u8 *h2c)
- {
- + struct rtw_h2c_cmd *h2c_cmd = (struct rtw_h2c_cmd *)h2c;
- u8 box;
- u8 box_state;
- u32 box_reg, box_ex_reg;
- - int idx;
- int ret;
-
- rtw_dbg(rtwdev, RTW_DBG_FW,
- @@ -322,7 +322,7 @@ static void rtw_fw_send_h2c_command(stru
- h2c[3], h2c[2], h2c[1], h2c[0],
- h2c[7], h2c[6], h2c[5], h2c[4]);
-
- - spin_lock(&rtwdev->h2c.lock);
- + lockdep_assert_held(&rtwdev->mutex);
-
- box = rtwdev->h2c.last_box_num;
- switch (box) {
- @@ -344,7 +344,7 @@ static void rtw_fw_send_h2c_command(stru
- break;
- default:
- WARN(1, "invalid h2c mail box number\n");
- - goto out;
- + return;
- }
-
- ret = read_poll_timeout_atomic(rtw_read8, box_state,
- @@ -353,19 +353,14 @@ static void rtw_fw_send_h2c_command(stru
-
- if (ret) {
- rtw_err(rtwdev, "failed to send h2c command\n");
- - goto out;
- + return;
- }
-
- - for (idx = 0; idx < 4; idx++)
- - rtw_write8(rtwdev, box_reg + idx, h2c[idx]);
- - for (idx = 0; idx < 4; idx++)
- - rtw_write8(rtwdev, box_ex_reg + idx, h2c[idx + 4]);
- + rtw_write32(rtwdev, box_ex_reg, le32_to_cpu(h2c_cmd->msg_ext));
- + rtw_write32(rtwdev, box_reg, le32_to_cpu(h2c_cmd->msg));
-
- if (++rtwdev->h2c.last_box_num >= 4)
- rtwdev->h2c.last_box_num = 0;
- -
- -out:
- - spin_unlock(&rtwdev->h2c.lock);
- }
-
- void rtw_fw_h2c_cmd_dbg(struct rtw_dev *rtwdev, u8 *h2c)
- @@ -377,15 +372,13 @@ static void rtw_fw_send_h2c_packet(struc
- {
- int ret;
-
- - spin_lock(&rtwdev->h2c.lock);
- + lockdep_assert_held(&rtwdev->mutex);
-
- FW_OFFLOAD_H2C_SET_SEQ_NUM(h2c_pkt, rtwdev->h2c.seq);
- ret = rtw_hci_write_data_h2c(rtwdev, h2c_pkt, H2C_PKT_SIZE);
- if (ret)
- rtw_err(rtwdev, "failed to send h2c packet\n");
- rtwdev->h2c.seq++;
- -
- - spin_unlock(&rtwdev->h2c.lock);
- }
-
- void
- @@ -823,6 +816,16 @@ void rtw_fw_set_nlo_info(struct rtw_dev
-
- rtw_fw_send_h2c_command(rtwdev, h2c_pkt);
- }
- +
- +void rtw_fw_set_recover_bt_device(struct rtw_dev *rtwdev)
- +{
- + u8 h2c_pkt[H2C_PKT_SIZE] = {0};
- +
- + SET_H2C_CMD_ID_CLASS(h2c_pkt, H2C_CMD_RECOVER_BT_DEV);
- + SET_RECOVER_BT_DEV_EN(h2c_pkt, 1);
- +
- + rtw_fw_send_h2c_command(rtwdev, h2c_pkt);
- +}
-
- void rtw_fw_set_pg_info(struct rtw_dev *rtwdev)
- {
- diff -Nurp linux-6.1/drivers/net/wireless/realtek/rtw88/fw.h linux-6.2/drivers/net/wireless/realtek/rtw88/fw.h
- --- linux-6.1/drivers/net/wireless/realtek/rtw88/fw.h 2022-12-12 00:15:18.000000000 +0200
- +++ linux-6.2/drivers/net/wireless/realtek/rtw88/fw.h 2022-12-24 00:49:25.771376835 +0200
- @@ -81,6 +81,11 @@ struct rtw_c2h_adaptivity {
- u8 option;
- } __packed;
-
- +struct rtw_h2c_cmd {
- + __le32 msg;
- + __le32 msg_ext;
- +} __packed;
- +
- enum rtw_rsvd_packet_type {
- RSVD_BEACON,
- RSVD_DUMMY,
- @@ -550,6 +555,8 @@ static inline void rtw_h2c_pkt_set_heade
- #define H2C_CMD_AOAC_GLOBAL_INFO 0x82
- #define H2C_CMD_NLO_INFO 0x8C
-
- +#define H2C_CMD_RECOVER_BT_DEV 0xD1
- +
- #define SET_H2C_CMD_ID_CLASS(h2c_pkt, value) \
- le32p_replace_bits((__le32 *)(h2c_pkt) + 0x00, value, GENMASK(7, 0))
-
- @@ -749,6 +756,9 @@ static inline void rtw_h2c_pkt_set_heade
- #define SET_NLO_LOC_NLO_INFO(h2c_pkt, value) \
- le32p_replace_bits((__le32 *)(h2c_pkt) + 0x00, value, GENMASK(23, 16))
-
- +#define SET_RECOVER_BT_DEV_EN(h2c_pkt, value) \
- + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x00, value, BIT(8))
- +
- #define GET_FW_DUMP_LEN(_header) \
- le32_get_bits(*((__le32 *)(_header) + 0x00), GENMASK(15, 0))
- #define GET_FW_DUMP_SEQ(_header) \
- @@ -838,6 +848,7 @@ void rtw_fw_set_aoac_global_info_cmd(str
- u8 group_key_enc);
-
- void rtw_fw_set_nlo_info(struct rtw_dev *rtwdev, bool enable);
- +void rtw_fw_set_recover_bt_device(struct rtw_dev *rtwdev);
- void rtw_fw_update_pkt_probe_req(struct rtw_dev *rtwdev,
- struct cfg80211_ssid *ssid);
- void rtw_fw_channel_switch(struct rtw_dev *rtwdev, bool enable);
- diff -Nurp linux-6.1/drivers/net/wireless/realtek/rtw88/hci.h linux-6.2/drivers/net/wireless/realtek/rtw88/hci.h
- --- linux-6.1/drivers/net/wireless/realtek/rtw88/hci.h 2022-12-12 00:15:18.000000000 +0200
- +++ linux-6.2/drivers/net/wireless/realtek/rtw88/hci.h 2022-12-24 00:49:25.771376835 +0200
- @@ -166,12 +166,11 @@ static inline u32
- rtw_read_rf(struct rtw_dev *rtwdev, enum rtw_rf_path rf_path,
- u32 addr, u32 mask)
- {
- - unsigned long flags;
- u32 val;
-
- - spin_lock_irqsave(&rtwdev->rf_lock, flags);
- + lockdep_assert_held(&rtwdev->mutex);
- +
- val = rtwdev->chip->ops->read_rf(rtwdev, rf_path, addr, mask);
- - spin_unlock_irqrestore(&rtwdev->rf_lock, flags);
-
- return val;
- }
- @@ -180,11 +179,9 @@ static inline void
- rtw_write_rf(struct rtw_dev *rtwdev, enum rtw_rf_path rf_path,
- u32 addr, u32 mask, u32 data)
- {
- - unsigned long flags;
- + lockdep_assert_held(&rtwdev->mutex);
-
- - spin_lock_irqsave(&rtwdev->rf_lock, flags);
- rtwdev->chip->ops->write_rf(rtwdev, rf_path, addr, mask, data);
- - spin_unlock_irqrestore(&rtwdev->rf_lock, flags);
- }
-
- static inline u32
- diff -Nurp linux-6.1/drivers/net/wireless/realtek/rtw88/Kconfig linux-6.2/drivers/net/wireless/realtek/rtw88/Kconfig
- --- linux-6.1/drivers/net/wireless/realtek/rtw88/Kconfig 2022-12-12 00:15:18.000000000 +0200
- +++ linux-6.2/drivers/net/wireless/realtek/rtw88/Kconfig 2022-12-24 00:49:25.770376835 +0200
- @@ -16,6 +16,9 @@ config RTW88_CORE
- config RTW88_PCI
- tristate
-
- +config RTW88_USB
- + tristate
- +
- config RTW88_8822B
- tristate
-
- @@ -39,6 +42,17 @@ config RTW88_8822BE
-
- 802.11ac PCIe wireless network adapter
-
- +config RTW88_8822BU
- + tristate "Realtek 8822BU USB wireless network adapter"
- + depends on USB
- + select RTW88_CORE
- + select RTW88_USB
- + select RTW88_8822B
- + help
- + Select this option will enable support for 8822BU chipset
- +
- + 802.11ac USB wireless network adapter
- +
- config RTW88_8822CE
- tristate "Realtek 8822CE PCI wireless network adapter"
- depends on PCI
- @@ -50,6 +64,17 @@ config RTW88_8822CE
-
- 802.11ac PCIe wireless network adapter
-
- +config RTW88_8822CU
- + tristate "Realtek 8822CU USB wireless network adapter"
- + depends on USB
- + select RTW88_CORE
- + select RTW88_USB
- + select RTW88_8822C
- + help
- + Select this option will enable support for 8822CU chipset
- +
- + 802.11ac USB wireless network adapter
- +
- config RTW88_8723DE
- tristate "Realtek 8723DE PCI wireless network adapter"
- depends on PCI
- @@ -61,6 +86,17 @@ config RTW88_8723DE
-
- 802.11n PCIe wireless network adapter
-
- +config RTW88_8723DU
- + tristate "Realtek 8723DU USB wireless network adapter"
- + depends on USB
- + select RTW88_CORE
- + select RTW88_USB
- + select RTW88_8723D
- + help
- + Select this option will enable support for 8723DU chipset
- +
- + 802.11n USB wireless network adapter
- +
- config RTW88_8821CE
- tristate "Realtek 8821CE PCI wireless network adapter"
- depends on PCI
- @@ -72,6 +108,17 @@ config RTW88_8821CE
-
- 802.11ac PCIe wireless network adapter
-
- +config RTW88_8821CU
- + tristate "Realtek 8821CU USB wireless network adapter"
- + depends on USB
- + select RTW88_CORE
- + select RTW88_USB
- + select RTW88_8821C
- + help
- + Select this option will enable support for 8821CU chipset
- +
- + 802.11ac USB wireless network adapter
- +
- config RTW88_DEBUG
- bool "Realtek rtw88 debug support"
- depends on RTW88_CORE
- diff -Nurp linux-6.1/drivers/net/wireless/realtek/rtw88/mac80211.c linux-6.2/drivers/net/wireless/realtek/rtw88/mac80211.c
- --- linux-6.1/drivers/net/wireless/realtek/rtw88/mac80211.c 2022-12-12 00:15:18.000000000 +0200
- +++ linux-6.2/drivers/net/wireless/realtek/rtw88/mac80211.c 2022-12-24 00:49:25.772376835 +0200
- @@ -487,8 +487,8 @@ static int rtw_ops_sta_remove(struct iee
- {
- struct rtw_dev *rtwdev = hw->priv;
-
- - rtw_fw_beacon_filter_config(rtwdev, false, vif);
- mutex_lock(&rtwdev->mutex);
- + rtw_fw_beacon_filter_config(rtwdev, false, vif);
- rtw_sta_remove(rtwdev, sta, true);
- mutex_unlock(&rtwdev->mutex);
-
- diff -Nurp linux-6.1/drivers/net/wireless/realtek/rtw88/mac.c linux-6.2/drivers/net/wireless/realtek/rtw88/mac.c
- --- linux-6.1/drivers/net/wireless/realtek/rtw88/mac.c 2022-12-12 00:15:18.000000000 +0200
- +++ linux-6.2/drivers/net/wireless/realtek/rtw88/mac.c 2022-12-24 00:49:25.772376835 +0200
- @@ -906,7 +906,8 @@ out:
- return ret;
- }
-
- -int rtw_download_firmware(struct rtw_dev *rtwdev, struct rtw_fw_state *fw)
- +static
- +int _rtw_download_firmware(struct rtw_dev *rtwdev, struct rtw_fw_state *fw)
- {
- if (rtw_chip_wcpu_11n(rtwdev))
- return __rtw_download_firmware_legacy(rtwdev, fw);
- @@ -914,6 +915,21 @@ int rtw_download_firmware(struct rtw_dev
- return __rtw_download_firmware(rtwdev, fw);
- }
-
- +int rtw_download_firmware(struct rtw_dev *rtwdev, struct rtw_fw_state *fw)
- +{
- + int ret;
- +
- + ret = _rtw_download_firmware(rtwdev, fw);
- + if (ret)
- + return ret;
- +
- + if (rtw_hci_type(rtwdev) == RTW_HCI_TYPE_PCIE &&
- + rtwdev->chip->id == RTW_CHIP_TYPE_8821C)
- + rtw_fw_set_recover_bt_device(rtwdev);
- +
- + return 0;
- +}
- +
- static u32 get_priority_queues(struct rtw_dev *rtwdev, u32 queues)
- {
- const struct rtw_rqpn *rqpn = rtwdev->fifo.rqpn;
- @@ -1032,6 +1048,9 @@ static int txdma_queue_mapping(struct rt
- if (rtw_chip_wcpu_11ac(rtwdev))
- rtw_write32(rtwdev, REG_H2CQ_CSR, BIT_H2CQ_FULL);
-
- + if (rtw_hci_type(rtwdev) == RTW_HCI_TYPE_USB)
- + rtw_write8_set(rtwdev, REG_TXDMA_PQ_MAP, BIT_RXDMA_ARBBW_EN);
- +
- return 0;
- }
-
- diff -Nurp linux-6.1/drivers/net/wireless/realtek/rtw88/main.c linux-6.2/drivers/net/wireless/realtek/rtw88/main.c
- --- linux-6.1/drivers/net/wireless/realtek/rtw88/main.c 2022-12-12 00:15:18.000000000 +0200
- +++ linux-6.2/drivers/net/wireless/realtek/rtw88/main.c 2022-12-24 00:49:25.772376835 +0200
- @@ -1731,7 +1731,8 @@ static void rtw_load_firmware_cb(const s
- update_firmware_info(rtwdev, fw);
- complete_all(&fw->completion);
-
- - rtw_info(rtwdev, "Firmware version %u.%u.%u, H2C version %u\n",
- + rtw_info(rtwdev, "%sFirmware version %u.%u.%u, H2C version %u\n",
- + fw->type == RTW_WOWLAN_FW ? "WOW " : "",
- fw->version, fw->sub_version, fw->sub_index, fw->h2c_version);
- }
-
- @@ -1757,6 +1758,7 @@ static int rtw_load_firmware(struct rtw_
- return -ENOENT;
- }
-
- + fw->type = type;
- fw->rtwdev = rtwdev;
- init_completion(&fw->completion);
-
- @@ -1781,6 +1783,10 @@ static int rtw_chip_parameter_setup(stru
- rtwdev->hci.rpwm_addr = 0x03d9;
- rtwdev->hci.cpwm_addr = 0x03da;
- break;
- + case RTW_HCI_TYPE_USB:
- + rtwdev->hci.rpwm_addr = 0xfe58;
- + rtwdev->hci.cpwm_addr = 0xfe57;
- + break;
- default:
- rtw_err(rtwdev, "unsupported hci type\n");
- return -EINVAL;
- @@ -2065,13 +2071,10 @@ int rtw_core_init(struct rtw_dev *rtwdev
- skb_queue_head_init(&rtwdev->coex.queue);
- skb_queue_head_init(&rtwdev->tx_report.queue);
-
- - spin_lock_init(&rtwdev->rf_lock);
- - spin_lock_init(&rtwdev->h2c.lock);
- spin_lock_init(&rtwdev->txq_lock);
- spin_lock_init(&rtwdev->tx_report.q_lock);
-
- mutex_init(&rtwdev->mutex);
- - mutex_init(&rtwdev->coex.mutex);
- mutex_init(&rtwdev->hal.tx_power_mutex);
-
- init_waitqueue_head(&rtwdev->coex.wait);
- @@ -2143,7 +2146,6 @@ void rtw_core_deinit(struct rtw_dev *rtw
- }
-
- mutex_destroy(&rtwdev->mutex);
- - mutex_destroy(&rtwdev->coex.mutex);
- mutex_destroy(&rtwdev->hal.tx_power_mutex);
- }
- EXPORT_SYMBOL(rtw_core_deinit);
- diff -Nurp linux-6.1/drivers/net/wireless/realtek/rtw88/main.h linux-6.2/drivers/net/wireless/realtek/rtw88/main.h
- --- linux-6.1/drivers/net/wireless/realtek/rtw88/main.h 2022-12-12 00:15:18.000000000 +0200
- +++ linux-6.2/drivers/net/wireless/realtek/rtw88/main.h 2022-12-24 00:49:25.773376835 +0200
- @@ -871,6 +871,10 @@ struct rtw_chip_ops {
- bool is_tx2_path);
- void (*config_txrx_mode)(struct rtw_dev *rtwdev, u8 tx_path,
- u8 rx_path, bool is_tx2_path);
- + /* for USB/SDIO only */
- + void (*fill_txdesc_checksum)(struct rtw_dev *rtwdev,
- + struct rtw_tx_pkt_info *pkt_info,
- + u8 *txdesc);
-
- /* for coex */
- void (*coex_set_init)(struct rtw_dev *rtwdev);
- @@ -1501,8 +1505,6 @@ struct rtw_coex_stat {
- };
-
- struct rtw_coex {
- - /* protects coex info request section */
- - struct mutex mutex;
- struct sk_buff_head queue;
- wait_queue_head_t wait;
-
- @@ -1851,6 +1853,7 @@ struct rtw_fw_state {
- u16 h2c_version;
- u32 feature;
- u32 feature_ext;
- + enum rtw_fw_type type;
- };
-
- enum rtw_sar_sources {
- @@ -1994,9 +1997,6 @@ struct rtw_dev {
- /* ensures exclusive access from mac80211 callbacks */
- struct mutex mutex;
-
- - /* read/write rf register */
- - spinlock_t rf_lock;
- -
- /* watch dog every 2 sec */
- struct delayed_work watch_dog_work;
- u32 watch_dog_cnt;
- @@ -2022,8 +2022,6 @@ struct rtw_dev {
- struct {
- /* incicate the mail box to use with fw */
- u8 last_box_num;
- - /* protect to send h2c to fw */
- - spinlock_t lock;
- u32 seq;
- } h2c;
-
- diff -Nurp linux-6.1/drivers/net/wireless/realtek/rtw88/Makefile linux-6.2/drivers/net/wireless/realtek/rtw88/Makefile
- --- linux-6.1/drivers/net/wireless/realtek/rtw88/Makefile 2022-12-12 00:15:18.000000000 +0200
- +++ linux-6.2/drivers/net/wireless/realtek/rtw88/Makefile 2022-12-24 00:49:25.770376835 +0200
- @@ -26,23 +26,38 @@ rtw88_8822b-objs := rtw8822b.o rtw8822b
- obj-$(CONFIG_RTW88_8822BE) += rtw88_8822be.o
- rtw88_8822be-objs := rtw8822be.o
-
- +obj-$(CONFIG_RTW88_8822BU) += rtw88_8822bu.o
- +rtw88_8822bu-objs := rtw8822bu.o
- +
- obj-$(CONFIG_RTW88_8822C) += rtw88_8822c.o
- rtw88_8822c-objs := rtw8822c.o rtw8822c_table.o
-
- obj-$(CONFIG_RTW88_8822CE) += rtw88_8822ce.o
- rtw88_8822ce-objs := rtw8822ce.o
-
- +obj-$(CONFIG_RTW88_8822CU) += rtw88_8822cu.o
- +rtw88_8822cu-objs := rtw8822cu.o
- +
- obj-$(CONFIG_RTW88_8723D) += rtw88_8723d.o
- rtw88_8723d-objs := rtw8723d.o rtw8723d_table.o
-
- obj-$(CONFIG_RTW88_8723DE) += rtw88_8723de.o
- rtw88_8723de-objs := rtw8723de.o
-
- +obj-$(CONFIG_RTW88_8723DU) += rtw88_8723du.o
- +rtw88_8723du-objs := rtw8723du.o
- +
- obj-$(CONFIG_RTW88_8821C) += rtw88_8821c.o
- rtw88_8821c-objs := rtw8821c.o rtw8821c_table.o
-
- obj-$(CONFIG_RTW88_8821CE) += rtw88_8821ce.o
- rtw88_8821ce-objs := rtw8821ce.o
-
- +obj-$(CONFIG_RTW88_8821CU) += rtw88_8821cu.o
- +rtw88_8821cu-objs := rtw8821cu.o
- +
- obj-$(CONFIG_RTW88_PCI) += rtw88_pci.o
- rtw88_pci-objs := pci.o
- +
- +obj-$(CONFIG_RTW88_USB) += rtw88_usb.o
- +rtw88_usb-objs := usb.o
- diff -Nurp linux-6.1/drivers/net/wireless/realtek/rtw88/phy.c linux-6.2/drivers/net/wireless/realtek/rtw88/phy.c
- --- linux-6.1/drivers/net/wireless/realtek/rtw88/phy.c 2022-12-12 00:15:18.000000000 +0200
- +++ linux-6.2/drivers/net/wireless/realtek/rtw88/phy.c 2022-12-24 00:49:25.773376835 +0200
- @@ -300,7 +300,7 @@ static void rtw_phy_stat_rssi(struct rtw
-
- data.rtwdev = rtwdev;
- data.min_rssi = U8_MAX;
- - rtw_iterate_stas_atomic(rtwdev, rtw_phy_stat_rssi_iter, &data);
- + rtw_iterate_stas(rtwdev, rtw_phy_stat_rssi_iter, &data);
-
- dm_info->pre_min_rssi = dm_info->min_rssi;
- dm_info->min_rssi = data.min_rssi;
- @@ -544,7 +544,7 @@ static void rtw_phy_ra_info_update(struc
- if (rtwdev->watch_dog_cnt & 0x3)
- return;
-
- - rtw_iterate_stas_atomic(rtwdev, rtw_phy_ra_info_update_iter, rtwdev);
- + rtw_iterate_stas(rtwdev, rtw_phy_ra_info_update_iter, rtwdev);
- }
-
- static u32 rtw_phy_get_rrsr_mask(struct rtw_dev *rtwdev, u8 rate_idx)
- @@ -597,7 +597,7 @@ static void rtw_phy_rrsr_update(struct r
- struct rtw_dm_info *dm_info = &rtwdev->dm_info;
-
- dm_info->rrsr_mask_min = RRSR_RATE_ORDER_MAX;
- - rtw_iterate_stas_atomic(rtwdev, rtw_phy_rrsr_mask_min_iter, rtwdev);
- + rtw_iterate_stas(rtwdev, rtw_phy_rrsr_mask_min_iter, rtwdev);
- rtw_write32(rtwdev, REG_RRSR, dm_info->rrsr_val_init & dm_info->rrsr_mask_min);
- }
-
- diff -Nurp linux-6.1/drivers/net/wireless/realtek/rtw88/ps.c linux-6.2/drivers/net/wireless/realtek/rtw88/ps.c
- --- linux-6.1/drivers/net/wireless/realtek/rtw88/ps.c 2022-12-12 00:15:18.000000000 +0200
- +++ linux-6.2/drivers/net/wireless/realtek/rtw88/ps.c 2022-12-24 00:49:25.773376835 +0200
- @@ -61,7 +61,7 @@ int rtw_leave_ips(struct rtw_dev *rtwdev
- return ret;
- }
-
- - rtw_iterate_vifs_atomic(rtwdev, rtw_restore_port_cfg_iter, rtwdev);
- + rtw_iterate_vifs(rtwdev, rtw_restore_port_cfg_iter, rtwdev);
-
- rtw_coex_ips_notify(rtwdev, COEX_IPS_LEAVE);
-
- diff -Nurp linux-6.1/drivers/net/wireless/realtek/rtw88/reg.h linux-6.2/drivers/net/wireless/realtek/rtw88/reg.h
- --- linux-6.1/drivers/net/wireless/realtek/rtw88/reg.h 2022-12-12 00:15:18.000000000 +0200
- +++ linux-6.2/drivers/net/wireless/realtek/rtw88/reg.h 2022-12-24 00:49:25.773376835 +0200
- @@ -184,6 +184,7 @@
- #define BIT_TXDMA_VIQ_MAP(x) \
- (((x) & BIT_MASK_TXDMA_VIQ_MAP) << BIT_SHIFT_TXDMA_VIQ_MAP)
- #define REG_TXDMA_PQ_MAP 0x010C
- +#define BIT_RXDMA_ARBBW_EN BIT(0)
- #define BIT_SHIFT_TXDMA_BEQ_MAP 8
- #define BIT_MASK_TXDMA_BEQ_MAP 0x3
- #define BIT_TXDMA_BEQ_MAP(x) \
- diff -Nurp linux-6.1/drivers/net/wireless/realtek/rtw88/rtw8723d.c linux-6.2/drivers/net/wireless/realtek/rtw88/rtw8723d.c
- --- linux-6.1/drivers/net/wireless/realtek/rtw88/rtw8723d.c 2022-12-12 00:15:18.000000000 +0200
- +++ linux-6.2/drivers/net/wireless/realtek/rtw88/rtw8723d.c 2022-12-24 00:49:25.773376835 +0200
- @@ -210,6 +210,12 @@ static void rtw8723de_efuse_parsing(stru
- ether_addr_copy(efuse->addr, map->e.mac_addr);
- }
-
- +static void rtw8723du_efuse_parsing(struct rtw_efuse *efuse,
- + struct rtw8723d_efuse *map)
- +{
- + ether_addr_copy(efuse->addr, map->u.mac_addr);
- +}
- +
- static int rtw8723d_read_efuse(struct rtw_dev *rtwdev, u8 *log_map)
- {
- struct rtw_efuse *efuse = &rtwdev->efuse;
- @@ -239,6 +245,9 @@ static int rtw8723d_read_efuse(struct rt
- case RTW_HCI_TYPE_PCIE:
- rtw8723de_efuse_parsing(efuse, map);
- break;
- + case RTW_HCI_TYPE_USB:
- + rtw8723du_efuse_parsing(efuse, map);
- + break;
- default:
- /* unsupported now */
- return -ENOTSUPP;
- @@ -1945,6 +1954,24 @@ static void rtw8723d_pwr_track(struct rt
- dm_info->pwr_trk_triggered = false;
- }
-
- +static void rtw8723d_fill_txdesc_checksum(struct rtw_dev *rtwdev,
- + struct rtw_tx_pkt_info *pkt_info,
- + u8 *txdesc)
- +{
- + size_t words = 32 / 2; /* calculate the first 32 bytes (16 words) */
- + __le16 chksum = 0;
- + __le16 *data = (__le16 *)(txdesc);
- +
- + SET_TX_DESC_TXDESC_CHECKSUM(txdesc, 0x0000);
- +
- + while (words--)
- + chksum ^= *data++;
- +
- + chksum = ~chksum;
- +
- + SET_TX_DESC_TXDESC_CHECKSUM(txdesc, __le16_to_cpu(chksum));
- +}
- +
- static struct rtw_chip_ops rtw8723d_ops = {
- .phy_set_param = rtw8723d_phy_set_param,
- .read_efuse = rtw8723d_read_efuse,
- @@ -1965,6 +1992,7 @@ static struct rtw_chip_ops rtw8723d_ops
- .config_bfee = NULL,
- .set_gid_table = NULL,
- .cfg_csi_rate = NULL,
- + .fill_txdesc_checksum = rtw8723d_fill_txdesc_checksum,
-
- .coex_set_init = rtw8723d_coex_cfg_init,
- .coex_set_ant_switch = NULL,
- diff -Nurp linux-6.1/drivers/net/wireless/realtek/rtw88/rtw8723d.h linux-6.2/drivers/net/wireless/realtek/rtw88/rtw8723d.h
- --- linux-6.1/drivers/net/wireless/realtek/rtw88/rtw8723d.h 2022-12-12 00:15:18.000000000 +0200
- +++ linux-6.2/drivers/net/wireless/realtek/rtw88/rtw8723d.h 2022-12-24 00:49:25.773376835 +0200
- @@ -41,6 +41,14 @@ struct rtw8723de_efuse {
- u8 sub_device_id[2];
- };
-
- +struct rtw8723du_efuse {
- + u8 res4[48]; /* 0xd0 */
- + u8 vender_id[2]; /* 0x100 */
- + u8 product_id[2]; /* 0x102 */
- + u8 usb_option; /* 0x104 */
- + u8 mac_addr[ETH_ALEN]; /* 0x107 */
- +};
- +
- struct rtw8723d_efuse {
- __le16 rtl_id;
- u8 rsvd[2];
- @@ -69,7 +77,10 @@ struct rtw8723d_efuse {
- u8 rfe_option;
- u8 country_code[2];
- u8 res[3];
- - struct rtw8723de_efuse e;
- + union {
- + struct rtw8723de_efuse e;
- + struct rtw8723du_efuse u;
- + };
- };
-
- extern const struct rtw_chip_info rtw8723d_hw_spec;
- diff -Nurp linux-6.1/drivers/net/wireless/realtek/rtw88/rtw8723du.c linux-6.2/drivers/net/wireless/realtek/rtw88/rtw8723du.c
- --- linux-6.1/drivers/net/wireless/realtek/rtw88/rtw8723du.c 1970-01-01 02:00:00.000000000 +0200
- +++ linux-6.2/drivers/net/wireless/realtek/rtw88/rtw8723du.c 2022-12-24 00:49:25.773376835 +0200
- @@ -0,0 +1,36 @@
- +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
- +/* Copyright(c) 2018-2019 Realtek Corporation
- + */
- +
- +#include <linux/module.h>
- +#include <linux/usb.h>
- +#include "main.h"
- +#include "rtw8723d.h"
- +#include "usb.h"
- +
- +static const struct usb_device_id rtw_8723du_id_table[] = {
- + { USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0xd723, 0xff, 0xff, 0xff),
- + .driver_info = (kernel_ulong_t)&(rtw8723d_hw_spec) }, /* 8723DU 1*1 */
- + { USB_DEVICE_AND_INTERFACE_INFO(0x7392, 0xd611, 0xff, 0xff, 0xff),
- + .driver_info = (kernel_ulong_t)&(rtw8723d_hw_spec) }, /* Edimax EW-7611ULB V2 */
- + { },
- +};
- +MODULE_DEVICE_TABLE(usb, rtw_8723du_id_table);
- +
- +static int rtw8723du_probe(struct usb_interface *intf,
- + const struct usb_device_id *id)
- +{
- + return rtw_usb_probe(intf, id);
- +}
- +
- +static struct usb_driver rtw_8723du_driver = {
- + .name = "rtw_8723du",
- + .id_table = rtw_8723du_id_table,
- + .probe = rtw8723du_probe,
- + .disconnect = rtw_usb_disconnect,
- +};
- +module_usb_driver(rtw_8723du_driver);
- +
- +MODULE_AUTHOR("Hans Ulli Kroll <linux@ulli-kroll.de>");
- +MODULE_DESCRIPTION("Realtek 802.11n wireless 8723du driver");
- +MODULE_LICENSE("Dual BSD/GPL");
- diff -Nurp linux-6.1/drivers/net/wireless/realtek/rtw88/rtw8821c.c linux-6.2/drivers/net/wireless/realtek/rtw88/rtw8821c.c
- --- linux-6.1/drivers/net/wireless/realtek/rtw88/rtw8821c.c 2022-12-12 00:15:18.000000000 +0200
- +++ linux-6.2/drivers/net/wireless/realtek/rtw88/rtw8821c.c 2022-12-24 00:49:25.774376835 +0200
- @@ -26,6 +26,12 @@ static void rtw8821ce_efuse_parsing(stru
- ether_addr_copy(efuse->addr, map->e.mac_addr);
- }
-
- +static void rtw8821cu_efuse_parsing(struct rtw_efuse *efuse,
- + struct rtw8821c_efuse *map)
- +{
- + ether_addr_copy(efuse->addr, map->u.mac_addr);
- +}
- +
- enum rtw8821ce_rf_set {
- SWITCH_TO_BTG,
- SWITCH_TO_WLG,
- @@ -68,6 +74,9 @@ static int rtw8821c_read_efuse(struct rt
- case RTW_HCI_TYPE_PCIE:
- rtw8821ce_efuse_parsing(efuse, map);
- break;
- + case RTW_HCI_TYPE_USB:
- + rtw8821cu_efuse_parsing(efuse, map);
- + break;
- default:
- /* unsupported now */
- return -ENOTSUPP;
- @@ -1148,6 +1157,13 @@ static void rtw8821c_phy_cck_pd_set(stru
- dm_info->cck_pd_default + new_lvl * 2);
- }
-
- +static void rtw8821c_fill_txdesc_checksum(struct rtw_dev *rtwdev,
- + struct rtw_tx_pkt_info *pkt_info,
- + u8 *txdesc)
- +{
- + fill_txdesc_checksum_common(txdesc, 16);
- +}
- +
- static struct rtw_pwr_seq_cmd trans_carddis_to_cardemu_8821c[] = {
- {0x0086,
- RTW_PWR_CUT_ALL_MSK,
- @@ -1521,6 +1537,7 @@ static const struct rtw_rfe_def rtw8821c
- [2] = RTW_DEF_RFE_EXT(8821c, 0, 0, 2),
- [4] = RTW_DEF_RFE_EXT(8821c, 0, 0, 2),
- [6] = RTW_DEF_RFE(8821c, 0, 0),
- + [34] = RTW_DEF_RFE(8821c, 0, 0),
- };
-
- static struct rtw_hw_reg rtw8821c_dig[] = {
- @@ -1595,6 +1612,7 @@ static struct rtw_chip_ops rtw8821c_ops
- .config_bfee = rtw8821c_bf_config_bfee,
- .set_gid_table = rtw_bf_set_gid_table,
- .cfg_csi_rate = rtw_bf_cfg_csi_rate,
- + .fill_txdesc_checksum = rtw8821c_fill_txdesc_checksum,
-
- .coex_set_init = rtw8821c_coex_cfg_init,
- .coex_set_ant_switch = rtw8821c_coex_cfg_ant_switch,
- diff -Nurp linux-6.1/drivers/net/wireless/realtek/rtw88/rtw8821c.h linux-6.2/drivers/net/wireless/realtek/rtw88/rtw8821c.h
- --- linux-6.1/drivers/net/wireless/realtek/rtw88/rtw8821c.h 2022-12-12 00:15:18.000000000 +0200
- +++ linux-6.2/drivers/net/wireless/realtek/rtw88/rtw8821c.h 2022-12-24 00:49:25.774376835 +0200
- @@ -9,6 +9,26 @@
-
- #define RCR_VHT_ACK BIT(26)
-
- +struct rtw8821cu_efuse {
- + u8 res4[4]; /* 0xd0 */
- + u8 usb_optional_function;
- + u8 res5[0x1e];
- + u8 res6[2];
- + u8 serial[0x0b]; /* 0xf5 */
- + u8 vid; /* 0x100 */
- + u8 res7;
- + u8 pid;
- + u8 res8[4];
- + u8 mac_addr[ETH_ALEN]; /* 0x107 */
- + u8 res9[2];
- + u8 vendor_name[0x07];
- + u8 res10[2];
- + u8 device_name[0x14];
- + u8 res11[0xcf];
- + u8 package_type; /* 0x1fb */
- + u8 res12[0x4];
- +};
- +
- struct rtw8821ce_efuse {
- u8 mac_addr[ETH_ALEN]; /* 0xd0 */
- u8 vender_id[2];
- @@ -73,6 +93,7 @@ struct rtw8821c_efuse {
- u8 res[3];
- union {
- struct rtw8821ce_efuse e;
- + struct rtw8821cu_efuse u;
- };
- };
-
- diff -Nurp linux-6.1/drivers/net/wireless/realtek/rtw88/rtw8821cu.c linux-6.2/drivers/net/wireless/realtek/rtw88/rtw8821cu.c
- --- linux-6.1/drivers/net/wireless/realtek/rtw88/rtw8821cu.c 1970-01-01 02:00:00.000000000 +0200
- +++ linux-6.2/drivers/net/wireless/realtek/rtw88/rtw8821cu.c 2022-12-24 00:49:25.774376835 +0200
- @@ -0,0 +1,50 @@
- +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
- +/* Copyright(c) 2018-2019 Realtek Corporation
- + */
- +
- +#include <linux/module.h>
- +#include <linux/usb.h>
- +#include "main.h"
- +#include "rtw8821c.h"
- +#include "usb.h"
- +
- +static const struct usb_device_id rtw_8821cu_id_table[] = {
- + { USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0xb82b, 0xff, 0xff, 0xff),
- + .driver_info = (kernel_ulong_t)&(rtw8821c_hw_spec) }, /* 8821CU */
- + { USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0xb820, 0xff, 0xff, 0xff),
- + .driver_info = (kernel_ulong_t)&(rtw8821c_hw_spec) }, /* 8821CU */
- + { USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0xc821, 0xff, 0xff, 0xff),
- + .driver_info = (kernel_ulong_t)&(rtw8821c_hw_spec) }, /* 8821CU */
- + { USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0xc820, 0xff, 0xff, 0xff),
- + .driver_info = (kernel_ulong_t)&(rtw8821c_hw_spec) }, /* 8821CU */
- + { USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0xc82a, 0xff, 0xff, 0xff),
- + .driver_info = (kernel_ulong_t)&(rtw8821c_hw_spec) }, /* 8821CU */
- + { USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0xc82b, 0xff, 0xff, 0xff),
- + .driver_info = (kernel_ulong_t)&(rtw8821c_hw_spec) }, /* 8821CU */
- + { USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0xc811, 0xff, 0xff, 0xff),
- + .driver_info = (kernel_ulong_t)&(rtw8821c_hw_spec) }, /* 8811CU */
- + { USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0x8811, 0xff, 0xff, 0xff),
- + .driver_info = (kernel_ulong_t)&(rtw8821c_hw_spec) }, /* 8811CU */
- + { USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0x2006, 0xff, 0xff, 0xff),
- + .driver_info = (kernel_ulong_t)&(rtw8821c_hw_spec) }, /* TOTOLINK A650UA v3 */
- + {},
- +};
- +MODULE_DEVICE_TABLE(usb, rtw_8821cu_id_table);
- +
- +static int rtw_8821cu_probe(struct usb_interface *intf,
- + const struct usb_device_id *id)
- +{
- + return rtw_usb_probe(intf, id);
- +}
- +
- +static struct usb_driver rtw_8821cu_driver = {
- + .name = "rtw_8821cu",
- + .id_table = rtw_8821cu_id_table,
- + .probe = rtw_8821cu_probe,
- + .disconnect = rtw_usb_disconnect,
- +};
- +module_usb_driver(rtw_8821cu_driver);
- +
- +MODULE_AUTHOR("Hans Ulli Kroll <linux@ulli-kroll.de>");
- +MODULE_DESCRIPTION("Realtek 802.11ac wireless 8821cu driver");
- +MODULE_LICENSE("Dual BSD/GPL");
- diff -Nurp linux-6.1/drivers/net/wireless/realtek/rtw88/rtw8822b.c linux-6.2/drivers/net/wireless/realtek/rtw88/rtw8822b.c
- --- linux-6.1/drivers/net/wireless/realtek/rtw88/rtw8822b.c 2022-12-12 00:15:18.000000000 +0200
- +++ linux-6.2/drivers/net/wireless/realtek/rtw88/rtw8822b.c 2022-12-24 00:49:25.774376835 +0200
- @@ -26,6 +26,12 @@ static void rtw8822be_efuse_parsing(stru
- ether_addr_copy(efuse->addr, map->e.mac_addr);
- }
-
- +static void rtw8822bu_efuse_parsing(struct rtw_efuse *efuse,
- + struct rtw8822b_efuse *map)
- +{
- + ether_addr_copy(efuse->addr, map->u.mac_addr);
- +}
- +
- static int rtw8822b_read_efuse(struct rtw_dev *rtwdev, u8 *log_map)
- {
- struct rtw_efuse *efuse = &rtwdev->efuse;
- @@ -56,6 +62,9 @@ static int rtw8822b_read_efuse(struct rt
- case RTW_HCI_TYPE_PCIE:
- rtw8822be_efuse_parsing(efuse, map);
- break;
- + case RTW_HCI_TYPE_USB:
- + rtw8822bu_efuse_parsing(efuse, map);
- + break;
- default:
- /* unsupported now */
- return -ENOTSUPP;
- @@ -1588,6 +1597,15 @@ static void rtw8822b_adaptivity(struct r
- rtw_phy_set_edcca_th(rtwdev, l2h, h2l);
- }
-
- +static void rtw8822b_fill_txdesc_checksum(struct rtw_dev *rtwdev,
- + struct rtw_tx_pkt_info *pkt_info,
- + u8 *txdesc)
- +{
- + size_t words = 32 / 2; /* calculate the first 32 bytes (16 words) */
- +
- + fill_txdesc_checksum_common(txdesc, words);
- +}
- +
- static const struct rtw_pwr_seq_cmd trans_carddis_to_cardemu_8822b[] = {
- {0x0086,
- RTW_PWR_CUT_ALL_MSK,
- @@ -2163,6 +2181,7 @@ static struct rtw_chip_ops rtw8822b_ops
- .cfg_csi_rate = rtw_bf_cfg_csi_rate,
- .adaptivity_init = rtw8822b_adaptivity_init,
- .adaptivity = rtw8822b_adaptivity,
- + .fill_txdesc_checksum = rtw8822b_fill_txdesc_checksum,
-
- .coex_set_init = rtw8822b_coex_cfg_init,
- .coex_set_ant_switch = rtw8822b_coex_cfg_ant_switch,
- diff -Nurp linux-6.1/drivers/net/wireless/realtek/rtw88/rtw8822bu.c linux-6.2/drivers/net/wireless/realtek/rtw88/rtw8822bu.c
- --- linux-6.1/drivers/net/wireless/realtek/rtw88/rtw8822bu.c 1970-01-01 02:00:00.000000000 +0200
- +++ linux-6.2/drivers/net/wireless/realtek/rtw88/rtw8822bu.c 2022-12-24 00:49:25.774376835 +0200
- @@ -0,0 +1,90 @@
- +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
- +/* Copyright(c) 2018-2019 Realtek Corporation
- + */
- +
- +#include <linux/module.h>
- +#include <linux/usb.h>
- +#include "main.h"
- +#include "rtw8822b.h"
- +#include "usb.h"
- +
- +static const struct usb_device_id rtw_8822bu_id_table[] = {
- + { USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0xb812, 0xff, 0xff, 0xff),
- + .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) },
- + { USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0xb82c, 0xff, 0xff, 0xff),
- + .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) },
- + { USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0x2102, 0xff, 0xff, 0xff),
- + .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* CCNC */
- + { USB_DEVICE_AND_INTERFACE_INFO(0x7392, 0xb822, 0xff, 0xff, 0xff),
- + .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* Edimax EW-7822ULC */
- + { USB_DEVICE_AND_INTERFACE_INFO(0x7392, 0xc822, 0xff, 0xff, 0xff),
- + .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* Edimax EW-7822UTC */
- + { USB_DEVICE_AND_INTERFACE_INFO(0x7392, 0xd822, 0xff, 0xff, 0xff),
- + .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* Edimax */
- + { USB_DEVICE_AND_INTERFACE_INFO(0x7392, 0xe822, 0xff, 0xff, 0xff),
- + .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* Edimax */
- + { USB_DEVICE_AND_INTERFACE_INFO(0x7392, 0xf822, 0xff, 0xff, 0xff),
- + .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* Edimax EW-7822UAD */
- + { USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0xb81a, 0xff, 0xff, 0xff),
- + .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* Default ID */
- + { USB_DEVICE_AND_INTERFACE_INFO(0x0b05, 0x1841, 0xff, 0xff, 0xff),
- + .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* ASUS AC1300 USB-AC55 B1 */
- + { USB_DEVICE_AND_INTERFACE_INFO(0x0b05, 0x184c, 0xff, 0xff, 0xff),
- + .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* ASUS U2 */
- + { USB_DEVICE_AND_INTERFACE_INFO(0x0B05, 0x19aa, 0xff, 0xff, 0xff),
- + .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* ASUS - USB-AC58 rev A1 */
- + { USB_DEVICE_AND_INTERFACE_INFO(0x0B05, 0x1870, 0xff, 0xff, 0xff),
- + .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* ASUS */
- + { USB_DEVICE_AND_INTERFACE_INFO(0x0B05, 0x1874, 0xff, 0xff, 0xff),
- + .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* ASUS */
- + { USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x331e, 0xff, 0xff, 0xff),
- + .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* Dlink - DWA-181 */
- + { USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x331c, 0xff, 0xff, 0xff),
- + .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* Dlink - DWA-182 - D1 */
- + {USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x331f, 0xff, 0xff, 0xff),
- + .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec)}, /* Dlink - DWA-183 D Ver */
- + { USB_DEVICE_AND_INTERFACE_INFO(0x13b1, 0x0043, 0xff, 0xff, 0xff),
- + .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* Linksys WUSB6400M */
- + { USB_DEVICE_AND_INTERFACE_INFO(0x13b1, 0x0045, 0xff, 0xff, 0xff),
- + .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* Linksys WUSB3600 v2 */
- + { USB_DEVICE_AND_INTERFACE_INFO(0x2357, 0x012d, 0xff, 0xff, 0xff),
- + .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* TP-Link Archer T3U v1 */
- + { USB_DEVICE_AND_INTERFACE_INFO(0x2357, 0x0138, 0xff, 0xff, 0xff),
- + .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* TP-Link Archer T3U Plus v1 */
- + { USB_DEVICE_AND_INTERFACE_INFO(0x2357, 0x0115, 0xff, 0xff, 0xff),
- + .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* TP-Link Archer T4U V3 */
- + { USB_DEVICE_AND_INTERFACE_INFO(0x2357, 0x012e, 0xff, 0xff, 0xff),
- + .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* TP-LINK */
- + { USB_DEVICE_AND_INTERFACE_INFO(0x2357, 0x0116, 0xff, 0xff, 0xff),
- + .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* TP-LINK */
- + { USB_DEVICE_AND_INTERFACE_INFO(0x2357, 0x0117, 0xff, 0xff, 0xff),
- + .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* TP-LINK */
- + { USB_DEVICE_AND_INTERFACE_INFO(0x0846, 0x9055, 0xff, 0xff, 0xff),
- + .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* Netgear A6150 */
- + { USB_DEVICE_AND_INTERFACE_INFO(0x0e66, 0x0025, 0xff, 0xff, 0xff),
- + .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* Hawking HW12ACU */
- + { USB_DEVICE_AND_INTERFACE_INFO(0x04ca, 0x8602, 0xff, 0xff, 0xff),
- + .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* LiteOn */
- + { USB_DEVICE_AND_INTERFACE_INFO(0x20f4, 0x808a, 0xff, 0xff, 0xff),
- + .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* TRENDnet TEW-808UBM */
- + {},
- +};
- +MODULE_DEVICE_TABLE(usb, rtw_8822bu_id_table);
- +
- +static int rtw8822bu_probe(struct usb_interface *intf,
- + const struct usb_device_id *id)
- +{
- + return rtw_usb_probe(intf, id);
- +}
- +
- +static struct usb_driver rtw_8822bu_driver = {
- + .name = "rtw_8822bu",
- + .id_table = rtw_8822bu_id_table,
- + .probe = rtw8822bu_probe,
- + .disconnect = rtw_usb_disconnect,
- +};
- +module_usb_driver(rtw_8822bu_driver);
- +
- +MODULE_AUTHOR("Realtek Corporation");
- +MODULE_DESCRIPTION("Realtek 802.11ac wireless 8822bu driver");
- +MODULE_LICENSE("Dual BSD/GPL");
- diff -Nurp linux-6.1/drivers/net/wireless/realtek/rtw88/rtw8822c.c linux-6.2/drivers/net/wireless/realtek/rtw88/rtw8822c.c
- --- linux-6.1/drivers/net/wireless/realtek/rtw88/rtw8822c.c 2022-12-12 00:15:18.000000000 +0200
- +++ linux-6.2/drivers/net/wireless/realtek/rtw88/rtw8822c.c 2022-12-24 00:49:25.775376835 +0200
- @@ -29,6 +29,12 @@ static void rtw8822ce_efuse_parsing(stru
- ether_addr_copy(efuse->addr, map->e.mac_addr);
- }
-
- +static void rtw8822cu_efuse_parsing(struct rtw_efuse *efuse,
- + struct rtw8822c_efuse *map)
- +{
- + ether_addr_copy(efuse->addr, map->u.mac_addr);
- +}
- +
- static int rtw8822c_read_efuse(struct rtw_dev *rtwdev, u8 *log_map)
- {
- struct rtw_efuse *efuse = &rtwdev->efuse;
- @@ -58,6 +64,9 @@ static int rtw8822c_read_efuse(struct rt
- case RTW_HCI_TYPE_PCIE:
- rtw8822ce_efuse_parsing(efuse, map);
- break;
- + case RTW_HCI_TYPE_USB:
- + rtw8822cu_efuse_parsing(efuse, map);
- + break;
- default:
- /* unsupported now */
- return -ENOTSUPP;
- @@ -4557,6 +4566,18 @@ static void rtw8822c_adaptivity(struct r
- rtw_phy_set_edcca_th(rtwdev, l2h, h2l);
- }
-
- +static void rtw8822c_fill_txdesc_checksum(struct rtw_dev *rtwdev,
- + struct rtw_tx_pkt_info *pkt_info,
- + u8 *txdesc)
- +{
- + const struct rtw_chip_info *chip = rtwdev->chip;
- + size_t words;
- +
- + words = (pkt_info->pkt_offset * 8 + chip->tx_pkt_desc_sz) / 2;
- +
- + fill_txdesc_checksum_common(txdesc, words);
- +}
- +
- static const struct rtw_pwr_seq_cmd trans_carddis_to_cardemu_8822c[] = {
- {0x0086,
- RTW_PWR_CUT_ALL_MSK,
- @@ -4895,6 +4916,8 @@ static const struct rtw_rfe_def rtw8822c
- [0] = RTW_DEF_RFE(8822c, 0, 0),
- [1] = RTW_DEF_RFE(8822c, 0, 0),
- [2] = RTW_DEF_RFE(8822c, 0, 0),
- + [3] = RTW_DEF_RFE(8822c, 0, 0),
- + [4] = RTW_DEF_RFE(8822c, 0, 0),
- [5] = RTW_DEF_RFE(8822c, 0, 5),
- [6] = RTW_DEF_RFE(8822c, 0, 0),
- };
- @@ -4978,6 +5001,7 @@ static struct rtw_chip_ops rtw8822c_ops
- .cfo_track = rtw8822c_cfo_track,
- .config_tx_path = rtw8822c_config_tx_path,
- .config_txrx_mode = rtw8822c_config_trx_mode,
- + .fill_txdesc_checksum = rtw8822c_fill_txdesc_checksum,
-
- .coex_set_init = rtw8822c_coex_cfg_init,
- .coex_set_ant_switch = NULL,
- diff -Nurp linux-6.1/drivers/net/wireless/realtek/rtw88/rtw8822cu.c linux-6.2/drivers/net/wireless/realtek/rtw88/rtw8822cu.c
- --- linux-6.1/drivers/net/wireless/realtek/rtw88/rtw8822cu.c 1970-01-01 02:00:00.000000000 +0200
- +++ linux-6.2/drivers/net/wireless/realtek/rtw88/rtw8822cu.c 2022-12-24 00:49:25.775376835 +0200
- @@ -0,0 +1,44 @@
- +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
- +/* Copyright(c) 2018-2019 Realtek Corporation
- + */
- +
- +#include <linux/module.h>
- +#include <linux/usb.h>
- +#include "main.h"
- +#include "rtw8822c.h"
- +#include "usb.h"
- +
- +static const struct usb_device_id rtw_8822cu_id_table[] = {
- + { USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0xc82c, 0xff, 0xff, 0xff),
- + .driver_info = (kernel_ulong_t)&(rtw8822c_hw_spec) },
- + { USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0xc812, 0xff, 0xff, 0xff),
- + .driver_info = (kernel_ulong_t)&(rtw8822c_hw_spec) },
- + { USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0xc82e, 0xff, 0xff, 0xff),
- + .driver_info = (kernel_ulong_t)&(rtw8822c_hw_spec) },
- + { USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0xd820, 0xff, 0xff, 0xff),
- + .driver_info = (kernel_ulong_t)&(rtw8822c_hw_spec) },
- + { USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0xd82b, 0xff, 0xff, 0xff),
- + .driver_info = (kernel_ulong_t)&(rtw8822c_hw_spec) },
- + { USB_DEVICE_AND_INTERFACE_INFO(0x13b1, 0x0043, 0xff, 0xff, 0xff),
- + .driver_info = (kernel_ulong_t)&(rtw8822c_hw_spec) }, /* Alpha - Alpha */
- + {},
- +};
- +MODULE_DEVICE_TABLE(usb, rtw_8822cu_id_table);
- +
- +static int rtw8822bu_probe(struct usb_interface *intf,
- + const struct usb_device_id *id)
- +{
- + return rtw_usb_probe(intf, id);
- +}
- +
- +static struct usb_driver rtw_8822cu_driver = {
- + .name = "rtw_8822cu",
- + .id_table = rtw_8822cu_id_table,
- + .probe = rtw8822bu_probe,
- + .disconnect = rtw_usb_disconnect,
- +};
- +module_usb_driver(rtw_8822cu_driver);
- +
- +MODULE_AUTHOR("Realtek Corporation");
- +MODULE_DESCRIPTION("Realtek 802.11ac wireless 8822cu driver");
- +MODULE_LICENSE("Dual BSD/GPL");
- diff -Nurp linux-6.1/drivers/net/wireless/realtek/rtw88/tx.h linux-6.2/drivers/net/wireless/realtek/rtw88/tx.h
- --- linux-6.1/drivers/net/wireless/realtek/rtw88/tx.h 2022-12-12 00:15:18.000000000 +0200
- +++ linux-6.2/drivers/net/wireless/realtek/rtw88/tx.h 2022-12-24 00:49:25.775376835 +0200
- @@ -71,6 +71,14 @@
- le32p_replace_bits((__le32 *)(txdesc) + 0x03, value, BIT(15))
- #define SET_TX_DESC_BT_NULL(txdesc, value) \
- le32p_replace_bits((__le32 *)(txdesc) + 0x02, value, BIT(23))
- +#define SET_TX_DESC_TXDESC_CHECKSUM(txdesc, value) \
- + le32p_replace_bits((__le32 *)(txdesc) + 0x07, value, GENMASK(15, 0))
- +#define SET_TX_DESC_DMA_TXAGG_NUM(txdesc, value) \
- + le32p_replace_bits((__le32 *)(txdesc) + 0x07, value, GENMASK(31, 24))
- +#define GET_TX_DESC_PKT_OFFSET(txdesc) \
- + le32_get_bits(*((__le32 *)(txdesc) + 0x01), GENMASK(28, 24))
- +#define GET_TX_DESC_QSEL(txdesc) \
- + le32_get_bits(*((__le32 *)(txdesc) + 0x01), GENMASK(12, 8))
-
- enum rtw_tx_desc_queue_select {
- TX_DESC_QSEL_TID0 = 0,
- @@ -123,4 +131,27 @@ rtw_tx_write_data_h2c_get(struct rtw_dev
- struct rtw_tx_pkt_info *pkt_info,
- u8 *buf, u32 size);
-
- +static inline
- +void fill_txdesc_checksum_common(u8 *txdesc, size_t words)
- +{
- + __le16 chksum = 0;
- + __le16 *data = (__le16 *)(txdesc);
- +
- + SET_TX_DESC_TXDESC_CHECKSUM(txdesc, 0x0000);
- +
- + while (words--)
- + chksum ^= *data++;
- +
- + SET_TX_DESC_TXDESC_CHECKSUM(txdesc, __le16_to_cpu(chksum));
- +}
- +
- +static inline void rtw_tx_fill_txdesc_checksum(struct rtw_dev *rtwdev,
- + struct rtw_tx_pkt_info *pkt_info,
- + u8 *txdesc)
- +{
- + const struct rtw_chip_info *chip = rtwdev->chip;
- +
- + chip->ops->fill_txdesc_checksum(rtwdev, pkt_info, txdesc);
- +}
- +
- #endif
- diff -Nurp linux-6.1/drivers/net/wireless/realtek/rtw88/usb.c linux-6.2/drivers/net/wireless/realtek/rtw88/usb.c
- --- linux-6.1/drivers/net/wireless/realtek/rtw88/usb.c 1970-01-01 02:00:00.000000000 +0200
- +++ linux-6.2/drivers/net/wireless/realtek/rtw88/usb.c 2022-12-24 00:49:25.775376835 +0200
- @@ -0,0 +1,911 @@
- +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
- +/* Copyright(c) 2018-2019 Realtek Corporation
- + */
- +
- +#include <linux/module.h>
- +#include <linux/usb.h>
- +#include <linux/mutex.h>
- +#include "main.h"
- +#include "debug.h"
- +#include "reg.h"
- +#include "tx.h"
- +#include "rx.h"
- +#include "fw.h"
- +#include "ps.h"
- +#include "usb.h"
- +
- +#define RTW_USB_MAX_RXQ_LEN 512
- +
- +struct rtw_usb_txcb {
- + struct rtw_dev *rtwdev;
- + struct sk_buff_head tx_ack_queue;
- +};
- +
- +static void rtw_usb_fill_tx_checksum(struct rtw_usb *rtwusb,
- + struct sk_buff *skb, int agg_num)
- +{
- + struct rtw_dev *rtwdev = rtwusb->rtwdev;
- + struct rtw_tx_pkt_info pkt_info;
- +
- + SET_TX_DESC_DMA_TXAGG_NUM(skb->data, agg_num);
- + pkt_info.pkt_offset = GET_TX_DESC_PKT_OFFSET(skb->data);
- + rtw_tx_fill_txdesc_checksum(rtwdev, &pkt_info, skb->data);
- +}
- +
- +static u32 rtw_usb_read(struct rtw_dev *rtwdev, u32 addr, u16 len)
- +{
- + struct rtw_usb *rtwusb = rtw_get_usb_priv(rtwdev);
- + struct usb_device *udev = rtwusb->udev;
- + __le32 *data;
- + unsigned long flags;
- + int idx, ret;
- + static int count;
- +
- + spin_lock_irqsave(&rtwusb->usb_lock, flags);
- +
- + idx = rtwusb->usb_data_index;
- + rtwusb->usb_data_index = (idx + 1) & (RTW_USB_MAX_RXTX_COUNT - 1);
- +
- + spin_unlock_irqrestore(&rtwusb->usb_lock, flags);
- +
- + data = &rtwusb->usb_data[idx];
- +
- + ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
- + RTW_USB_CMD_REQ, RTW_USB_CMD_READ, addr,
- + RTW_USB_VENQT_CMD_IDX, data, len, 1000);
- + if (ret < 0 && ret != -ENODEV && count++ < 4)
- + rtw_err(rtwdev, "read register 0x%x failed with %d\n",
- + addr, ret);
- +
- + return le32_to_cpu(*data);
- +}
- +
- +static u8 rtw_usb_read8(struct rtw_dev *rtwdev, u32 addr)
- +{
- + return (u8)rtw_usb_read(rtwdev, addr, 1);
- +}
- +
- +static u16 rtw_usb_read16(struct rtw_dev *rtwdev, u32 addr)
- +{
- + return (u16)rtw_usb_read(rtwdev, addr, 2);
- +}
- +
- +static u32 rtw_usb_read32(struct rtw_dev *rtwdev, u32 addr)
- +{
- + return (u32)rtw_usb_read(rtwdev, addr, 4);
- +}
- +
- +static void rtw_usb_write(struct rtw_dev *rtwdev, u32 addr, u32 val, int len)
- +{
- + struct rtw_usb *rtwusb = (struct rtw_usb *)rtwdev->priv;
- + struct usb_device *udev = rtwusb->udev;
- + unsigned long flags;
- + __le32 *data;
- + int idx, ret;
- + static int count;
- +
- + spin_lock_irqsave(&rtwusb->usb_lock, flags);
- +
- + idx = rtwusb->usb_data_index;
- + rtwusb->usb_data_index = (idx + 1) & (RTW_USB_MAX_RXTX_COUNT - 1);
- +
- + spin_unlock_irqrestore(&rtwusb->usb_lock, flags);
- +
- + data = &rtwusb->usb_data[idx];
- +
- + *data = cpu_to_le32(val);
- +
- + ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
- + RTW_USB_CMD_REQ, RTW_USB_CMD_WRITE,
- + addr, 0, data, len, 30000);
- + if (ret < 0 && ret != -ENODEV && count++ < 4)
- + rtw_err(rtwdev, "write register 0x%x failed with %d\n",
- + addr, ret);
- +}
- +
- +static void rtw_usb_write8(struct rtw_dev *rtwdev, u32 addr, u8 val)
- +{
- + rtw_usb_write(rtwdev, addr, val, 1);
- +}
- +
- +static void rtw_usb_write16(struct rtw_dev *rtwdev, u32 addr, u16 val)
- +{
- + rtw_usb_write(rtwdev, addr, val, 2);
- +}
- +
- +static void rtw_usb_write32(struct rtw_dev *rtwdev, u32 addr, u32 val)
- +{
- + rtw_usb_write(rtwdev, addr, val, 4);
- +}
- +
- +static int rtw_usb_parse(struct rtw_dev *rtwdev,
- + struct usb_interface *interface)
- +{
- + struct rtw_usb *rtwusb = rtw_get_usb_priv(rtwdev);
- + struct usb_host_interface *host_interface = &interface->altsetting[0];
- + struct usb_interface_descriptor *interface_desc = &host_interface->desc;
- + struct usb_endpoint_descriptor *endpoint;
- + struct usb_device *usbd = interface_to_usbdev(interface);
- + int num_out_pipes = 0;
- + int i;
- + u8 num;
- +
- + for (i = 0; i < interface_desc->bNumEndpoints; i++) {
- + endpoint = &host_interface->endpoint[i].desc;
- + num = usb_endpoint_num(endpoint);
- +
- + if (usb_endpoint_dir_in(endpoint) &&
- + usb_endpoint_xfer_bulk(endpoint)) {
- + if (rtwusb->pipe_in) {
- + rtw_err(rtwdev, "IN pipes overflow\n");
- + return -EINVAL;
- + }
- +
- + rtwusb->pipe_in = num;
- + }
- +
- + if (usb_endpoint_dir_in(endpoint) &&
- + usb_endpoint_xfer_int(endpoint)) {
- + if (rtwusb->pipe_interrupt) {
- + rtw_err(rtwdev, "INT pipes overflow\n");
- + return -EINVAL;
- + }
- +
- + rtwusb->pipe_interrupt = num;
- + }
- +
- + if (usb_endpoint_dir_out(endpoint) &&
- + usb_endpoint_xfer_bulk(endpoint)) {
- + if (num_out_pipes >= ARRAY_SIZE(rtwusb->out_ep)) {
- + rtw_err(rtwdev, "OUT pipes overflow\n");
- + return -EINVAL;
- + }
- +
- + rtwusb->out_ep[num_out_pipes++] = num;
- + }
- + }
- +
- + switch (usbd->speed) {
- + case USB_SPEED_LOW:
- + case USB_SPEED_FULL:
- + rtwusb->bulkout_size = RTW_USB_FULL_SPEED_BULK_SIZE;
- + break;
- + case USB_SPEED_HIGH:
- + rtwusb->bulkout_size = RTW_USB_HIGH_SPEED_BULK_SIZE;
- + break;
- + case USB_SPEED_SUPER:
- + rtwusb->bulkout_size = RTW_USB_SUPER_SPEED_BULK_SIZE;
- + break;
- + default:
- + rtw_err(rtwdev, "failed to detect usb speed\n");
- + return -EINVAL;
- + }
- +
- + rtwdev->hci.bulkout_num = num_out_pipes;
- +
- + switch (num_out_pipes) {
- + case 4:
- + case 3:
- + rtwusb->qsel_to_ep[TX_DESC_QSEL_TID0] = 2;
- + rtwusb->qsel_to_ep[TX_DESC_QSEL_TID1] = 2;
- + rtwusb->qsel_to_ep[TX_DESC_QSEL_TID2] = 2;
- + rtwusb->qsel_to_ep[TX_DESC_QSEL_TID3] = 2;
- + rtwusb->qsel_to_ep[TX_DESC_QSEL_TID4] = 1;
- + rtwusb->qsel_to_ep[TX_DESC_QSEL_TID5] = 1;
- + rtwusb->qsel_to_ep[TX_DESC_QSEL_TID6] = 0;
- + rtwusb->qsel_to_ep[TX_DESC_QSEL_TID7] = 0;
- + break;
- + case 2:
- + rtwusb->qsel_to_ep[TX_DESC_QSEL_TID0] = 1;
- + rtwusb->qsel_to_ep[TX_DESC_QSEL_TID1] = 1;
- + rtwusb->qsel_to_ep[TX_DESC_QSEL_TID2] = 1;
- + rtwusb->qsel_to_ep[TX_DESC_QSEL_TID3] = 1;
- + break;
- + case 1:
- + break;
- + default:
- + rtw_err(rtwdev, "failed to get out_pipes(%d)\n", num_out_pipes);
- + return -EINVAL;
- + }
- +
- + return 0;
- +}
- +
- +static void rtw_usb_write_port_tx_complete(struct urb *urb)
- +{
- + struct rtw_usb_txcb *txcb = urb->context;
- + struct rtw_dev *rtwdev = txcb->rtwdev;
- + struct ieee80211_hw *hw = rtwdev->hw;
- +
- + while (true) {
- + struct sk_buff *skb = skb_dequeue(&txcb->tx_ack_queue);
- + struct ieee80211_tx_info *info;
- + struct rtw_usb_tx_data *tx_data;
- +
- + if (!skb)
- + break;
- +
- + info = IEEE80211_SKB_CB(skb);
- + tx_data = rtw_usb_get_tx_data(skb);
- +
- + /* enqueue to wait for tx report */
- + if (info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS) {
- + rtw_tx_report_enqueue(rtwdev, skb, tx_data->sn);
- + continue;
- + }
- +
- + /* always ACK for others, then they won't be marked as drop */
- + ieee80211_tx_info_clear_status(info);
- + if (info->flags & IEEE80211_TX_CTL_NO_ACK)
- + info->flags |= IEEE80211_TX_STAT_NOACK_TRANSMITTED;
- + else
- + info->flags |= IEEE80211_TX_STAT_ACK;
- +
- + ieee80211_tx_status_irqsafe(hw, skb);
- + }
- +
- + kfree(txcb);
- +}
- +
- +static int qsel_to_ep(struct rtw_usb *rtwusb, unsigned int qsel)
- +{
- + if (qsel >= ARRAY_SIZE(rtwusb->qsel_to_ep))
- + return 0;
- +
- + return rtwusb->qsel_to_ep[qsel];
- +}
- +
- +static int rtw_usb_write_port(struct rtw_dev *rtwdev, u8 qsel, struct sk_buff *skb,
- + usb_complete_t cb, void *context)
- +{
- + struct rtw_usb *rtwusb = rtw_get_usb_priv(rtwdev);
- + struct usb_device *usbd = rtwusb->udev;
- + struct urb *urb;
- + unsigned int pipe;
- + int ret;
- + int ep = qsel_to_ep(rtwusb, qsel);
- +
- + pipe = usb_sndbulkpipe(usbd, rtwusb->out_ep[ep]);
- + urb = usb_alloc_urb(0, GFP_ATOMIC);
- + if (!urb)
- + return -ENOMEM;
- +
- + usb_fill_bulk_urb(urb, usbd, pipe, skb->data, skb->len, cb, context);
- + ret = usb_submit_urb(urb, GFP_ATOMIC);
- +
- + usb_free_urb(urb);
- +
- + return ret;
- +}
- +
- +static bool rtw_usb_tx_agg_skb(struct rtw_usb *rtwusb, struct sk_buff_head *list)
- +{
- + struct rtw_dev *rtwdev = rtwusb->rtwdev;
- + struct rtw_usb_txcb *txcb;
- + struct sk_buff *skb_head;
- + struct sk_buff *skb_iter;
- + int agg_num = 0;
- + unsigned int align_next = 0;
- +
- + if (skb_queue_empty(list))
- + return false;
- +
- + txcb = kmalloc(sizeof(*txcb), GFP_ATOMIC);
- + if (!txcb)
- + return false;
- +
- + txcb->rtwdev = rtwdev;
- + skb_queue_head_init(&txcb->tx_ack_queue);
- +
- + skb_iter = skb_dequeue(list);
- +
- + if (skb_queue_empty(list)) {
- + skb_head = skb_iter;
- + goto queue;
- + }
- +
- + skb_head = dev_alloc_skb(RTW_USB_MAX_XMITBUF_SZ);
- + if (!skb_head) {
- + skb_head = skb_iter;
- + goto queue;
- + }
- +
- + while (skb_iter) {
- + unsigned long flags;
- +
- + skb_put(skb_head, align_next);
- + skb_put_data(skb_head, skb_iter->data, skb_iter->len);
- +
- + align_next = ALIGN(skb_iter->len, 8) - skb_iter->len;
- +
- + agg_num++;
- +
- + skb_queue_tail(&txcb->tx_ack_queue, skb_iter);
- +
- + spin_lock_irqsave(&list->lock, flags);
- +
- + skb_iter = skb_peek(list);
- +
- + if (skb_iter && skb_iter->len + skb_head->len <= RTW_USB_MAX_XMITBUF_SZ)
- + __skb_unlink(skb_iter, list);
- + else
- + skb_iter = NULL;
- + spin_unlock_irqrestore(&list->lock, flags);
- + }
- +
- + if (agg_num > 1)
- + rtw_usb_fill_tx_checksum(rtwusb, skb_head, agg_num);
- +
- +queue:
- + skb_queue_tail(&txcb->tx_ack_queue, skb_head);
- +
- + rtw_usb_write_port(rtwdev, GET_TX_DESC_QSEL(skb_head->data), skb_head,
- + rtw_usb_write_port_tx_complete, txcb);
- +
- + return true;
- +}
- +
- +static void rtw_usb_tx_handler(struct work_struct *work)
- +{
- + struct rtw_usb *rtwusb = container_of(work, struct rtw_usb, tx_work);
- + int i, limit;
- +
- + for (i = ARRAY_SIZE(rtwusb->tx_queue) - 1; i >= 0; i--) {
- + for (limit = 0; limit < 200; limit++) {
- + struct sk_buff_head *list = &rtwusb->tx_queue[i];
- +
- + if (!rtw_usb_tx_agg_skb(rtwusb, list))
- + break;
- + }
- + }
- +}
- +
- +static void rtw_usb_tx_queue_purge(struct rtw_usb *rtwusb)
- +{
- + int i;
- +
- + for (i = 0; i < ARRAY_SIZE(rtwusb->tx_queue); i++)
- + skb_queue_purge(&rtwusb->tx_queue[i]);
- +}
- +
- +static void rtw_usb_write_port_complete(struct urb *urb)
- +{
- + struct sk_buff *skb = urb->context;
- +
- + dev_kfree_skb_any(skb);
- +}
- +
- +static int rtw_usb_write_data(struct rtw_dev *rtwdev,
- + struct rtw_tx_pkt_info *pkt_info,
- + u8 *buf)
- +{
- + const struct rtw_chip_info *chip = rtwdev->chip;
- + struct sk_buff *skb;
- + unsigned int desclen, headsize, size;
- + u8 qsel;
- + int ret = 0;
- +
- + size = pkt_info->tx_pkt_size;
- + qsel = pkt_info->qsel;
- + desclen = chip->tx_pkt_desc_sz;
- + headsize = pkt_info->offset ? pkt_info->offset : desclen;
- +
- + skb = dev_alloc_skb(headsize + size);
- + if (unlikely(!skb))
- + return -ENOMEM;
- +
- + skb_reserve(skb, headsize);
- + skb_put_data(skb, buf, size);
- + skb_push(skb, headsize);
- + memset(skb->data, 0, headsize);
- + rtw_tx_fill_tx_desc(pkt_info, skb);
- + rtw_tx_fill_txdesc_checksum(rtwdev, pkt_info, skb->data);
- +
- + ret = rtw_usb_write_port(rtwdev, qsel, skb,
- + rtw_usb_write_port_complete, skb);
- + if (unlikely(ret))
- + rtw_err(rtwdev, "failed to do USB write, ret=%d\n", ret);
- +
- + return ret;
- +}
- +
- +static int rtw_usb_write_data_rsvd_page(struct rtw_dev *rtwdev, u8 *buf,
- + u32 size)
- +{
- + const struct rtw_chip_info *chip = rtwdev->chip;
- + struct rtw_usb *rtwusb;
- + struct rtw_tx_pkt_info pkt_info = {0};
- + u32 len, desclen;
- +
- + rtwusb = rtw_get_usb_priv(rtwdev);
- +
- + pkt_info.tx_pkt_size = size;
- + pkt_info.qsel = TX_DESC_QSEL_BEACON;
- +
- + desclen = chip->tx_pkt_desc_sz;
- + len = desclen + size;
- + if (len % rtwusb->bulkout_size == 0) {
- + len += RTW_USB_PACKET_OFFSET_SZ;
- + pkt_info.offset = desclen + RTW_USB_PACKET_OFFSET_SZ;
- + pkt_info.pkt_offset = 1;
- + } else {
- + pkt_info.offset = desclen;
- + }
- +
- + return rtw_usb_write_data(rtwdev, &pkt_info, buf);
- +}
- +
- +static int rtw_usb_write_data_h2c(struct rtw_dev *rtwdev, u8 *buf, u32 size)
- +{
- + struct rtw_tx_pkt_info pkt_info = {0};
- +
- + pkt_info.tx_pkt_size = size;
- + pkt_info.qsel = TX_DESC_QSEL_H2C;
- +
- + return rtw_usb_write_data(rtwdev, &pkt_info, buf);
- +}
- +
- +static u8 rtw_usb_tx_queue_mapping_to_qsel(struct sk_buff *skb)
- +{
- + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
- + __le16 fc = hdr->frame_control;
- + u8 qsel;
- +
- + if (unlikely(ieee80211_is_mgmt(fc) || ieee80211_is_ctl(fc)))
- + qsel = TX_DESC_QSEL_MGMT;
- + else if (skb_get_queue_mapping(skb) <= IEEE80211_AC_BK)
- + qsel = skb->priority;
- + else
- + qsel = TX_DESC_QSEL_BEACON;
- +
- + return qsel;
- +}
- +
- +static int rtw_usb_tx_write(struct rtw_dev *rtwdev,
- + struct rtw_tx_pkt_info *pkt_info,
- + struct sk_buff *skb)
- +{
- + struct rtw_usb *rtwusb = rtw_get_usb_priv(rtwdev);
- + const struct rtw_chip_info *chip = rtwdev->chip;
- + struct rtw_usb_tx_data *tx_data;
- + u8 *pkt_desc;
- + int ep;
- +
- + pkt_desc = skb_push(skb, chip->tx_pkt_desc_sz);
- + memset(pkt_desc, 0, chip->tx_pkt_desc_sz);
- + pkt_info->qsel = rtw_usb_tx_queue_mapping_to_qsel(skb);
- + ep = qsel_to_ep(rtwusb, pkt_info->qsel);
- + rtw_tx_fill_tx_desc(pkt_info, skb);
- + rtw_tx_fill_txdesc_checksum(rtwdev, pkt_info, skb->data);
- + tx_data = rtw_usb_get_tx_data(skb);
- + tx_data->sn = pkt_info->sn;
- +
- + skb_queue_tail(&rtwusb->tx_queue[ep], skb);
- +
- + return 0;
- +}
- +
- +static void rtw_usb_tx_kick_off(struct rtw_dev *rtwdev)
- +{
- + struct rtw_usb *rtwusb = rtw_get_usb_priv(rtwdev);
- +
- + queue_work(rtwusb->txwq, &rtwusb->tx_work);
- +}
- +
- +static void rtw_usb_rx_handler(struct work_struct *work)
- +{
- + struct rtw_usb *rtwusb = container_of(work, struct rtw_usb, rx_work);
- + struct rtw_dev *rtwdev = rtwusb->rtwdev;
- + const struct rtw_chip_info *chip = rtwdev->chip;
- + struct rtw_rx_pkt_stat pkt_stat;
- + struct ieee80211_rx_status rx_status;
- + struct sk_buff *skb;
- + u32 pkt_desc_sz = chip->rx_pkt_desc_sz;
- + u32 pkt_offset;
- + u8 *rx_desc;
- + int limit;
- +
- + for (limit = 0; limit < 200; limit++) {
- + skb = skb_dequeue(&rtwusb->rx_queue);
- + if (!skb)
- + break;
- +
- + rx_desc = skb->data;
- + chip->ops->query_rx_desc(rtwdev, rx_desc, &pkt_stat,
- + &rx_status);
- + pkt_offset = pkt_desc_sz + pkt_stat.drv_info_sz +
- + pkt_stat.shift;
- +
- + if (pkt_stat.is_c2h) {
- + skb_put(skb, pkt_stat.pkt_len + pkt_offset);
- + rtw_fw_c2h_cmd_rx_irqsafe(rtwdev, pkt_offset, skb);
- + continue;
- + }
- +
- + if (skb_queue_len(&rtwusb->rx_queue) >= RTW_USB_MAX_RXQ_LEN) {
- + rtw_err(rtwdev, "failed to get rx_queue, overflow\n");
- + dev_kfree_skb_any(skb);
- + continue;
- + }
- +
- + skb_put(skb, pkt_stat.pkt_len);
- + skb_reserve(skb, pkt_offset);
- + memcpy(skb->cb, &rx_status, sizeof(rx_status));
- + ieee80211_rx_irqsafe(rtwdev->hw, skb);
- + }
- +}
- +
- +static void rtw_usb_read_port_complete(struct urb *urb);
- +
- +static void rtw_usb_rx_resubmit(struct rtw_usb *rtwusb, struct rx_usb_ctrl_block *rxcb)
- +{
- + struct rtw_dev *rtwdev = rtwusb->rtwdev;
- + int error;
- +
- + rxcb->rx_skb = alloc_skb(RTW_USB_MAX_RECVBUF_SZ, GFP_ATOMIC);
- + if (!rxcb->rx_skb)
- + return;
- +
- + usb_fill_bulk_urb(rxcb->rx_urb, rtwusb->udev,
- + usb_rcvbulkpipe(rtwusb->udev, rtwusb->pipe_in),
- + rxcb->rx_skb->data, RTW_USB_MAX_RECVBUF_SZ,
- + rtw_usb_read_port_complete, rxcb);
- +
- + error = usb_submit_urb(rxcb->rx_urb, GFP_ATOMIC);
- + if (error) {
- + kfree_skb(rxcb->rx_skb);
- + if (error != -ENODEV)
- + rtw_err(rtwdev, "Err sending rx data urb %d\n",
- + error);
- + }
- +}
- +
- +static void rtw_usb_read_port_complete(struct urb *urb)
- +{
- + struct rx_usb_ctrl_block *rxcb = urb->context;
- + struct rtw_dev *rtwdev = rxcb->rtwdev;
- + struct rtw_usb *rtwusb = rtw_get_usb_priv(rtwdev);
- + struct sk_buff *skb = rxcb->rx_skb;
- +
- + if (urb->status == 0) {
- + if (urb->actual_length >= RTW_USB_MAX_RECVBUF_SZ ||
- + urb->actual_length < 24) {
- + rtw_err(rtwdev, "failed to get urb length:%d\n",
- + urb->actual_length);
- + if (skb)
- + dev_kfree_skb_any(skb);
- + } else {
- + skb_queue_tail(&rtwusb->rx_queue, skb);
- + queue_work(rtwusb->rxwq, &rtwusb->rx_work);
- + }
- + rtw_usb_rx_resubmit(rtwusb, rxcb);
- + } else {
- + switch (urb->status) {
- + case -EINVAL:
- + case -EPIPE:
- + case -ENODEV:
- + case -ESHUTDOWN:
- + case -ENOENT:
- + case -EPROTO:
- + case -EILSEQ:
- + case -ETIME:
- + case -ECOMM:
- + case -EOVERFLOW:
- + case -EINPROGRESS:
- + break;
- + default:
- + rtw_err(rtwdev, "status %d\n", urb->status);
- + break;
- + }
- + if (skb)
- + dev_kfree_skb_any(skb);
- + }
- +}
- +
- +static void rtw_usb_cancel_rx_bufs(struct rtw_usb *rtwusb)
- +{
- + struct rx_usb_ctrl_block *rxcb;
- + int i;
- +
- + for (i = 0; i < RTW_USB_RXCB_NUM; i++) {
- + rxcb = &rtwusb->rx_cb[i];
- + if (rxcb->rx_urb)
- + usb_kill_urb(rxcb->rx_urb);
- + }
- +}
- +
- +static void rtw_usb_free_rx_bufs(struct rtw_usb *rtwusb)
- +{
- + struct rx_usb_ctrl_block *rxcb;
- + int i;
- +
- + for (i = 0; i < RTW_USB_RXCB_NUM; i++) {
- + rxcb = &rtwusb->rx_cb[i];
- + if (rxcb->rx_urb) {
- + usb_kill_urb(rxcb->rx_urb);
- + usb_free_urb(rxcb->rx_urb);
- + }
- + }
- +}
- +
- +static int rtw_usb_alloc_rx_bufs(struct rtw_usb *rtwusb)
- +{
- + int i;
- +
- + for (i = 0; i < RTW_USB_RXCB_NUM; i++) {
- + struct rx_usb_ctrl_block *rxcb = &rtwusb->rx_cb[i];
- +
- + rxcb->n = i;
- + rxcb->rtwdev = rtwusb->rtwdev;
- + rxcb->rx_urb = usb_alloc_urb(0, GFP_KERNEL);
- + if (!rxcb->rx_urb)
- + goto err;
- + }
- +
- + return 0;
- +err:
- + rtw_usb_free_rx_bufs(rtwusb);
- + return -ENOMEM;
- +}
- +
- +static int rtw_usb_setup(struct rtw_dev *rtwdev)
- +{
- + /* empty function for rtw_hci_ops */
- + return 0;
- +}
- +
- +static int rtw_usb_start(struct rtw_dev *rtwdev)
- +{
- + return 0;
- +}
- +
- +static void rtw_usb_stop(struct rtw_dev *rtwdev)
- +{
- +}
- +
- +static void rtw_usb_deep_ps(struct rtw_dev *rtwdev, bool enter)
- +{
- + /* empty function for rtw_hci_ops */
- +}
- +
- +static void rtw_usb_link_ps(struct rtw_dev *rtwdev, bool enter)
- +{
- + /* empty function for rtw_hci_ops */
- +}
- +
- +static void rtw_usb_interface_cfg(struct rtw_dev *rtwdev)
- +{
- + /* empty function for rtw_hci_ops */
- +}
- +
- +static struct rtw_hci_ops rtw_usb_ops = {
- + .tx_write = rtw_usb_tx_write,
- + .tx_kick_off = rtw_usb_tx_kick_off,
- + .setup = rtw_usb_setup,
- + .start = rtw_usb_start,
- + .stop = rtw_usb_stop,
- + .deep_ps = rtw_usb_deep_ps,
- + .link_ps = rtw_usb_link_ps,
- + .interface_cfg = rtw_usb_interface_cfg,
- +
- + .write8 = rtw_usb_write8,
- + .write16 = rtw_usb_write16,
- + .write32 = rtw_usb_write32,
- + .read8 = rtw_usb_read8,
- + .read16 = rtw_usb_read16,
- + .read32 = rtw_usb_read32,
- +
- + .write_data_rsvd_page = rtw_usb_write_data_rsvd_page,
- + .write_data_h2c = rtw_usb_write_data_h2c,
- +};
- +
- +static int rtw_usb_init_rx(struct rtw_dev *rtwdev)
- +{
- + struct rtw_usb *rtwusb = rtw_get_usb_priv(rtwdev);
- + int i;
- +
- + rtwusb->rxwq = create_singlethread_workqueue("rtw88_usb: rx wq");
- + if (!rtwusb->rxwq) {
- + rtw_err(rtwdev, "failed to create RX work queue\n");
- + return -ENOMEM;
- + }
- +
- + skb_queue_head_init(&rtwusb->rx_queue);
- +
- + INIT_WORK(&rtwusb->rx_work, rtw_usb_rx_handler);
- +
- + for (i = 0; i < RTW_USB_RXCB_NUM; i++) {
- + struct rx_usb_ctrl_block *rxcb = &rtwusb->rx_cb[i];
- +
- + rtw_usb_rx_resubmit(rtwusb, rxcb);
- + }
- +
- + return 0;
- +}
- +
- +static void rtw_usb_deinit_rx(struct rtw_dev *rtwdev)
- +{
- + struct rtw_usb *rtwusb = rtw_get_usb_priv(rtwdev);
- +
- + skb_queue_purge(&rtwusb->rx_queue);
- +
- + flush_workqueue(rtwusb->rxwq);
- + destroy_workqueue(rtwusb->rxwq);
- +}
- +
- +static int rtw_usb_init_tx(struct rtw_dev *rtwdev)
- +{
- + struct rtw_usb *rtwusb = rtw_get_usb_priv(rtwdev);
- + int i;
- +
- + rtwusb->txwq = create_singlethread_workqueue("rtw88_usb: tx wq");
- + if (!rtwusb->txwq) {
- + rtw_err(rtwdev, "failed to create TX work queue\n");
- + return -ENOMEM;
- + }
- +
- + for (i = 0; i < ARRAY_SIZE(rtwusb->tx_queue); i++)
- + skb_queue_head_init(&rtwusb->tx_queue[i]);
- +
- + INIT_WORK(&rtwusb->tx_work, rtw_usb_tx_handler);
- +
- + return 0;
- +}
- +
- +static void rtw_usb_deinit_tx(struct rtw_dev *rtwdev)
- +{
- + struct rtw_usb *rtwusb = rtw_get_usb_priv(rtwdev);
- +
- + rtw_usb_tx_queue_purge(rtwusb);
- + flush_workqueue(rtwusb->txwq);
- + destroy_workqueue(rtwusb->txwq);
- +}
- +
- +static int rtw_usb_intf_init(struct rtw_dev *rtwdev,
- + struct usb_interface *intf)
- +{
- + struct rtw_usb *rtwusb = rtw_get_usb_priv(rtwdev);
- + struct usb_device *udev = usb_get_dev(interface_to_usbdev(intf));
- + int ret;
- +
- + rtwusb->udev = udev;
- + ret = rtw_usb_parse(rtwdev, intf);
- + if (ret)
- + return ret;
- +
- + rtwusb->usb_data = kcalloc(RTW_USB_MAX_RXTX_COUNT, sizeof(u32),
- + GFP_KERNEL);
- + if (!rtwusb->usb_data)
- + return -ENOMEM;
- +
- + usb_set_intfdata(intf, rtwdev->hw);
- +
- + SET_IEEE80211_DEV(rtwdev->hw, &intf->dev);
- + spin_lock_init(&rtwusb->usb_lock);
- +
- + return 0;
- +}
- +
- +static void rtw_usb_intf_deinit(struct rtw_dev *rtwdev,
- + struct usb_interface *intf)
- +{
- + struct rtw_usb *rtwusb = rtw_get_usb_priv(rtwdev);
- +
- + usb_put_dev(rtwusb->udev);
- + usb_set_intfdata(intf, NULL);
- +}
- +
- +int rtw_usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
- +{
- + struct rtw_dev *rtwdev;
- + struct ieee80211_hw *hw;
- + struct rtw_usb *rtwusb;
- + int drv_data_size;
- + int ret;
- +
- + drv_data_size = sizeof(struct rtw_dev) + sizeof(struct rtw_usb);
- + hw = ieee80211_alloc_hw(drv_data_size, &rtw_ops);
- + if (!hw)
- + return -ENOMEM;
- +
- + rtwdev = hw->priv;
- + rtwdev->hw = hw;
- + rtwdev->dev = &intf->dev;
- + rtwdev->chip = (struct rtw_chip_info *)id->driver_info;
- + rtwdev->hci.ops = &rtw_usb_ops;
- + rtwdev->hci.type = RTW_HCI_TYPE_USB;
- +
- + rtwusb = rtw_get_usb_priv(rtwdev);
- + rtwusb->rtwdev = rtwdev;
- +
- + ret = rtw_usb_alloc_rx_bufs(rtwusb);
- + if (ret)
- + return ret;
- +
- + ret = rtw_core_init(rtwdev);
- + if (ret)
- + goto err_release_hw;
- +
- + ret = rtw_usb_intf_init(rtwdev, intf);
- + if (ret) {
- + rtw_err(rtwdev, "failed to init USB interface\n");
- + goto err_deinit_core;
- + }
- +
- + ret = rtw_usb_init_tx(rtwdev);
- + if (ret) {
- + rtw_err(rtwdev, "failed to init USB TX\n");
- + goto err_destroy_usb;
- + }
- +
- + ret = rtw_usb_init_rx(rtwdev);
- + if (ret) {
- + rtw_err(rtwdev, "failed to init USB RX\n");
- + goto err_destroy_txwq;
- + }
- +
- + ret = rtw_chip_info_setup(rtwdev);
- + if (ret) {
- + rtw_err(rtwdev, "failed to setup chip information\n");
- + goto err_destroy_rxwq;
- + }
- +
- + ret = rtw_register_hw(rtwdev, rtwdev->hw);
- + if (ret) {
- + rtw_err(rtwdev, "failed to register hw\n");
- + goto err_destroy_rxwq;
- + }
- +
- + return 0;
- +
- +err_destroy_rxwq:
- + rtw_usb_deinit_rx(rtwdev);
- +
- +err_destroy_txwq:
- + rtw_usb_deinit_tx(rtwdev);
- +
- +err_destroy_usb:
- + rtw_usb_intf_deinit(rtwdev, intf);
- +
- +err_deinit_core:
- + rtw_core_deinit(rtwdev);
- +
- +err_release_hw:
- + ieee80211_free_hw(hw);
- +
- + return ret;
- +}
- +EXPORT_SYMBOL(rtw_usb_probe);
- +
- +void rtw_usb_disconnect(struct usb_interface *intf)
- +{
- + struct ieee80211_hw *hw = usb_get_intfdata(intf);
- + struct rtw_dev *rtwdev;
- + struct rtw_usb *rtwusb;
- +
- + if (!hw)
- + return;
- +
- + rtwdev = hw->priv;
- + rtwusb = rtw_get_usb_priv(rtwdev);
- +
- + rtw_usb_cancel_rx_bufs(rtwusb);
- +
- + rtw_unregister_hw(rtwdev, hw);
- + rtw_usb_deinit_tx(rtwdev);
- + rtw_usb_deinit_rx(rtwdev);
- +
- + if (rtwusb->udev->state != USB_STATE_NOTATTACHED)
- + usb_reset_device(rtwusb->udev);
- +
- + rtw_usb_free_rx_bufs(rtwusb);
- +
- + rtw_usb_intf_deinit(rtwdev, intf);
- + rtw_core_deinit(rtwdev);
- + ieee80211_free_hw(hw);
- +}
- +EXPORT_SYMBOL(rtw_usb_disconnect);
- +
- +MODULE_AUTHOR("Realtek Corporation");
- +MODULE_DESCRIPTION("Realtek 802.11ac wireless USB driver");
- +MODULE_LICENSE("Dual BSD/GPL");
- diff -Nurp linux-6.1/drivers/net/wireless/realtek/rtw88/usb.h linux-6.2/drivers/net/wireless/realtek/rtw88/usb.h
- --- linux-6.1/drivers/net/wireless/realtek/rtw88/usb.h 1970-01-01 02:00:00.000000000 +0200
- +++ linux-6.2/drivers/net/wireless/realtek/rtw88/usb.h 2022-12-24 00:49:25.775376835 +0200
- @@ -0,0 +1,107 @@
- +/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
- +/* Copyright(c) 2018-2019 Realtek Corporation
- + */
- +
- +#ifndef __RTW_USB_H_
- +#define __RTW_USB_H_
- +
- +#define FW_8192C_START_ADDRESS 0x1000
- +#define FW_8192C_END_ADDRESS 0x5fff
- +
- +#define RTW_USB_MAX_RXTX_COUNT 128
- +#define RTW_USB_VENQT_MAX_BUF_SIZE 254
- +#define MAX_USBCTRL_VENDORREQ_TIMES 10
- +
- +#define RTW_USB_CMD_READ 0xc0
- +#define RTW_USB_CMD_WRITE 0x40
- +#define RTW_USB_CMD_REQ 0x05
- +
- +#define RTW_USB_VENQT_CMD_IDX 0x00
- +
- +#define RTW_USB_SUPER_SPEED_BULK_SIZE 1024
- +#define RTW_USB_HIGH_SPEED_BULK_SIZE 512
- +#define RTW_USB_FULL_SPEED_BULK_SIZE 64
- +
- +#define RTW_USB_TX_SEL_HQ BIT(0)
- +#define RTW_USB_TX_SEL_LQ BIT(1)
- +#define RTW_USB_TX_SEL_NQ BIT(2)
- +#define RTW_USB_TX_SEL_EQ BIT(3)
- +
- +#define RTW_USB_BULK_IN_ADDR 0x80
- +#define RTW_USB_INT_IN_ADDR 0x81
- +
- +#define RTW_USB_HW_QUEUE_ENTRY 8
- +
- +#define RTW_USB_PACKET_OFFSET_SZ 8
- +#define RTW_USB_MAX_XMITBUF_SZ (1024 * 20)
- +#define RTW_USB_MAX_RECVBUF_SZ 32768
- +
- +#define RTW_USB_RECVBUFF_ALIGN_SZ 8
- +
- +#define RTW_USB_RXAGG_SIZE 6
- +#define RTW_USB_RXAGG_TIMEOUT 10
- +
- +#define RTW_USB_RXCB_NUM 4
- +
- +#define RTW_USB_EP_MAX 4
- +
- +#define TX_DESC_QSEL_MAX 20
- +
- +#define RTW_USB_VENDOR_ID_REALTEK 0x0bda
- +
- +static inline struct rtw_usb *rtw_get_usb_priv(struct rtw_dev *rtwdev)
- +{
- + return (struct rtw_usb *)rtwdev->priv;
- +}
- +
- +struct rx_usb_ctrl_block {
- + struct rtw_dev *rtwdev;
- + struct urb *rx_urb;
- + struct sk_buff *rx_skb;
- + int n;
- +};
- +
- +struct rtw_usb_tx_data {
- + u8 sn;
- +};
- +
- +struct rtw_usb {
- + struct rtw_dev *rtwdev;
- + struct usb_device *udev;
- +
- + /* protects usb_data_index */
- + spinlock_t usb_lock;
- + __le32 *usb_data;
- + unsigned int usb_data_index;
- +
- + u32 bulkout_size;
- + u8 pipe_interrupt;
- + u8 pipe_in;
- + u8 out_ep[RTW_USB_EP_MAX];
- + u8 qsel_to_ep[TX_DESC_QSEL_MAX];
- + u8 usb_txagg_num;
- +
- + struct workqueue_struct *txwq, *rxwq;
- +
- + struct sk_buff_head tx_queue[RTW_USB_EP_MAX];
- + struct work_struct tx_work;
- +
- + struct rx_usb_ctrl_block rx_cb[RTW_USB_RXCB_NUM];
- + struct sk_buff_head rx_queue;
- + struct work_struct rx_work;
- +};
- +
- +static inline struct rtw_usb_tx_data *rtw_usb_get_tx_data(struct sk_buff *skb)
- +{
- + struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
- +
- + BUILD_BUG_ON(sizeof(struct rtw_usb_tx_data) >
- + sizeof(info->status.status_driver_data));
- +
- + return (struct rtw_usb_tx_data *)info->status.status_driver_data;
- +}
- +
- +int rtw_usb_probe(struct usb_interface *intf, const struct usb_device_id *id);
- +void rtw_usb_disconnect(struct usb_interface *intf);
- +
- +#endif
- diff -Nurp linux-6.1/drivers/net/wireless/realtek/rtw88/util.c linux-6.2/drivers/net/wireless/realtek/rtw88/util.c
- --- linux-6.1/drivers/net/wireless/realtek/rtw88/util.c 2022-12-12 00:15:18.000000000 +0200
- +++ linux-6.2/drivers/net/wireless/realtek/rtw88/util.c 2022-12-24 00:49:25.775376835 +0200
- @@ -105,3 +105,106 @@ void rtw_desc_to_mcsrate(u16 rate, u8 *m
- *mcs = rate - DESC_RATEMCS0;
- }
- }
- +
- +struct rtw_stas_entry {
- + struct list_head list;
- + struct ieee80211_sta *sta;
- +};
- +
- +struct rtw_iter_stas_data {
- + struct rtw_dev *rtwdev;
- + struct list_head list;
- +};
- +
- +static void rtw_collect_sta_iter(void *data, struct ieee80211_sta *sta)
- +{
- + struct rtw_iter_stas_data *iter_stas = data;
- + struct rtw_stas_entry *stas_entry;
- +
- + stas_entry = kmalloc(sizeof(*stas_entry), GFP_ATOMIC);
- + if (!stas_entry)
- + return;
- +
- + stas_entry->sta = sta;
- + list_add_tail(&stas_entry->list, &iter_stas->list);
- +}
- +
- +void rtw_iterate_stas(struct rtw_dev *rtwdev,
- + void (*iterator)(void *data,
- + struct ieee80211_sta *sta),
- + void *data)
- +{
- + struct rtw_iter_stas_data iter_data;
- + struct rtw_stas_entry *sta_entry, *tmp;
- +
- + /* &rtwdev->mutex makes sure no stations can be removed between
- + * collecting the stations and iterating over them.
- + */
- + lockdep_assert_held(&rtwdev->mutex);
- +
- + iter_data.rtwdev = rtwdev;
- + INIT_LIST_HEAD(&iter_data.list);
- +
- + ieee80211_iterate_stations_atomic(rtwdev->hw, rtw_collect_sta_iter,
- + &iter_data);
- +
- + list_for_each_entry_safe(sta_entry, tmp, &iter_data.list,
- + list) {
- + list_del_init(&sta_entry->list);
- + iterator(data, sta_entry->sta);
- + kfree(sta_entry);
- + }
- +}
- +
- +struct rtw_vifs_entry {
- + struct list_head list;
- + struct ieee80211_vif *vif;
- + u8 mac[ETH_ALEN];
- +};
- +
- +struct rtw_iter_vifs_data {
- + struct rtw_dev *rtwdev;
- + struct list_head list;
- +};
- +
- +static void rtw_collect_vif_iter(void *data, u8 *mac, struct ieee80211_vif *vif)
- +{
- + struct rtw_iter_vifs_data *iter_stas = data;
- + struct rtw_vifs_entry *vifs_entry;
- +
- + vifs_entry = kmalloc(sizeof(*vifs_entry), GFP_ATOMIC);
- + if (!vifs_entry)
- + return;
- +
- + vifs_entry->vif = vif;
- + ether_addr_copy(vifs_entry->mac, mac);
- + list_add_tail(&vifs_entry->list, &iter_stas->list);
- +}
- +
- +void rtw_iterate_vifs(struct rtw_dev *rtwdev,
- + void (*iterator)(void *data, u8 *mac,
- + struct ieee80211_vif *vif),
- + void *data)
- +{
- + struct rtw_iter_vifs_data iter_data;
- + struct rtw_vifs_entry *vif_entry, *tmp;
- +
- + /* &rtwdev->mutex makes sure no interfaces can be removed between
- + * collecting the interfaces and iterating over them.
- + */
- + lockdep_assert_held(&rtwdev->mutex);
- +
- + iter_data.rtwdev = rtwdev;
- + INIT_LIST_HEAD(&iter_data.list);
- +
- + ieee80211_iterate_active_interfaces_atomic(rtwdev->hw,
- + IEEE80211_IFACE_ITER_NORMAL,
- + rtw_collect_vif_iter, &iter_data);
- +
- + list_for_each_entry_safe(vif_entry, tmp, &iter_data.list,
- + list) {
- + list_del_init(&vif_entry->list);
- + iterator(data, vif_entry->mac, vif_entry->vif);
- + kfree(vif_entry);
- + }
- +}
- diff -Nurp linux-6.1/drivers/net/wireless/realtek/rtw88/util.h linux-6.2/drivers/net/wireless/realtek/rtw88/util.h
- --- linux-6.1/drivers/net/wireless/realtek/rtw88/util.h 2022-12-12 00:15:18.000000000 +0200
- +++ linux-6.2/drivers/net/wireless/realtek/rtw88/util.h 2022-12-24 00:49:25.775376835 +0200
- @@ -7,9 +7,6 @@
-
- struct rtw_dev;
-
- -#define rtw_iterate_vifs(rtwdev, iterator, data) \
- - ieee80211_iterate_active_interfaces(rtwdev->hw, \
- - IEEE80211_IFACE_ITER_NORMAL, iterator, data)
- #define rtw_iterate_vifs_atomic(rtwdev, iterator, data) \
- ieee80211_iterate_active_interfaces_atomic(rtwdev->hw, \
- IEEE80211_IFACE_ITER_NORMAL, iterator, data)
- @@ -20,6 +17,15 @@ struct rtw_dev;
- #define rtw_iterate_keys_rcu(rtwdev, vif, iterator, data) \
- ieee80211_iter_keys_rcu((rtwdev)->hw, vif, iterator, data)
-
- +void rtw_iterate_vifs(struct rtw_dev *rtwdev,
- + void (*iterator)(void *data, u8 *mac,
- + struct ieee80211_vif *vif),
- + void *data);
- +void rtw_iterate_stas(struct rtw_dev *rtwdev,
- + void (*iterator)(void *data,
- + struct ieee80211_sta *sta),
- + void *data);
- +
- static inline u8 *get_hdr_bssid(struct ieee80211_hdr *hdr)
- {
- __le16 fc = hdr->frame_control;
|