Search Linux Wireless

Re: [PATCH v3 07/12] wifi: rtlwifi: Add rtl8192du/trx.{c,h}

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Wed, 2024-03-20 at 21:39 +0200, Bitterblue Smith wrote:

> 
> These contain routines related to sending frames to the chip.
> 
> Signed-off-by: Bitterblue Smith <rtl8821cerfe2@xxxxxxxxx>
> ---
> v3:
>  - No change.
> 
> v2:
>  - Patch is new in v2, split from patch 3/3 in v1.
> ---
>  .../wireless/realtek/rtlwifi/rtl8192du/trx.c  | 380 ++++++++++++++++++
>  .../wireless/realtek/rtlwifi/rtl8192du/trx.h  |  60 +++
>  2 files changed, 440 insertions(+)
>  create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8192du/trx.c
>  create mode 100644 drivers/net/wireless/realtek/rtlwifi/rtl8192du/trx.h
> 
> diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192du/trx.c
> b/drivers/net/wireless/realtek/rtlwifi/rtl8192du/trx.c
> new file mode 100644
> index 000000000000..830e6e1f2718
> --- /dev/null
> +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192du/trx.c
> @@ -0,0 +1,380 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/* Copyright(c) 2009-2012  Realtek Corporation.*/
> +
> +#include "../wifi.h"
> +#include "../pci.h"
> +#include "../base.h"
> +#include "../stats.h"
> +#include "../usb.h"
> +#include "../rtl8192d/reg.h"
> +#include "../rtl8192d/def.h"
> +#include "../rtl8192d/phy_common.h"
> +#include "../rtl8192d/trx_common.h"
> +#include "phy.h"
> +#include "trx.h"
> +#include "led.h"
> +
> +void rtl92du_tx_cleanup(struct ieee80211_hw *hw, struct sk_buff *skb)
> +{
> +}
> +
> +int rtl92du_tx_post_hdl(struct ieee80211_hw *hw, struct urb *urb,
> +                       struct sk_buff *skb)
> +{
> +       return 0;
> +}
> +
> +struct sk_buff *rtl92du_tx_aggregate_hdl(struct ieee80211_hw *hw,
> +                                        struct sk_buff_head *list)
> +{
> +       return skb_dequeue(list);
> +}
> +
> +static enum rtl_desc_qsel _rtl92du_hwq_to_descq(u16 queue_index)
> +{
> +       switch (queue_index) {
> +       case RTL_TXQ_BCN:
> +               return QSLT_BEACON;
> +       case RTL_TXQ_MGT:
> +               return QSLT_MGNT;
> +       case RTL_TXQ_VO:
> +               return QSLT_VO;
> +       case RTL_TXQ_VI:
> +               return QSLT_VI;
> +       case RTL_TXQ_BK:
> +               return QSLT_BK;
> +       default:
> +       case RTL_TXQ_BE:
> +               return QSLT_BE;
> +       }
> +}
> +
> +/* For HW recovery information */
> +static void _rtl92du_tx_desc_checksum(__le32 *txdesc)
> +{
> +       __le16 *ptr = (__le16 *)txdesc;
> +       u16 checksum = 0;
> +       u32 index;
> +
> +       /* Clear first */
> +       set_tx_desc_tx_desc_checksum(txdesc, 0);
> +       for (index = 0; index < 16; index++)
> +               checksum = checksum ^ le16_to_cpu(*(ptr + index));
> +       set_tx_desc_tx_desc_checksum(txdesc, checksum);
> +}
> +
> +void rtl92du_tx_fill_desc(struct ieee80211_hw *hw,
> +                         struct ieee80211_hdr *hdr, u8 *pdesc_tx,
> +                         u8 *pbd_desc_tx, struct ieee80211_tx_info *info,
> +                         struct ieee80211_sta *sta,
> +                         struct sk_buff *skb,
> +                         u8 queue_index,
> +                         struct rtl_tcb_desc *tcb_desc)
> +{
> +       struct rtl_priv *rtlpriv = rtl_priv(hw);
> +       struct rtl_ps_ctl *ppsc = rtl_psc(rtlpriv);
> +       struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
> +       struct rtl_mac *mac = rtl_mac(rtlpriv);
> +       struct rtl_sta_info *sta_entry;
> +       __le16 fc = hdr->frame_control;
> +       u8 agg_state = RTL_AGG_STOP;
> +       u16 pktlen = skb->len;
> +       u8 ampdu_density = 0;
> +       u16 seq_number;
> +       __le32 *txdesc;
> +       u8 rate_flag;
> +       u8 tid;
> +
> +       rtl_get_tcb_desc(hw, info, sta, skb, tcb_desc);
> +
> +       txdesc = (__le32 *)skb_push(skb, RTL_TX_HEADER_SIZE);
> +       memset(txdesc, 0, RTL_TX_HEADER_SIZE);
> +
> +       set_tx_desc_pkt_size(txdesc, pktlen);
> +       set_tx_desc_linip(txdesc, 0);
> +       set_tx_desc_pkt_offset(txdesc, RTL_DUMMY_OFFSET);
> +       set_tx_desc_offset(txdesc, RTL_TX_HEADER_SIZE);
> +       /* 5G have no CCK rate */
> +       if (rtlhal->current_bandtype == BAND_ON_5G)
> +               if (tcb_desc->hw_rate < DESC_RATE6M)
> +                       tcb_desc->hw_rate = DESC_RATE6M;
> +
> +       set_tx_desc_tx_rate(txdesc, tcb_desc->hw_rate);
> +       if (tcb_desc->use_shortgi || tcb_desc->use_shortpreamble)
> +               set_tx_desc_data_shortgi(txdesc, 1);
> +
> +       if (rtlhal->macphymode == DUALMAC_DUALPHY &&
> +           tcb_desc->hw_rate == DESC_RATEMCS7)
> +               set_tx_desc_data_shortgi(txdesc, 1);
> +
> +       if (sta) {
> +               sta_entry = (struct rtl_sta_info *)sta->drv_priv;
> +               tid = ieee80211_get_tid(hdr);
> +               agg_state = sta_entry->tids[tid].agg.agg_state;
> +               ampdu_density = sta->deflink.ht_cap.ampdu_density;
> +       }
> +
> +       if (agg_state == RTL_AGG_OPERATIONAL &&
> +           info->flags & IEEE80211_TX_CTL_AMPDU) {
> +               set_tx_desc_agg_enable(txdesc, 1);
> +               set_tx_desc_max_agg_num(txdesc, 0x14);
> +               set_tx_desc_ampdu_density(txdesc, ampdu_density);
> +               tcb_desc->rts_enable = 1;
> +               tcb_desc->rts_rate = DESC_RATE24M;
> +       } else {
> +               set_tx_desc_agg_break(txdesc, 1);
> +       }
> +       seq_number = (le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_SEQ) >> 4;
> +       set_tx_desc_seq(txdesc, seq_number);
> +       set_tx_desc_rts_enable(txdesc,
> +                              ((tcb_desc->rts_enable &&
> +                               !tcb_desc->cts_enable) ? 1 : 0));

u32 rts_en = tcb_desc->rts_enable && !tcb_desc->cts_enable ? 1 : 0;

or 

u32 rts_en = tcb_desc->rts_enable && !tcb_desc->cts_enable;

set_tx_desc_rts_enable(txdesc, rts_en);



> +       set_tx_desc_hw_rts_enable(txdesc,
> +                                 ((tcb_desc->rts_enable ||
> +                                  tcb_desc->cts_enable) ? 1 : 0));
> +       set_tx_desc_cts2self(txdesc, ((tcb_desc->cts_enable) ? 1 : 0));
> +       set_tx_desc_rts_stbc(txdesc, ((tcb_desc->rts_stbc) ? 1 : 0));
> +       /* 5G have no CCK rate */
> +       if (rtlhal->current_bandtype == BAND_ON_5G)
> +               if (tcb_desc->rts_rate < DESC_RATE6M)
> +                       tcb_desc->rts_rate = DESC_RATE6M;
> +       set_tx_desc_rts_rate(txdesc, tcb_desc->rts_rate);
> +       set_tx_desc_rts_bw(txdesc, 0);
> +       set_tx_desc_rts_sc(txdesc, tcb_desc->rts_sc);
> +       set_tx_desc_rts_short(txdesc,
> +                             ((tcb_desc->rts_rate <= DESC_RATE54M) ?
> +                              (tcb_desc->rts_use_shortpreamble ? 1 : 0)
> +                              : (tcb_desc->rts_use_shortgi ? 1 : 0)));

u32 rts_short;

if (...)
    rts_short = 1;
else if (...)
    rts_short = 1;
else
    rts_short = 0;


> +
> +       if (info->control.hw_key) {
> +               struct ieee80211_key_conf *keyconf = info->control.hw_key;
> +
> +               switch (keyconf->cipher) {
> +               case WLAN_CIPHER_SUITE_WEP40:
> +               case WLAN_CIPHER_SUITE_WEP104:
> +               case WLAN_CIPHER_SUITE_TKIP:
> +                       set_tx_desc_sec_type(txdesc, 0x1);
> +                       break;
> +               case WLAN_CIPHER_SUITE_CCMP:
> +                       set_tx_desc_sec_type(txdesc, 0x3);
> +                       break;
> +               default:
> +                       set_tx_desc_sec_type(txdesc, 0x0);
> +                       break;
> +               }
> +       }

blank line

> +       set_tx_desc_pkt_id(txdesc, 0);
> +       set_tx_desc_queue_sel(txdesc, _rtl92du_hwq_to_descq(queue_index));
> +       set_tx_desc_data_rate_fb_limit(txdesc, 0x1F);
> +       set_tx_desc_rts_rate_fb_limit(txdesc, 0xF);
> +       set_tx_desc_disable_fb(txdesc, 0);
> +       set_tx_desc_use_rate(txdesc, tcb_desc->use_driver_rate ? 1 : 0);

blank line

> +       if (ieee80211_is_data_qos(fc)) {
> +               if (mac->rdg_en) {
> +                       rtl_dbg(rtlpriv, COMP_SEND, DBG_TRACE,
> +                               "Enable RDG function\n");
> +                       set_tx_desc_rdg_enable(txdesc, 1);
> +                       set_tx_desc_htc(txdesc, 1);
> +               }
> +               set_tx_desc_qos(txdesc, 1);
> +       }

> +       if (rtlpriv->dm.useramask) {
> +               set_tx_desc_rate_id(txdesc, tcb_desc->ratr_index);
> +               set_tx_desc_macid(txdesc, tcb_desc->mac_id);
> +       } else {
> +               set_tx_desc_rate_id(txdesc, 0xC + tcb_desc->ratr_index);
> +               set_tx_desc_macid(txdesc, tcb_desc->ratr_index);
> +       }

> +       if (!ieee80211_is_data_qos(fc) && ppsc->leisure_ps &&
> +           ppsc->fwctrl_lps) {
> +               set_tx_desc_hwseq_en(txdesc, 1);
> +               set_tx_desc_pkt_id(txdesc, 8);
> +       }

> +       if (ieee80211_has_morefrags(fc))
> +               set_tx_desc_more_frag(txdesc, 1);
> +       if (is_multicast_ether_addr(ieee80211_get_DA(hdr)) ||
> +           is_broadcast_ether_addr(ieee80211_get_DA(hdr)))
> +               set_tx_desc_bmc(txdesc, 1);

> +       set_tx_desc_own(txdesc, 1);
> +       set_tx_desc_last_seg(txdesc, 1);
> +       set_tx_desc_first_seg(txdesc, 1);
> +       _rtl92du_tx_desc_checksum(txdesc);
> +
> +       rtl_dbg(rtlpriv, COMP_SEND, DBG_TRACE, "==>\n");
> +}
> +


