> -----Original Message----- > From: Bitterblue Smith <rtl8821cerfe2@xxxxxxxxx> > Sent: Wednesday, December 7, 2022 5:49 AM > To: linux-wireless@xxxxxxxxxxxxxxx > Cc: Jes Sorensen <Jes.Sorensen@xxxxxxxxx>; Ping-Ke Shih <pkshih@xxxxxxxxxxx>; Andrea Merello > <andrea.merello@xxxxxxxxx>; Taehee Yoo <ap420073@xxxxxxxxx> > Subject: [PATCH 2/2] wifi: rtl8xxxu: Add rate control code for RTL8188EU > > Copied from the newer vendor driver, v5.2.2.4. > > Signed-off-by: Bitterblue Smith <rtl8821cerfe2@xxxxxxxxx> > --- > This patch should be applied after my older patch: > "[PATCH v4 3/3] wifi: rtl8xxxu: Introduce rtl8xxxu_update_ra_report" > --- > .../net/wireless/realtek/rtl8xxxu/rtl8xxxu.h | 39 ++ > .../realtek/rtl8xxxu/rtl8xxxu_8188e.c | 600 +++++++++++++++++- > .../wireless/realtek/rtl8xxxu/rtl8xxxu_core.c | 129 +++- > 3 files changed, 738 insertions(+), 30 deletions(-) > [...] > diff --git a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8188e.c > b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8188e.c > index 9eb9ae03ca81..d620c7a4d3c6 100644 > --- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8188e.c > +++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8188e.c [...] > @@ -1251,6 +1377,478 @@ static s8 rtl8188e_cck_rssi(struct rtl8xxxu_priv *priv, u8 cck_agc_rpt) > return rx_pwr_all; > } > > +static void rtl8188e_set_tx_rpt_timing(struct rtl8xxxu_ra_info *ra, u8 timing) > +{ > + u8 idx = 0; no need '=0' > + > + for (idx = 0; idx < 5; idx++) > + if (dynamic_tx_rpt_timing[idx] == ra->rpt_time) > + break; > + > + if (timing == DEFAULT_TIMING) { > + idx = 0; /* 200ms */ > + } else if (timing == INCREASE_TIMING) { > + if (idx < 5) > + idx++; > + } else if (timing == DECREASE_TIMING) { > + if (idx > 0) > + idx--; > + } > + > + ra->rpt_time = dynamic_tx_rpt_timing[idx]; > +} [...] > +static void rtl8188e_power_training_try_state(struct rtl8xxxu_ra_info *ra) > +{ > + ra->pt_try_state = 0; > + switch (ra->pt_mode_ss) { > + case 3: > + if (ra->decision_rate >= DESC_RATE_MCS13) > + ra->pt_try_state = 1; > + break; > + case 2: > + if (ra->decision_rate >= DESC_RATE_MCS5) > + ra->pt_try_state = 1; > + break; > + case 1: > + if (ra->decision_rate >= DESC_RATE_48M) > + ra->pt_try_state = 1; > + break; > + case 0: > + if (ra->decision_rate >= DESC_RATE_11M) > + ra->pt_try_state = 1; > + break; > + default: > + ra->pt_try_state = 0; break; > + } > + > + if (ra->rssi_sta_ra < 48) { > + ra->pt_stage = 0; > + } else if (ra->pt_try_state == 1) { > + if ((ra->pt_stop_count >= 10) || > + (ra->pt_pre_rssi > ra->rssi_sta_ra + 5) || > + (ra->pt_pre_rssi < ra->rssi_sta_ra - 5) || > + (ra->decision_rate != ra->pt_pre_rate)) { > + if (ra->pt_stage == 0) > + ra->pt_stage = 1; > + else if (ra->pt_stage == 1) > + ra->pt_stage = 3; > + else > + ra->pt_stage = 5; > + > + ra->pt_pre_rssi = ra->rssi_sta_ra; > + ra->pt_stop_count = 0; > + } else { > + ra->ra_stage = 0; > + ra->pt_stop_count++; > + } > + } else { > + ra->pt_stage = 0; > + ra->ra_stage = 0; > + } > + > + ra->pt_pre_rate = ra->decision_rate; > + > + /* TODO: implement the "false alarm" statistics for this */ > + /* Disable power training when noisy environment */ > + /* if (p_dm_odm->is_disable_power_training) { */ > + if (1) { > + ra->pt_stage = 0; > + ra->ra_stage = 0; > + ra->pt_stop_count = 0; > + } > +} [...] > @@ -5757,6 +5780,42 @@ static void rtl8723bu_handle_c2h(struct rtl8xxxu_priv *priv, > schedule_work(&priv->c2hcmd_work); > } > > +static void rtl8188e_c2hcmd_callback(struct work_struct *work) > +{ > + struct rtl8xxxu_priv *priv = container_of(work, struct rtl8xxxu_priv, c2hcmd_work); > + struct device *dev = &priv->udev->dev; > + struct sk_buff *skb = NULL; > + struct rtl8xxxu_rxdesc16 *rx_desc; > + > + while (!skb_queue_empty(&priv->c2hcmd_queue)) { > + skb = skb_dequeue(&priv->c2hcmd_queue); > + > + rx_desc = (struct rtl8xxxu_rxdesc16 *)(skb->data - sizeof(struct rtl8xxxu_rxdesc16)); > + > + switch (rx_desc->rpt_sel) { > + case 1: > + dev_dbg(dev, "C2H TX report type 1\n"); > + > + break; > + case 2: > + dev_dbg(dev, "C2H TX report type 2\n"); > + > + rtl8188e_handle_ra_tx_report2(priv, skb); > + > + break; > + case 3: > + dev_dbg(dev, "C2H USB interrupt report\n"); > + > + break; > + default: > + dev_warn(dev, "%s: rpt_sel should not be %d\n", > + __func__, rx_desc->rpt_sel); break; > + } > + > + dev_kfree_skb(skb); > + } > +} > + > int rtl8xxxu_parse_rxdesc16(struct rtl8xxxu_priv *priv, struct sk_buff *skb) [...] I admit that I don't quite understand rate control code, so I just review surface, but it would be fine if it works fine to you. :-) -- Ping-Ke