162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
262306a36Sopenharmony_ci/* Copyright(c) 2018-2019  Realtek Corporation
362306a36Sopenharmony_ci */
462306a36Sopenharmony_ci
562306a36Sopenharmony_ci#ifndef	__RTW_HCI_H__
662306a36Sopenharmony_ci#define __RTW_HCI_H__
762306a36Sopenharmony_ci
862306a36Sopenharmony_ci/* ops for PCI, USB and SDIO */
962306a36Sopenharmony_cistruct rtw_hci_ops {
1062306a36Sopenharmony_ci	int (*tx_write)(struct rtw_dev *rtwdev,
1162306a36Sopenharmony_ci			struct rtw_tx_pkt_info *pkt_info,
1262306a36Sopenharmony_ci			struct sk_buff *skb);
1362306a36Sopenharmony_ci	void (*tx_kick_off)(struct rtw_dev *rtwdev);
1462306a36Sopenharmony_ci	void (*flush_queues)(struct rtw_dev *rtwdev, u32 queues, bool drop);
1562306a36Sopenharmony_ci	int (*setup)(struct rtw_dev *rtwdev);
1662306a36Sopenharmony_ci	int (*start)(struct rtw_dev *rtwdev);
1762306a36Sopenharmony_ci	void (*stop)(struct rtw_dev *rtwdev);
1862306a36Sopenharmony_ci	void (*deep_ps)(struct rtw_dev *rtwdev, bool enter);
1962306a36Sopenharmony_ci	void (*link_ps)(struct rtw_dev *rtwdev, bool enter);
2062306a36Sopenharmony_ci	void (*interface_cfg)(struct rtw_dev *rtwdev);
2162306a36Sopenharmony_ci
2262306a36Sopenharmony_ci	int (*write_data_rsvd_page)(struct rtw_dev *rtwdev, u8 *buf, u32 size);
2362306a36Sopenharmony_ci	int (*write_data_h2c)(struct rtw_dev *rtwdev, u8 *buf, u32 size);
2462306a36Sopenharmony_ci
2562306a36Sopenharmony_ci	u8 (*read8)(struct rtw_dev *rtwdev, u32 addr);
2662306a36Sopenharmony_ci	u16 (*read16)(struct rtw_dev *rtwdev, u32 addr);
2762306a36Sopenharmony_ci	u32 (*read32)(struct rtw_dev *rtwdev, u32 addr);
2862306a36Sopenharmony_ci	void (*write8)(struct rtw_dev *rtwdev, u32 addr, u8 val);
2962306a36Sopenharmony_ci	void (*write16)(struct rtw_dev *rtwdev, u32 addr, u16 val);
3062306a36Sopenharmony_ci	void (*write32)(struct rtw_dev *rtwdev, u32 addr, u32 val);
3162306a36Sopenharmony_ci};
3262306a36Sopenharmony_ci
3362306a36Sopenharmony_cistatic inline int rtw_hci_tx_write(struct rtw_dev *rtwdev,
3462306a36Sopenharmony_ci				   struct rtw_tx_pkt_info *pkt_info,
3562306a36Sopenharmony_ci				   struct sk_buff *skb)
3662306a36Sopenharmony_ci{
3762306a36Sopenharmony_ci	return rtwdev->hci.ops->tx_write(rtwdev, pkt_info, skb);
3862306a36Sopenharmony_ci}
3962306a36Sopenharmony_ci
4062306a36Sopenharmony_cistatic inline void rtw_hci_tx_kick_off(struct rtw_dev *rtwdev)
4162306a36Sopenharmony_ci{
4262306a36Sopenharmony_ci	return rtwdev->hci.ops->tx_kick_off(rtwdev);
4362306a36Sopenharmony_ci}
4462306a36Sopenharmony_ci
4562306a36Sopenharmony_cistatic inline int rtw_hci_setup(struct rtw_dev *rtwdev)
4662306a36Sopenharmony_ci{
4762306a36Sopenharmony_ci	return rtwdev->hci.ops->setup(rtwdev);
4862306a36Sopenharmony_ci}
4962306a36Sopenharmony_ci
5062306a36Sopenharmony_cistatic inline int rtw_hci_start(struct rtw_dev *rtwdev)
5162306a36Sopenharmony_ci{
5262306a36Sopenharmony_ci	return rtwdev->hci.ops->start(rtwdev);
5362306a36Sopenharmony_ci}
5462306a36Sopenharmony_ci
5562306a36Sopenharmony_cistatic inline void rtw_hci_stop(struct rtw_dev *rtwdev)
5662306a36Sopenharmony_ci{
5762306a36Sopenharmony_ci	rtwdev->hci.ops->stop(rtwdev);
5862306a36Sopenharmony_ci}
5962306a36Sopenharmony_ci
6062306a36Sopenharmony_cistatic inline void rtw_hci_deep_ps(struct rtw_dev *rtwdev, bool enter)
6162306a36Sopenharmony_ci{
6262306a36Sopenharmony_ci	rtwdev->hci.ops->deep_ps(rtwdev, enter);
6362306a36Sopenharmony_ci}
6462306a36Sopenharmony_ci
6562306a36Sopenharmony_cistatic inline void rtw_hci_link_ps(struct rtw_dev *rtwdev, bool enter)
6662306a36Sopenharmony_ci{
6762306a36Sopenharmony_ci	rtwdev->hci.ops->link_ps(rtwdev, enter);
6862306a36Sopenharmony_ci}
6962306a36Sopenharmony_ci
7062306a36Sopenharmony_cistatic inline void rtw_hci_interface_cfg(struct rtw_dev *rtwdev)
7162306a36Sopenharmony_ci{
7262306a36Sopenharmony_ci	rtwdev->hci.ops->interface_cfg(rtwdev);
7362306a36Sopenharmony_ci}
7462306a36Sopenharmony_ci
7562306a36Sopenharmony_cistatic inline int
7662306a36Sopenharmony_cirtw_hci_write_data_rsvd_page(struct rtw_dev *rtwdev, u8 *buf, u32 size)
7762306a36Sopenharmony_ci{
7862306a36Sopenharmony_ci	return rtwdev->hci.ops->write_data_rsvd_page(rtwdev, buf, size);
7962306a36Sopenharmony_ci}
8062306a36Sopenharmony_ci
8162306a36Sopenharmony_cistatic inline int
8262306a36Sopenharmony_cirtw_hci_write_data_h2c(struct rtw_dev *rtwdev, u8 *buf, u32 size)
8362306a36Sopenharmony_ci{
8462306a36Sopenharmony_ci	return rtwdev->hci.ops->write_data_h2c(rtwdev, buf, size);
8562306a36Sopenharmony_ci}
8662306a36Sopenharmony_ci
8762306a36Sopenharmony_cistatic inline u8 rtw_read8(struct rtw_dev *rtwdev, u32 addr)
8862306a36Sopenharmony_ci{
8962306a36Sopenharmony_ci	return rtwdev->hci.ops->read8(rtwdev, addr);
9062306a36Sopenharmony_ci}
9162306a36Sopenharmony_ci
9262306a36Sopenharmony_cistatic inline u16 rtw_read16(struct rtw_dev *rtwdev, u32 addr)
9362306a36Sopenharmony_ci{
9462306a36Sopenharmony_ci	return rtwdev->hci.ops->read16(rtwdev, addr);
9562306a36Sopenharmony_ci}
9662306a36Sopenharmony_ci
9762306a36Sopenharmony_cistatic inline u32 rtw_read32(struct rtw_dev *rtwdev, u32 addr)
9862306a36Sopenharmony_ci{
9962306a36Sopenharmony_ci	return rtwdev->hci.ops->read32(rtwdev, addr);
10062306a36Sopenharmony_ci}
10162306a36Sopenharmony_ci
10262306a36Sopenharmony_cistatic inline void rtw_write8(struct rtw_dev *rtwdev, u32 addr, u8 val)
10362306a36Sopenharmony_ci{
10462306a36Sopenharmony_ci	rtwdev->hci.ops->write8(rtwdev, addr, val);
10562306a36Sopenharmony_ci}
10662306a36Sopenharmony_ci
10762306a36Sopenharmony_cistatic inline void rtw_write16(struct rtw_dev *rtwdev, u32 addr, u16 val)
10862306a36Sopenharmony_ci{
10962306a36Sopenharmony_ci	rtwdev->hci.ops->write16(rtwdev, addr, val);
11062306a36Sopenharmony_ci}
11162306a36Sopenharmony_ci
11262306a36Sopenharmony_cistatic inline void rtw_write32(struct rtw_dev *rtwdev, u32 addr, u32 val)
11362306a36Sopenharmony_ci{
11462306a36Sopenharmony_ci	rtwdev->hci.ops->write32(rtwdev, addr, val);
11562306a36Sopenharmony_ci}
11662306a36Sopenharmony_ci
11762306a36Sopenharmony_cistatic inline void rtw_write8_set(struct rtw_dev *rtwdev, u32 addr, u8 bit)
11862306a36Sopenharmony_ci{
11962306a36Sopenharmony_ci	u8 val;
12062306a36Sopenharmony_ci
12162306a36Sopenharmony_ci	val = rtw_read8(rtwdev, addr);
12262306a36Sopenharmony_ci	rtw_write8(rtwdev, addr, val | bit);
12362306a36Sopenharmony_ci}
12462306a36Sopenharmony_ci
12562306a36Sopenharmony_cistatic inline void rtw_write16_set(struct rtw_dev *rtwdev, u32 addr, u16 bit)
12662306a36Sopenharmony_ci{
12762306a36Sopenharmony_ci	u16 val;
12862306a36Sopenharmony_ci
12962306a36Sopenharmony_ci	val = rtw_read16(rtwdev, addr);
13062306a36Sopenharmony_ci	rtw_write16(rtwdev, addr, val | bit);
13162306a36Sopenharmony_ci}
13262306a36Sopenharmony_ci
13362306a36Sopenharmony_cistatic inline void rtw_write32_set(struct rtw_dev *rtwdev, u32 addr, u32 bit)
13462306a36Sopenharmony_ci{
13562306a36Sopenharmony_ci	u32 val;
13662306a36Sopenharmony_ci
13762306a36Sopenharmony_ci	val = rtw_read32(rtwdev, addr);
13862306a36Sopenharmony_ci	rtw_write32(rtwdev, addr, val | bit);
13962306a36Sopenharmony_ci}
14062306a36Sopenharmony_ci
14162306a36Sopenharmony_cistatic inline void rtw_write8_clr(struct rtw_dev *rtwdev, u32 addr, u8 bit)
14262306a36Sopenharmony_ci{
14362306a36Sopenharmony_ci	u8 val;
14462306a36Sopenharmony_ci
14562306a36Sopenharmony_ci	val = rtw_read8(rtwdev, addr);
14662306a36Sopenharmony_ci	rtw_write8(rtwdev, addr, val & ~bit);
14762306a36Sopenharmony_ci}
14862306a36Sopenharmony_ci
14962306a36Sopenharmony_cistatic inline void rtw_write16_clr(struct rtw_dev *rtwdev, u32 addr, u16 bit)
15062306a36Sopenharmony_ci{
15162306a36Sopenharmony_ci	u16 val;
15262306a36Sopenharmony_ci
15362306a36Sopenharmony_ci	val = rtw_read16(rtwdev, addr);
15462306a36Sopenharmony_ci	rtw_write16(rtwdev, addr, val & ~bit);
15562306a36Sopenharmony_ci}
15662306a36Sopenharmony_ci
15762306a36Sopenharmony_cistatic inline void rtw_write32_clr(struct rtw_dev *rtwdev, u32 addr, u32 bit)
15862306a36Sopenharmony_ci{
15962306a36Sopenharmony_ci	u32 val;
16062306a36Sopenharmony_ci
16162306a36Sopenharmony_ci	val = rtw_read32(rtwdev, addr);
16262306a36Sopenharmony_ci	rtw_write32(rtwdev, addr, val & ~bit);
16362306a36Sopenharmony_ci}
16462306a36Sopenharmony_ci
16562306a36Sopenharmony_cistatic inline u32
16662306a36Sopenharmony_cirtw_read_rf(struct rtw_dev *rtwdev, enum rtw_rf_path rf_path,
16762306a36Sopenharmony_ci	    u32 addr, u32 mask)
16862306a36Sopenharmony_ci{
16962306a36Sopenharmony_ci	u32 val;
17062306a36Sopenharmony_ci
17162306a36Sopenharmony_ci	lockdep_assert_held(&rtwdev->mutex);
17262306a36Sopenharmony_ci
17362306a36Sopenharmony_ci	val = rtwdev->chip->ops->read_rf(rtwdev, rf_path, addr, mask);
17462306a36Sopenharmony_ci
17562306a36Sopenharmony_ci	return val;
17662306a36Sopenharmony_ci}
17762306a36Sopenharmony_ci
17862306a36Sopenharmony_cistatic inline void
17962306a36Sopenharmony_cirtw_write_rf(struct rtw_dev *rtwdev, enum rtw_rf_path rf_path,
18062306a36Sopenharmony_ci	     u32 addr, u32 mask, u32 data)
18162306a36Sopenharmony_ci{
18262306a36Sopenharmony_ci	lockdep_assert_held(&rtwdev->mutex);
18362306a36Sopenharmony_ci
18462306a36Sopenharmony_ci	rtwdev->chip->ops->write_rf(rtwdev, rf_path, addr, mask, data);
18562306a36Sopenharmony_ci}
18662306a36Sopenharmony_ci
18762306a36Sopenharmony_cistatic inline u32
18862306a36Sopenharmony_cirtw_read32_mask(struct rtw_dev *rtwdev, u32 addr, u32 mask)
18962306a36Sopenharmony_ci{
19062306a36Sopenharmony_ci	u32 shift = __ffs(mask);
19162306a36Sopenharmony_ci	u32 orig;
19262306a36Sopenharmony_ci	u32 ret;
19362306a36Sopenharmony_ci
19462306a36Sopenharmony_ci	orig = rtw_read32(rtwdev, addr);
19562306a36Sopenharmony_ci	ret = (orig & mask) >> shift;
19662306a36Sopenharmony_ci
19762306a36Sopenharmony_ci	return ret;
19862306a36Sopenharmony_ci}
19962306a36Sopenharmony_ci
20062306a36Sopenharmony_cistatic inline u16
20162306a36Sopenharmony_cirtw_read16_mask(struct rtw_dev *rtwdev, u32 addr, u32 mask)
20262306a36Sopenharmony_ci{
20362306a36Sopenharmony_ci	u32 shift = __ffs(mask);
20462306a36Sopenharmony_ci	u32 orig;
20562306a36Sopenharmony_ci	u32 ret;
20662306a36Sopenharmony_ci
20762306a36Sopenharmony_ci	orig = rtw_read16(rtwdev, addr);
20862306a36Sopenharmony_ci	ret = (orig & mask) >> shift;
20962306a36Sopenharmony_ci
21062306a36Sopenharmony_ci	return ret;
21162306a36Sopenharmony_ci}
21262306a36Sopenharmony_ci
21362306a36Sopenharmony_cistatic inline u8
21462306a36Sopenharmony_cirtw_read8_mask(struct rtw_dev *rtwdev, u32 addr, u32 mask)
21562306a36Sopenharmony_ci{
21662306a36Sopenharmony_ci	u32 shift = __ffs(mask);
21762306a36Sopenharmony_ci	u32 orig;
21862306a36Sopenharmony_ci	u32 ret;
21962306a36Sopenharmony_ci
22062306a36Sopenharmony_ci	orig = rtw_read8(rtwdev, addr);
22162306a36Sopenharmony_ci	ret = (orig & mask) >> shift;
22262306a36Sopenharmony_ci
22362306a36Sopenharmony_ci	return ret;
22462306a36Sopenharmony_ci}
22562306a36Sopenharmony_ci
22662306a36Sopenharmony_cistatic inline void
22762306a36Sopenharmony_cirtw_write32_mask(struct rtw_dev *rtwdev, u32 addr, u32 mask, u32 data)
22862306a36Sopenharmony_ci{
22962306a36Sopenharmony_ci	u32 shift = __ffs(mask);
23062306a36Sopenharmony_ci	u32 orig;
23162306a36Sopenharmony_ci	u32 set;
23262306a36Sopenharmony_ci
23362306a36Sopenharmony_ci	WARN(addr & 0x3, "should be 4-byte aligned, addr = 0x%08x\n", addr);
23462306a36Sopenharmony_ci
23562306a36Sopenharmony_ci	orig = rtw_read32(rtwdev, addr);
23662306a36Sopenharmony_ci	set = (orig & ~mask) | ((data << shift) & mask);
23762306a36Sopenharmony_ci	rtw_write32(rtwdev, addr, set);
23862306a36Sopenharmony_ci}
23962306a36Sopenharmony_ci
24062306a36Sopenharmony_cistatic inline void
24162306a36Sopenharmony_cirtw_write8_mask(struct rtw_dev *rtwdev, u32 addr, u32 mask, u8 data)
24262306a36Sopenharmony_ci{
24362306a36Sopenharmony_ci	u32 shift;
24462306a36Sopenharmony_ci	u8 orig, set;
24562306a36Sopenharmony_ci
24662306a36Sopenharmony_ci	mask &= 0xff;
24762306a36Sopenharmony_ci	shift = __ffs(mask);
24862306a36Sopenharmony_ci
24962306a36Sopenharmony_ci	orig = rtw_read8(rtwdev, addr);
25062306a36Sopenharmony_ci	set = (orig & ~mask) | ((data << shift) & mask);
25162306a36Sopenharmony_ci	rtw_write8(rtwdev, addr, set);
25262306a36Sopenharmony_ci}
25362306a36Sopenharmony_ci
25462306a36Sopenharmony_cistatic inline enum rtw_hci_type rtw_hci_type(struct rtw_dev *rtwdev)
25562306a36Sopenharmony_ci{
25662306a36Sopenharmony_ci	return rtwdev->hci.type;
25762306a36Sopenharmony_ci}
25862306a36Sopenharmony_ci
25962306a36Sopenharmony_cistatic inline void rtw_hci_flush_queues(struct rtw_dev *rtwdev, u32 queues,
26062306a36Sopenharmony_ci					bool drop)
26162306a36Sopenharmony_ci{
26262306a36Sopenharmony_ci	if (rtwdev->hci.ops->flush_queues)
26362306a36Sopenharmony_ci		rtwdev->hci.ops->flush_queues(rtwdev, queues, drop);
26462306a36Sopenharmony_ci}
26562306a36Sopenharmony_ci
26662306a36Sopenharmony_cistatic inline void rtw_hci_flush_all_queues(struct rtw_dev *rtwdev, bool drop)
26762306a36Sopenharmony_ci{
26862306a36Sopenharmony_ci	if (rtwdev->hci.ops->flush_queues)
26962306a36Sopenharmony_ci		rtwdev->hci.ops->flush_queues(rtwdev,
27062306a36Sopenharmony_ci					      BIT(rtwdev->hw->queues) - 1,
27162306a36Sopenharmony_ci					      drop);
27262306a36Sopenharmony_ci}
27362306a36Sopenharmony_ci
27462306a36Sopenharmony_ci#endif
275