[...]


> +
> +static int _rtl92du_out_ep_mapping(struct ieee80211_hw *hw)
> +{
> +       struct rtl_usb *rtlusb = rtl_usbdev(rtl_usbpriv(hw));
> +       struct rtl_ep_map *ep_map = &rtlusb->ep_map;
> +       int err = 0;
> +
> +       switch (rtlusb->out_ep_nums) {
> +       case 1:
> +               _rtl92du_one_out_ep_mapping(rtlusb, ep_map);
> +               break;
> +       case 2:
> +               _rtl92du_two_out_ep_mapping(rtlusb, ep_map);
> +               break;
> +       case 3:
> +               _rtl92du_three_out_ep_mapping(rtlusb, ep_map);
> +               break;
> +       default:
> +               err = -EINVAL;

return -EINVAL;

> +               break;
> +       }
> +
> +       return err;

return 0;

> +}
> +
> +int rtl92du_endpoint_mapping(struct ieee80211_hw *hw)
> +{
> +       struct rtl_usb *rtlusb = rtl_usbdev(rtl_usbpriv(hw));
> +       int error = -EINVAL;
> +
> +       _rtl92du_config_out_ep(hw, rtlusb->out_ep_nums);
> +
> +       /* Normal chip with one IN and one OUT doesn't have interrupt IN EP. */
> +       if (rtlusb->out_ep_nums == 1 && rtlusb->in_ep_nums != 1)
> +               goto err_out;

return -EINVAL;

> +
> +       error = _rtl92du_out_ep_mapping(hw);
> +       if (error)
> +               goto err_out;

return ret;

or

return _rtl92du_out_ep_mapping(hw);


> +err_out:
> +       return error;
> +}
> +







[Index of Archives]     [Linux Host AP]     [ATH6KL]     [Linux Wireless Personal Area Network]     [Linux Bluetooth]     [Wireless Regulations]     [Linux Netdev]     [Kernel Newbies]     [Linux Kernel]     [IDE]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite Hiking]     [MIPS Linux]     [ARM Linux]     [Linux RAID]

  Powered by Linux