8dd79199f8
The bes2600 driver is a fork of the upstream cw1200 driver
(drivers/net/wireless/st/cw1200/, ST-Ericsson, Dmitry Tarnyagin
2010-2011). The fork's file headers have three GPL-compliance issues:
1. NO SPDX-License-Identifier on any of 48 source files (cw1200
mainline has them on all 25). kernel.org-mandated since 2017.
2. Original "Copyright (c) 2010, ST-Ericsson" lines stripped from
all files inherited from cw1200, replaced with
"Copyright (c) 2010, Bestechnic" — factually impossible
(Bestechnic did not author the 2010 work) and a GPL-2.0 §1
attribution-preservation violation.
3. The "GPL version 2 as published by the Free Software Foundation"
boilerplate paragraph is redundant alongside SPDX and is the
legacy form modern kernel sources have replaced.
This patch corrects all three for the 48 .c/.h files in bes2600/:
- Adds `// SPDX-License-Identifier: GPL-2.0-only` (or `/* ... */`
for headers) as line 1 of every file.
- Restores `Copyright (c) 2010, ST-Ericsson` + `Author: Dmitry
Tarnyagin <dmitry.tarnyagin@lockless.no>` as the FIRST copyright
chain entry on all 22 files derived from cw1200 (bh.{c,h},
debug.{c,h}, fwio.{c,h}, hwio.{c,h}, main.c, pm.{c,h},
queue.{c,h}, scan.{c,h}, sta.{c,h}, txrx.{c,h}, wsm.{c,h}).
- Keeps `Copyright (c) 2022, Bestechnic (Beijing) Co., Ltd.` as
the SECOND chain entry where Bestechnic genuinely contributed.
- Notes "Derived from cw1200_sdio.c" + ST-Ericsson copyright on
bes2600_sdio.c (heavy derivation, not a literal rename).
- Notes "Replaces hwbus.h from cw1200/" + ST-Ericsson copyright
on sbus.h.
- Preserves the prism54/islsm authorship chain on main.c and
bes2600.h (Michael Wu 2006 + Jean-Baptiste Note 2004-2006).
- Drops the GPL-2.0 boilerplate paragraph in favour of SPDX.
No code changes — only file-header comment blocks. Module build is
unaffected (verified by header-only diff scope).
This is a prerequisite for any kernel.org submission attempt. The
existing MODULE_LICENSE("GPL") + MODULE_AUTHOR(Tarnyagin@stericsson.com)
declarations were already present and are unchanged here; the
mismatch between MODULE_AUTHOR and the (since-corrected) per-file
copyrights is now resolved.
331 lines
8.1 KiB
C
331 lines
8.1 KiB
C
// SPDX-License-Identifier: GPL-2.0-only
|
|
/*
|
|
* Low-level device I/O for BES2600 mac80211 driver
|
|
*
|
|
* Copyright (c) 2010, ST-Ericsson
|
|
* Author: Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>
|
|
*
|
|
* Copyright (c) 2022, Bestechnic (Beijing) Co., Ltd.
|
|
*
|
|
*/
|
|
|
|
#include <linux/types.h>
|
|
|
|
#include "bes2600.h"
|
|
#include "hwio.h"
|
|
#include "sbus.h"
|
|
#include "bes_log.h"
|
|
|
|
/* Sdio addr is 4*spi_addr */
|
|
#define SPI_REG_ADDR_TO_SDIO(spi_reg_addr) ((spi_reg_addr) << 2)
|
|
#define SDIO_ADDR17BIT(buf_id, mpf, rfu, reg_id_ofs) \
|
|
((((buf_id) & 0x1F) << 7) \
|
|
| (((mpf) & 1) << 6) \
|
|
| (((rfu) & 1) << 5) \
|
|
| (((reg_id_ofs) & 0x1F) << 0))
|
|
#define MAX_RETRY 3
|
|
|
|
static struct sbus_ops *bes2600_subs_ops = NULL;
|
|
static struct sbus_priv *bes2600_sbus_priv = NULL;
|
|
|
|
static int __bes2600_reg_read(u16 addr, void *buf, size_t buf_len, int buf_id)
|
|
{
|
|
u16 addr_sdio;
|
|
u32 sdio_reg_addr_17bit ;
|
|
|
|
/* Check if buffer is aligned to 4 byte boundary */
|
|
if (WARN_ON(((unsigned long)buf & 3) && (buf_len > 4))) {
|
|
bes_err("%s: buffer is not aligned.\n", __func__);
|
|
return -EINVAL;
|
|
}
|
|
|
|
/* Convert to SDIO Register Address */
|
|
addr_sdio = SPI_REG_ADDR_TO_SDIO(addr);
|
|
sdio_reg_addr_17bit = SDIO_ADDR17BIT(buf_id, 0, 0, addr_sdio);
|
|
|
|
BUG_ON(!bes2600_subs_ops);
|
|
return bes2600_subs_ops->sbus_memcpy_fromio(bes2600_sbus_priv,
|
|
sdio_reg_addr_17bit,
|
|
buf, buf_len);
|
|
}
|
|
|
|
static int __bes2600_reg_write(u16 addr, const void *buf, size_t buf_len, int buf_id)
|
|
{
|
|
u16 addr_sdio;
|
|
u32 sdio_reg_addr_17bit ;
|
|
|
|
#if 0
|
|
/* Check if buffer is aligned to 4 byte boundary */
|
|
if (WARN_ON(((unsigned long)buf & 3) && (buf_len > 4))) {
|
|
bes_devel("%s: buffer is not aligned.\n", __func__);
|
|
return -EINVAL;
|
|
}
|
|
#endif
|
|
|
|
/* Convert to SDIO Register Address */
|
|
addr_sdio = SPI_REG_ADDR_TO_SDIO(addr);
|
|
sdio_reg_addr_17bit = SDIO_ADDR17BIT(buf_id, 0, 0, addr_sdio);
|
|
|
|
BUG_ON(!bes2600_subs_ops);
|
|
return bes2600_subs_ops->sbus_memcpy_toio(bes2600_sbus_priv,
|
|
sdio_reg_addr_17bit,
|
|
buf, buf_len);
|
|
}
|
|
|
|
static inline int __bes2600_reg_read_32(u16 addr, u32 *val)
|
|
{
|
|
return __bes2600_reg_read(addr, val, sizeof(val), 0);
|
|
}
|
|
|
|
static inline int __bes2600_reg_write_32(u16 addr, u32 val)
|
|
{
|
|
return __bes2600_reg_write(addr, &val, sizeof(val), 0);
|
|
}
|
|
|
|
void bes2600_reg_set_object(struct sbus_ops *ops, struct sbus_priv *priv)
|
|
{
|
|
bes2600_subs_ops = ops;
|
|
bes2600_sbus_priv = priv;
|
|
}
|
|
|
|
int bes2600_reg_read(u32 addr, void *buf, size_t buf_len)
|
|
{
|
|
int ret;
|
|
BUG_ON(!bes2600_subs_ops);
|
|
bes2600_subs_ops->lock(bes2600_sbus_priv);
|
|
ret = bes2600_subs_ops->sbus_reg_read(bes2600_sbus_priv, addr, buf, buf_len);
|
|
bes2600_subs_ops->unlock(bes2600_sbus_priv);
|
|
return ret;
|
|
}
|
|
|
|
int bes2600_reg_write(u32 addr, const void *buf, size_t buf_len)
|
|
{
|
|
int ret;
|
|
BUG_ON(!bes2600_subs_ops);
|
|
bes2600_subs_ops->lock(bes2600_sbus_priv);
|
|
ret = bes2600_subs_ops->sbus_reg_write(bes2600_sbus_priv, addr, buf, buf_len);
|
|
bes2600_subs_ops->unlock(bes2600_sbus_priv);
|
|
return ret;
|
|
}
|
|
|
|
int bes2600_data_read(void *buf, size_t buf_len)
|
|
{
|
|
int ret, retry = 1;
|
|
BUG_ON(!bes2600_subs_ops);
|
|
bes2600_subs_ops->lock(bes2600_sbus_priv);
|
|
#ifndef CONFIG_BES2600_WLAN_BES
|
|
{
|
|
int buf_id_rx = hw_priv->buf_id_rx;
|
|
while (retry <= MAX_RETRY) {
|
|
ret = __bes2600_reg_read(hw_priv,
|
|
ST90TDS_IN_OUT_QUEUE_REG_ID, buf,
|
|
buf_len, buf_id_rx + 1);
|
|
if (!ret) {
|
|
buf_id_rx = (buf_id_rx + 1) & 3;
|
|
hw_priv->buf_id_rx = buf_id_rx;
|
|
break;
|
|
} else {
|
|
retry++;
|
|
mdelay(1);
|
|
bes_err("%s,error :[%d]\n", __func__, ret);
|
|
}
|
|
}
|
|
}
|
|
#else
|
|
while (retry <= MAX_RETRY) {
|
|
ret = bes2600_subs_ops->sbus_memcpy_fromio(bes2600_sbus_priv,
|
|
BES_TX_DATA_ADDR, buf, buf_len);
|
|
if (ret) {
|
|
retry ++;
|
|
mdelay(1);
|
|
bes_err("%s error :[%d]\n", __func__, ret);
|
|
} else {
|
|
break;
|
|
}
|
|
}
|
|
#endif
|
|
bes2600_subs_ops->unlock(bes2600_sbus_priv);
|
|
return ret;
|
|
}
|
|
|
|
int bes2600_data_write(const void *buf, size_t buf_len)
|
|
{
|
|
int ret, retry = 1;
|
|
u32 addr = 0;
|
|
|
|
BUG_ON(!bes2600_subs_ops);
|
|
bes2600_subs_ops->lock(bes2600_sbus_priv);
|
|
#ifndef CONFIG_BES2600_WLAN_BES
|
|
{
|
|
int buf_id_tx = hw_priv->buf_id_tx;
|
|
while (retry <= MAX_RETRY) {
|
|
ret = __bes2600_reg_write(hw_priv,
|
|
ST90TDS_IN_OUT_QUEUE_REG_ID, buf,
|
|
buf_len, buf_id_tx);
|
|
if (!ret) {
|
|
buf_id_tx = (buf_id_tx + 1) & 31;
|
|
hw_priv->buf_id_tx = buf_id_tx;
|
|
break;
|
|
} else {
|
|
retry++;
|
|
mdelay(1);
|
|
bes_err("%s,error :[%d]\n", __func__, ret);
|
|
}
|
|
}
|
|
}
|
|
#else
|
|
while (retry <= MAX_RETRY) {
|
|
ret = bes2600_subs_ops->sbus_memcpy_toio(bes2600_sbus_priv, addr, buf, buf_len);
|
|
if (ret) {
|
|
retry++;
|
|
mdelay(1);
|
|
bes_err("%s,error :[%d]\n", __func__, ret);
|
|
} else {
|
|
break;
|
|
}
|
|
}
|
|
#endif
|
|
bes2600_subs_ops->unlock(bes2600_sbus_priv);
|
|
return ret;
|
|
}
|
|
|
|
int bes2600_indirect_read(u32 addr, void *buf, size_t buf_len, u32 prefetch, u16 port_addr)
|
|
{
|
|
u32 val32 = 0;
|
|
int i, ret;
|
|
|
|
if ((buf_len / 2) >= 0x1000) {
|
|
bes_err("%s: Can't read more than 0xfff words.\n", __func__);
|
|
WARN_ON(1);
|
|
return -EINVAL;
|
|
goto out;
|
|
}
|
|
|
|
bes2600_subs_ops->lock(bes2600_sbus_priv);
|
|
/* Write address */
|
|
ret = __bes2600_reg_write_32(ST90TDS_SRAM_BASE_ADDR_REG_ID, addr);
|
|
if (ret < 0) {
|
|
bes_err("%s: Can't write address register.\n", __func__);
|
|
goto out;
|
|
}
|
|
|
|
/* Read CONFIG Register Value - We will read 32 bits */
|
|
ret = __bes2600_reg_read_32(ST90TDS_CONFIG_REG_ID, &val32);
|
|
if (ret < 0) {
|
|
bes_err("%s: Can't read config register.\n", __func__);
|
|
goto out;
|
|
}
|
|
|
|
/* Set PREFETCH bit */
|
|
ret = __bes2600_reg_write_32(ST90TDS_CONFIG_REG_ID, val32 | prefetch);
|
|
if (ret < 0) {
|
|
bes_err("%s: Can't write prefetch bit.\n", __func__);
|
|
goto out;
|
|
}
|
|
|
|
/* Check for PRE-FETCH bit to be cleared */
|
|
for (i = 0; i < 20; i++) {
|
|
ret = __bes2600_reg_read_32(ST90TDS_CONFIG_REG_ID, &val32);
|
|
if (ret < 0) {
|
|
bes_err("%s: Can't check prefetch bit.\n", __func__);
|
|
goto out;
|
|
}
|
|
if (!(val32 & prefetch))
|
|
break;
|
|
|
|
mdelay(i);
|
|
}
|
|
|
|
if (val32 & prefetch) {
|
|
bes_err("%s: Prefetch bit is not cleared.\n", __func__);
|
|
goto out;
|
|
}
|
|
|
|
/* Read data port */
|
|
ret = __bes2600_reg_read(port_addr, buf, buf_len, 0);
|
|
if (ret < 0) {
|
|
bes_err("%s: Can't read data port.\n", __func__);
|
|
goto out;
|
|
}
|
|
|
|
out:
|
|
bes2600_subs_ops->unlock(bes2600_sbus_priv);
|
|
return ret;
|
|
}
|
|
|
|
int bes2600_apb_write(u32 addr, const void *buf, size_t buf_len)
|
|
{
|
|
int ret;
|
|
|
|
if ((buf_len / 2) >= 0x1000) {
|
|
bes_err("%s: Can't wrire more than 0xfff words.\n", __func__);
|
|
WARN_ON(1);
|
|
return -EINVAL;
|
|
}
|
|
|
|
bes2600_subs_ops->lock(bes2600_sbus_priv);
|
|
|
|
/* Write address */
|
|
ret = __bes2600_reg_write_32(ST90TDS_SRAM_BASE_ADDR_REG_ID, addr);
|
|
if (ret < 0) {
|
|
bes_err("%s: Can't write address register.\n", __func__);
|
|
goto out;
|
|
}
|
|
|
|
/* Write data port */
|
|
ret = __bes2600_reg_write(ST90TDS_SRAM_DPORT_REG_ID, buf, buf_len, 0);
|
|
if (ret < 0) {
|
|
bes_err("%s: Can't write data port.\n", __func__);
|
|
goto out;
|
|
}
|
|
|
|
out:
|
|
bes2600_subs_ops->unlock(bes2600_sbus_priv);
|
|
return ret;
|
|
}
|
|
|
|
#if defined(BES2600_DETECTION_LOGIC)
|
|
int bes2600_ahb_write(u32 addr, const void *buf, size_t buf_len)
|
|
{
|
|
int ret;
|
|
bes2600_info(BES2600_DBG_SBUS,"%s: ENTER\n",__func__);
|
|
if ((buf_len / 2) >= 0x1000) {
|
|
bes2600_dbg(BES2600_DBG_SBUS,
|
|
"%s: Can't wrire more than 0xfff words.\n",
|
|
__func__);
|
|
WARN_ON(1);
|
|
bes2600_info(BES2600_DBG_SBUS, "%s:EXIT (1) \n",__func__);
|
|
return -EINVAL;
|
|
}
|
|
|
|
bes2600_subs_ops->lock(bes2600_sbus_priv);
|
|
|
|
/* Write address */
|
|
ret = __bes2600_reg_write_32(priv, ST90TDS_SRAM_BASE_ADDR_REG_ID, addr);
|
|
if (ret < 0) {
|
|
bes2600_dbg(BES2600_DBG_SBUS,
|
|
"%s: Can't write address register.\n",
|
|
__func__);
|
|
goto out;
|
|
}
|
|
|
|
/* Write data port */
|
|
ret = __bes2600_reg_write(priv, ST90TDS_AHB_DPORT_REG_ID,
|
|
buf, buf_len, 0);
|
|
if (ret < 0) {
|
|
bes2600_dbg(BES2600_DBG_SBUS, "%s: Can't write data port.\n",
|
|
__func__);
|
|
goto out;
|
|
}
|
|
|
|
out:
|
|
bes2600_subs_ops->unlock(priv->bes2600_sbus_priv);
|
|
return ret;
|
|
}
|
|
#endif
|
|
|
|
int __bes2600_irq_enable(int enable)
|
|
{
|
|
return 0;
|
|
}
|