summaryrefslogtreecommitdiff
path: root/drivers/staging
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/staging')
-rw-r--r--drivers/staging/fbtft/fb_ssd1351.c3
-rw-r--r--drivers/staging/fbtft/fbtft-core.c5
-rw-r--r--drivers/staging/greybus/audio_helper.c14
-rw-r--r--drivers/staging/greybus/fw-management.c6
-rw-r--r--drivers/staging/greybus/loopback.c2
-rw-r--r--drivers/staging/octeon/ethernet-rx.c4
-rw-r--r--drivers/staging/olpc_dcon/olpc_dcon.c7
-rw-r--r--drivers/staging/pi433/pi433_if.c2
-rw-r--r--drivers/staging/qlge/qlge_main.c40
-rw-r--r--drivers/staging/r8188eu/Makefile1
-rw-r--r--drivers/staging/r8188eu/core/rtw_ap.c23
-rw-r--r--drivers/staging/r8188eu/core/rtw_cmd.c15
-rw-r--r--drivers/staging/r8188eu/core/rtw_efuse.c61
-rw-r--r--drivers/staging/r8188eu/core/rtw_fw.c78
-rw-r--r--drivers/staging/r8188eu/core/rtw_ieee80211.c1
-rw-r--r--drivers/staging/r8188eu/core/rtw_ioctl_set.c1
-rw-r--r--drivers/staging/r8188eu/core/rtw_iol.c8
-rw-r--r--drivers/staging/r8188eu/core/rtw_led.c43
-rw-r--r--drivers/staging/r8188eu/core/rtw_mlme.c6
-rw-r--r--drivers/staging/r8188eu/core/rtw_mlme_ext.c464
-rw-r--r--drivers/staging/r8188eu/core/rtw_p2p.c13
-rw-r--r--drivers/staging/r8188eu/core/rtw_pwrctrl.c25
-rw-r--r--drivers/staging/r8188eu/core/rtw_recv.c80
-rw-r--r--drivers/staging/r8188eu/core/rtw_wlan_util.c145
-rw-r--r--drivers/staging/r8188eu/core/rtw_xmit.c34
-rw-r--r--drivers/staging/r8188eu/hal/Hal8188EPwrSeq.c45
-rw-r--r--drivers/staging/r8188eu/hal/Hal8188ERateAdaptive.c33
-rw-r--r--drivers/staging/r8188eu/hal/HalPhyRf_8188e.c21
-rw-r--r--drivers/staging/r8188eu/hal/HalPwrSeqCmd.c118
-rw-r--r--drivers/staging/r8188eu/hal/hal_com.c66
-rw-r--r--drivers/staging/r8188eu/hal/rtl8188e_cmd.c37
-rw-r--r--drivers/staging/r8188eu/hal/rtl8188e_dm.c6
-rw-r--r--drivers/staging/r8188eu/hal/rtl8188e_hal_init.c204
-rw-r--r--drivers/staging/r8188eu/hal/rtl8188e_phycfg.c30
-rw-r--r--drivers/staging/r8188eu/hal/rtl8188eu_recv.c2
-rw-r--r--drivers/staging/r8188eu/hal/usb_halinit.c476
-rw-r--r--drivers/staging/r8188eu/hal/usb_ops_linux.c33
-rw-r--r--drivers/staging/r8188eu/include/Hal8188EPwrSeq.h13
-rw-r--r--drivers/staging/r8188eu/include/Hal8188ERateAdaptive.h13
-rw-r--r--drivers/staging/r8188eu/include/HalPwrSeqCmd.h51
-rw-r--r--drivers/staging/r8188eu/include/basic_types.h52
-rw-r--r--drivers/staging/r8188eu/include/hal_com.h3
-rw-r--r--drivers/staging/r8188eu/include/hal_intf.h20
-rw-r--r--drivers/staging/r8188eu/include/ieee80211.h7
-rw-r--r--drivers/staging/r8188eu/include/osdep_service.h3
-rw-r--r--drivers/staging/r8188eu/include/rtl8188e_hal.h5
-rw-r--r--drivers/staging/r8188eu/include/rtl8188e_spec.h143
-rw-r--r--drivers/staging/r8188eu/include/rtw_eeprom.h10
-rw-r--r--drivers/staging/r8188eu/include/rtw_efuse.h2
-rw-r--r--drivers/staging/r8188eu/include/rtw_io.h8
-rw-r--r--drivers/staging/r8188eu/include/rtw_iol.h24
-rw-r--r--drivers/staging/r8188eu/include/rtw_led.h9
-rw-r--r--drivers/staging/r8188eu/include/rtw_mlme_ext.h19
-rw-r--r--drivers/staging/r8188eu/include/usb_ops_linux.h2
-rw-r--r--drivers/staging/r8188eu/os_dep/ioctl_linux.c83
-rw-r--r--drivers/staging/r8188eu/os_dep/os_intfs.c19
-rw-r--r--drivers/staging/r8188eu/os_dep/osdep_service.c8
-rw-r--r--drivers/staging/r8188eu/os_dep/usb_intf.c2
-rw-r--r--drivers/staging/r8188eu/os_dep/usb_ops_linux.c2
-rw-r--r--drivers/staging/r8188eu/os_dep/xmit_linux.c2
-rw-r--r--drivers/staging/rtl8192e/rtllib_tx.c24
-rw-r--r--drivers/staging/rtl8192e/rtllib_wx.c37
-rw-r--r--drivers/staging/rtl8192u/r8192U.h2
-rw-r--r--drivers/staging/rtl8192u/r8192U_dm.c40
-rw-r--r--drivers/staging/rtl8192u/r8192U_dm.h2
-rw-r--r--drivers/staging/rtl8723bs/core/rtw_mlme_ext.c2
-rw-r--r--drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c225
-rw-r--r--drivers/staging/rts5208/spi.c6
-rw-r--r--drivers/staging/sm750fb/ddk750_dvi.c2
-rw-r--r--drivers/staging/sm750fb/ddk750_power.h2
-rw-r--r--drivers/staging/sm750fb/ddk750_sii164.c6
-rw-r--r--drivers/staging/sm750fb/ddk750_sii164.h2
-rw-r--r--drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c40
-rw-r--r--drivers/staging/vc04_services/include/linux/raspberrypi/vchiq.h48
-rw-r--r--drivers/staging/vc04_services/interface/TESTING82
-rw-r--r--drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c96
-rw-r--r--drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.h8
-rw-r--r--drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.c106
-rw-r--r--drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.h38
-rw-r--r--drivers/staging/vc04_services/interface/vchiq_arm/vchiq_dev.c40
-rw-r--r--drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c63
-rw-r--r--drivers/staging/vme_user/Kconfig27
-rw-r--r--drivers/staging/vme_user/Makefile3
-rw-r--r--drivers/staging/vme_user/vme.c2015
-rw-r--r--drivers/staging/vme_user/vme.h190
-rw-r--r--drivers/staging/vme_user/vme_bridge.h190
-rw-r--r--drivers/staging/vme_user/vme_fake.c1305
-rw-r--r--drivers/staging/vme_user/vme_tsi148.c2661
-rw-r--r--drivers/staging/vme_user/vme_tsi148.h1407
-rw-r--r--drivers/staging/vme_user/vme_user.c2
-rw-r--r--drivers/staging/vt6655/baseband.c10
-rw-r--r--drivers/staging/vt6655/card.c103
-rw-r--r--drivers/staging/vt6655/channel.c2
-rw-r--r--drivers/staging/vt6655/device_main.c88
-rw-r--r--drivers/staging/vt6655/mac.c55
-rw-r--r--drivers/staging/vt6655/mac.h120
-rw-r--r--drivers/staging/vt6655/power.c25
-rw-r--r--drivers/staging/vt6655/rf.c20
-rw-r--r--drivers/staging/vt6655/rxtx.c6
-rw-r--r--drivers/staging/vt6655/srom.c2
-rw-r--r--drivers/staging/vt6655/upc.h35
101 files changed, 9805 insertions, 1984 deletions
diff --git a/drivers/staging/fbtft/fb_ssd1351.c b/drivers/staging/fbtft/fb_ssd1351.c
index 6fd549a424d5..b8d55aa8c5c7 100644
--- a/drivers/staging/fbtft/fb_ssd1351.c
+++ b/drivers/staging/fbtft/fb_ssd1351.c
@@ -196,8 +196,7 @@ static int update_onboard_backlight(struct backlight_device *bd)
"%s: power=%d, fb_blank=%d\n",
__func__, bd->props.power, bd->props.fb_blank);
- on = (bd->props.power == FB_BLANK_UNBLANK) &&
- (bd->props.fb_blank == FB_BLANK_UNBLANK);
+ on = !backlight_is_blank(bd);
/* Onboard backlight connected to GPIO0 on SSD1351, GPIO1 unused */
write_reg(par, 0xB5, on ? 0x03 : 0x02);
diff --git a/drivers/staging/fbtft/fbtft-core.c b/drivers/staging/fbtft/fbtft-core.c
index 60b2278d8b16..afaba94d1d1c 100644
--- a/drivers/staging/fbtft/fbtft-core.c
+++ b/drivers/staging/fbtft/fbtft-core.c
@@ -137,8 +137,7 @@ static int fbtft_backlight_update_status(struct backlight_device *bd)
"%s: polarity=%d, power=%d, fb_blank=%d\n",
__func__, polarity, bd->props.power, bd->props.fb_blank);
- if ((bd->props.power == FB_BLANK_UNBLANK) &&
- (bd->props.fb_blank == FB_BLANK_UNBLANK))
+ if (!backlight_is_blank(bd))
gpiod_set_value(par->gpio.led[0], polarity);
else
gpiod_set_value(par->gpio.led[0], !polarity);
@@ -655,7 +654,6 @@ struct fb_info *fbtft_framebuffer_alloc(struct fbtft_display *display,
fbdefio->delay = HZ / fps;
fbdefio->sort_pagereflist = true;
fbdefio->deferred_io = fbtft_deferred_io;
- fb_deferred_io_init(info);
snprintf(info->fix.id, sizeof(info->fix.id), "%s", dev->driver->name);
info->fix.type = FB_TYPE_PACKED_PIXELS;
@@ -666,6 +664,7 @@ struct fb_info *fbtft_framebuffer_alloc(struct fbtft_display *display,
info->fix.line_length = width * bpp / 8;
info->fix.accel = FB_ACCEL_NONE;
info->fix.smem_len = vmem_size;
+ fb_deferred_io_init(info);
info->var.rotate = pdata->rotate;
info->var.xres = width;
diff --git a/drivers/staging/greybus/audio_helper.c b/drivers/staging/greybus/audio_helper.c
index 843760675876..05e91e6bc2a0 100644
--- a/drivers/staging/greybus/audio_helper.c
+++ b/drivers/staging/greybus/audio_helper.c
@@ -115,7 +115,7 @@ int gbaudio_dapm_free_controls(struct snd_soc_dapm_context *dapm,
int num)
{
int i;
- struct snd_soc_dapm_widget *w, *next_w;
+ struct snd_soc_dapm_widget *w, *tmp_w;
#ifdef CONFIG_DEBUG_FS
struct dentry *parent = dapm->debugfs_dapm;
struct dentry *debugfs_w = NULL;
@@ -124,13 +124,13 @@ int gbaudio_dapm_free_controls(struct snd_soc_dapm_context *dapm,
mutex_lock(&dapm->card->dapm_mutex);
for (i = 0; i < num; i++) {
/* below logic can be optimized to identify widget pointer */
- list_for_each_entry_safe(w, next_w, &dapm->card->widgets,
- list) {
- if (w->dapm != dapm)
- continue;
- if (!strcmp(w->name, widget->name))
+ w = NULL;
+ list_for_each_entry(tmp_w, &dapm->card->widgets, list) {
+ if (tmp_w->dapm == dapm &&
+ !strcmp(tmp_w->name, widget->name)) {
+ w = tmp_w;
break;
- w = NULL;
+ }
}
if (!w) {
dev_err(dapm->dev, "%s: widget not found\n",
diff --git a/drivers/staging/greybus/fw-management.c b/drivers/staging/greybus/fw-management.c
index 687c6405c65b..3342b84597da 100644
--- a/drivers/staging/greybus/fw-management.c
+++ b/drivers/staging/greybus/fw-management.c
@@ -102,7 +102,7 @@ unlock:
}
static int fw_mgmt_interface_fw_version_operation(struct fw_mgmt *fw_mgmt,
- struct fw_mgmt_ioc_get_intf_version *fw_info)
+ struct fw_mgmt_ioc_get_intf_version *fw_info)
{
struct gb_connection *connection = fw_mgmt->connection;
struct gb_fw_mgmt_interface_fw_version_response response;
@@ -240,7 +240,7 @@ static int fw_mgmt_interface_fw_loaded_operation(struct gb_operation *op)
}
static int fw_mgmt_backend_fw_version_operation(struct fw_mgmt *fw_mgmt,
- struct fw_mgmt_ioc_get_backend_version *fw_info)
+ struct fw_mgmt_ioc_get_backend_version *fw_info)
{
struct gb_connection *connection = fw_mgmt->connection;
struct gb_fw_mgmt_backend_fw_version_request request;
@@ -473,7 +473,7 @@ static int fw_mgmt_ioctl(struct fw_mgmt *fw_mgmt, unsigned int cmd,
return -EFAULT;
ret = fw_mgmt_backend_fw_update_operation(fw_mgmt,
- backend_update.firmware_tag);
+ backend_update.firmware_tag);
if (ret)
return ret;
diff --git a/drivers/staging/greybus/loopback.c b/drivers/staging/greybus/loopback.c
index 2471448ba42a..1a61fce98056 100644
--- a/drivers/staging/greybus/loopback.c
+++ b/drivers/staging/greybus/loopback.c
@@ -870,7 +870,7 @@ static int gb_loopback_fn(void *data)
if (gb->send_count == gb->iteration_max) {
mutex_unlock(&gb->mutex);
- /* Wait for synchronous and asynchronus completion */
+ /* Wait for synchronous and asynchronous completion */
gb_loopback_async_wait_all(gb);
/* Mark complete unless user-space has poked us */
diff --git a/drivers/staging/octeon/ethernet-rx.c b/drivers/staging/octeon/ethernet-rx.c
index 9ebd665e5d42..965330eec80a 100644
--- a/drivers/staging/octeon/ethernet-rx.c
+++ b/drivers/staging/octeon/ethernet-rx.c
@@ -469,8 +469,8 @@ void cvm_oct_rx_initialize(void)
if (!(pow_receive_groups & BIT(i)))
continue;
- netif_napi_add(dev_for_napi, &oct_rx_group[i].napi,
- cvm_oct_napi_poll, rx_napi_weight);
+ netif_napi_add_weight(dev_for_napi, &oct_rx_group[i].napi,
+ cvm_oct_napi_poll, rx_napi_weight);
napi_enable(&oct_rx_group[i].napi);
oct_rx_group[i].irq = OCTEON_IRQ_WORKQ0 + i;
diff --git a/drivers/staging/olpc_dcon/olpc_dcon.c b/drivers/staging/olpc_dcon/olpc_dcon.c
index 7284cb4ac395..9363c5cfe50f 100644
--- a/drivers/staging/olpc_dcon/olpc_dcon.c
+++ b/drivers/staging/olpc_dcon/olpc_dcon.c
@@ -383,7 +383,7 @@ static void dcon_set_source(struct dcon_priv *dcon, int arg)
static void dcon_set_source_sync(struct dcon_priv *dcon, int arg)
{
dcon_set_source(dcon, arg);
- flush_scheduled_work();
+ flush_work(&dcon->switch_source);
}
static ssize_t dcon_mode_show(struct device *dev,
@@ -517,10 +517,7 @@ static struct device_attribute dcon_device_files[] = {
static int dcon_bl_update(struct backlight_device *dev)
{
struct dcon_priv *dcon = bl_get_data(dev);
- u8 level = dev->props.brightness & 0x0F;
-
- if (dev->props.power != FB_BLANK_UNBLANK)
- level = 0;
+ u8 level = backlight_get_brightness(dev) & 0x0F;
if (level != dcon->bl_val)
dcon_set_backlight(dcon, level);
diff --git a/drivers/staging/pi433/pi433_if.c b/drivers/staging/pi433/pi433_if.c
index 941aaa7eab2e..df02335fdbab 100644
--- a/drivers/staging/pi433/pi433_if.c
+++ b/drivers/staging/pi433/pi433_if.c
@@ -1406,7 +1406,7 @@ static int __init pi433_init(void)
/*
* Claim device numbers. Then register a class
- * that will key udev/mdev to add/remove /dev nodes. Last, register
+ * that will key udev/mdev to add/remove /dev nodes.
* Last, register the driver which manages those device numbers.
*/
status = alloc_chrdev_region(&pi433_dev, 0, N_PI433_MINORS, "pi433");
diff --git a/drivers/staging/qlge/qlge_main.c b/drivers/staging/qlge/qlge_main.c
index 6cd7fc9589c3..ca6b966f5dd3 100644
--- a/drivers/staging/qlge/qlge_main.c
+++ b/drivers/staging/qlge/qlge_main.c
@@ -1976,7 +1976,7 @@ static unsigned long qlge_process_mac_rx_intr(struct qlge_adapter *qdev,
vlan_id);
} else {
/* Non-TCP/UDP large frames that span multiple buffers
- * can be processed corrrectly by the split frame logic.
+ * can be processed correctly by the split frame logic.
*/
qlge_process_mac_split_rx_intr(qdev, rx_ring, ib_mac_rsp,
vlan_id);
@@ -2955,7 +2955,7 @@ static int qlge_start_rx_ring(struct qlge_adapter *qdev, struct rx_ring *rx_ring
void __iomem *doorbell_area =
qdev->doorbell_area + (DB_PAGE_SIZE * (128 + rx_ring->cq_id));
int err = 0;
- u64 tmp;
+ u64 dma;
__le64 *base_indirect_ptr;
int page_entries;
@@ -3004,15 +3004,15 @@ static int qlge_start_rx_ring(struct qlge_adapter *qdev, struct rx_ring *rx_ring
FLAGS_LI; /* Load irq delay values */
if (rx_ring->cq_id < qdev->rss_ring_count) {
cqicb->flags |= FLAGS_LL; /* Load lbq values */
- tmp = (u64)rx_ring->lbq.base_dma;
+ dma = (u64)rx_ring->lbq.base_dma;
base_indirect_ptr = rx_ring->lbq.base_indirect;
- page_entries = 0;
- do {
- *base_indirect_ptr = cpu_to_le64(tmp);
- tmp += DB_PAGE_SIZE;
- base_indirect_ptr++;
- page_entries++;
- } while (page_entries < MAX_DB_PAGES_PER_BQ(QLGE_BQ_LEN));
+
+ for (page_entries = 0;
+ page_entries < MAX_DB_PAGES_PER_BQ(QLGE_BQ_LEN);
+ page_entries++) {
+ base_indirect_ptr[page_entries] = cpu_to_le64(dma);
+ dma += DB_PAGE_SIZE;
+ }
cqicb->lbq_addr = cpu_to_le64(rx_ring->lbq.base_indirect_dma);
cqicb->lbq_buf_size =
cpu_to_le16(QLGE_FIT16(qdev->lbq_buf_size));
@@ -3021,15 +3021,15 @@ static int qlge_start_rx_ring(struct qlge_adapter *qdev, struct rx_ring *rx_ring
rx_ring->lbq.next_to_clean = 0;
cqicb->flags |= FLAGS_LS; /* Load sbq values */
- tmp = (u64)rx_ring->sbq.base_dma;
+ dma = (u64)rx_ring->sbq.base_dma;
base_indirect_ptr = rx_ring->sbq.base_indirect;
- page_entries = 0;
- do {
- *base_indirect_ptr = cpu_to_le64(tmp);
- tmp += DB_PAGE_SIZE;
- base_indirect_ptr++;
- page_entries++;
- } while (page_entries < MAX_DB_PAGES_PER_BQ(QLGE_BQ_LEN));
+
+ for (page_entries = 0;
+ page_entries < MAX_DB_PAGES_PER_BQ(QLGE_BQ_LEN);
+ page_entries++) {
+ base_indirect_ptr[page_entries] = cpu_to_le64(dma);
+ dma += DB_PAGE_SIZE;
+ }
cqicb->sbq_addr =
cpu_to_le64(rx_ring->sbq.base_indirect_dma);
cqicb->sbq_buf_size = cpu_to_le16(SMALL_BUFFER_SIZE);
@@ -3041,8 +3041,8 @@ static int qlge_start_rx_ring(struct qlge_adapter *qdev, struct rx_ring *rx_ring
/* Inbound completion handling rx_rings run in
* separate NAPI contexts.
*/
- netif_napi_add(qdev->ndev, &rx_ring->napi, qlge_napi_poll_msix,
- 64);
+ netif_napi_add_weight(qdev->ndev, &rx_ring->napi,
+ qlge_napi_poll_msix, 64);
cqicb->irq_delay = cpu_to_le16(qdev->rx_coalesce_usecs);
cqicb->pkt_delay = cpu_to_le16(qdev->rx_max_coalesced_frames);
} else {
diff --git a/drivers/staging/r8188eu/Makefile b/drivers/staging/r8188eu/Makefile
index 1d7982b618ba..eea16eb7caa0 100644
--- a/drivers/staging/r8188eu/Makefile
+++ b/drivers/staging/r8188eu/Makefile
@@ -5,7 +5,6 @@ r8188eu-y = \
hal/HalHWImg8188E_RF.o \
hal/HalPhyRf_8188e.o \
hal/HalPwrSeqCmd.o \
- hal/Hal8188EPwrSeq.o \
hal/Hal8188ERateAdaptive.o \
hal/hal_intf.o \
hal/hal_com.o \
diff --git a/drivers/staging/r8188eu/core/rtw_ap.c b/drivers/staging/r8188eu/core/rtw_ap.c
index ac6effbecf6d..5bd9dfa57cc5 100644
--- a/drivers/staging/r8188eu/core/rtw_ap.c
+++ b/drivers/staging/r8188eu/core/rtw_ap.c
@@ -654,18 +654,17 @@ void update_beacon(struct adapter *padapter, u8 ie_id, u8 *oui, u8 tx)
set_tx_beacon_cmd(padapter);
}
-/*
-op_mode
-Set to 0 (HT pure) under the following conditions
- - all STAs in the BSS are 20/40 MHz HT in 20/40 MHz BSS or
- - all STAs in the BSS are 20 MHz HT in 20 MHz BSS
-Set to 1 (HT non-member protection) if there may be non-HT STAs
- in both the primary and the secondary channel
-Set to 2 if only HT STAs are associated in BSS,
- however and at least one 20 MHz HT STA is associated
-Set to 3 (HT mixed mode) when one or more non-HT STAs are associated
- (currently non-GF HT station is considered as non-HT STA also)
-*/
+/* op_mode
+ * Set to 0 (HT pure) under the following conditions
+ * - all STAs in the BSS are 20/40 MHz HT in 20/40 MHz BSS or
+ * - all STAs in the BSS are 20 MHz HT in 20 MHz BSS
+ * Set to 1 (HT non-member protection) if there may be non-HT STAs
+ * in both the primary and the secondary channel
+ * Set to 2 if only HT STAs are associated in BSS,
+ * however and at least one 20 MHz HT STA is associated
+ * Set to 3 (HT mixed mode) when one or more non-HT STAs are associated
+ * (currently non-GF HT station is considered as non-HT STA also)
+ */
static int rtw_ht_operation_update(struct adapter *padapter)
{
u16 cur_op_mode, new_op_mode;
diff --git a/drivers/staging/r8188eu/core/rtw_cmd.c b/drivers/staging/r8188eu/core/rtw_cmd.c
index 06523d91939a..5b6a891b5d67 100644
--- a/drivers/staging/r8188eu/core/rtw_cmd.c
+++ b/drivers/staging/r8188eu/core/rtw_cmd.c
@@ -898,8 +898,12 @@ static void traffic_status_watchdog(struct adapter *padapter)
static void rtl8188e_sreset_xmit_status_check(struct adapter *padapter)
{
u32 txdma_status;
+ int res;
+
+ res = rtw_read32(padapter, REG_TXDMA_STATUS, &txdma_status);
+ if (res)
+ return;
- txdma_status = rtw_read32(padapter, REG_TXDMA_STATUS);
if (txdma_status != 0x00)
rtw_write32(padapter, REG_TXDMA_STATUS, txdma_status);
/* total xmit irp = 4 */
@@ -1177,7 +1181,14 @@ exit:
static bool rtw_is_hi_queue_empty(struct adapter *adapter)
{
- return (rtw_read32(adapter, REG_HGQ_INFORMATION) & 0x0000ff00) == 0;
+ int res;
+ u32 reg;
+
+ res = rtw_read32(adapter, REG_HGQ_INFORMATION, &reg);
+ if (res)
+ return false;
+
+ return (reg & 0x0000ff00) == 0;
}
static void rtw_chk_hi_queue_hdl(struct adapter *padapter)
diff --git a/drivers/staging/r8188eu/core/rtw_efuse.c b/drivers/staging/r8188eu/core/rtw_efuse.c
index 0e0e60638880..df9534dd25cb 100644
--- a/drivers/staging/r8188eu/core/rtw_efuse.c
+++ b/drivers/staging/r8188eu/core/rtw_efuse.c
@@ -28,22 +28,35 @@ ReadEFuseByte(
u32 value32;
u8 readbyte;
u16 retry;
+ int res;
/* Write Address */
rtw_write8(Adapter, EFUSE_CTRL + 1, (_offset & 0xff));
- readbyte = rtw_read8(Adapter, EFUSE_CTRL + 2);
+ res = rtw_read8(Adapter, EFUSE_CTRL + 2, &readbyte);
+ if (res)
+ return;
+
rtw_write8(Adapter, EFUSE_CTRL + 2, ((_offset >> 8) & 0x03) | (readbyte & 0xfc));
/* Write bit 32 0 */
- readbyte = rtw_read8(Adapter, EFUSE_CTRL + 3);
+ res = rtw_read8(Adapter, EFUSE_CTRL + 3, &readbyte);
+ if (res)
+ return;
+
rtw_write8(Adapter, EFUSE_CTRL + 3, (readbyte & 0x7f));
/* Check bit 32 read-ready */
- retry = 0;
- value32 = rtw_read32(Adapter, EFUSE_CTRL);
- while (!(((value32 >> 24) & 0xff) & 0x80) && (retry < 10000)) {
- value32 = rtw_read32(Adapter, EFUSE_CTRL);
- retry++;
+ res = rtw_read32(Adapter, EFUSE_CTRL, &value32);
+ if (res)
+ return;
+
+ for (retry = 0; retry < 10000; retry++) {
+ res = rtw_read32(Adapter, EFUSE_CTRL, &value32);
+ if (res)
+ continue;
+
+ if (((value32 >> 24) & 0xff) & 0x80)
+ break;
}
/* 20100205 Joseph: Add delay suggested by SD1 Victor. */
@@ -51,37 +64,11 @@ ReadEFuseByte(
/* Designer says that there shall be some delay after ready bit is set, or the */
/* result will always stay on last data we read. */
udelay(50);
- value32 = rtw_read32(Adapter, EFUSE_CTRL);
+ res = rtw_read32(Adapter, EFUSE_CTRL, &value32);
+ if (res)
+ return;
*pbuf = (u8)(value32 & 0xff);
-}
-
-/*-----------------------------------------------------------------------------
- * Function: EFUSE_ShadowMapUpdate
- *
- * Overview: Transfer current EFUSE content to shadow init and modify map.
- *
- * Input: NONE
- *
- * Output: NONE
- *
- * Return: NONE
- *
- * Revised History:
- * When Who Remark
- * 11/13/2008 MHC Create Version 0.
- *
- *---------------------------------------------------------------------------*/
-void EFUSE_ShadowMapUpdate(struct adapter *pAdapter)
-{
- struct eeprom_priv *pEEPROM = &pAdapter->eeprompriv;
-
- if (pEEPROM->bautoload_fail_flag) {
- memset(pEEPROM->efuse_eeprom_data, 0xFF, EFUSE_MAP_LEN_88E);
- return;
- }
- rtl8188e_EfusePowerSwitch(pAdapter, true);
- rtl8188e_ReadEFuse(pAdapter, 0, EFUSE_MAP_LEN_88E, pEEPROM->efuse_eeprom_data);
- rtl8188e_EfusePowerSwitch(pAdapter, false);
+ /* FIXME: return an error to caller */
}
diff --git a/drivers/staging/r8188eu/core/rtw_fw.c b/drivers/staging/r8188eu/core/rtw_fw.c
index 0451e5177644..95534f9c7a0f 100644
--- a/drivers/staging/r8188eu/core/rtw_fw.c
+++ b/drivers/staging/r8188eu/core/rtw_fw.c
@@ -44,18 +44,28 @@ static_assert(sizeof(struct rt_firmware_hdr) == 32);
static void fw_download_enable(struct adapter *padapter, bool enable)
{
u8 tmp;
+ int res;
if (enable) {
/* MCU firmware download enable. */
- tmp = rtw_read8(padapter, REG_MCUFWDL);
+ res = rtw_read8(padapter, REG_MCUFWDL, &tmp);
+ if (res)
+ return;
+
rtw_write8(padapter, REG_MCUFWDL, tmp | 0x01);
/* 8051 reset */
- tmp = rtw_read8(padapter, REG_MCUFWDL + 2);
+ res = rtw_read8(padapter, REG_MCUFWDL + 2, &tmp);
+ if (res)
+ return;
+
rtw_write8(padapter, REG_MCUFWDL + 2, tmp & 0xf7);
} else {
/* MCU firmware download disable. */
- tmp = rtw_read8(padapter, REG_MCUFWDL);
+ res = rtw_read8(padapter, REG_MCUFWDL, &tmp);
+ if (res)
+ return;
+
rtw_write8(padapter, REG_MCUFWDL, tmp & 0xfe);
/* Reserved for fw extension. */
@@ -125,8 +135,13 @@ static int page_write(struct adapter *padapter, u32 page, u8 *buffer, u32 size)
{
u8 value8;
u8 u8Page = (u8)(page & 0x07);
+ int res;
+
+ res = rtw_read8(padapter, REG_MCUFWDL + 2, &value8);
+ if (res)
+ return _FAIL;
- value8 = (rtw_read8(padapter, REG_MCUFWDL + 2) & 0xF8) | u8Page;
+ value8 = (value8 & 0xF8) | u8Page;
rtw_write8(padapter, REG_MCUFWDL + 2, value8);
return block_write(padapter, buffer, size);
@@ -165,8 +180,12 @@ exit:
void rtw_reset_8051(struct adapter *padapter)
{
u8 val8;
+ int res;
+
+ res = rtw_read8(padapter, REG_SYS_FUNC_EN + 1, &val8);
+ if (res)
+ return;
- val8 = rtw_read8(padapter, REG_SYS_FUNC_EN + 1);
rtw_write8(padapter, REG_SYS_FUNC_EN + 1, val8 & (~BIT(2)));
rtw_write8(padapter, REG_SYS_FUNC_EN + 1, val8 | (BIT(2)));
}
@@ -175,10 +194,14 @@ static int fw_free_to_go(struct adapter *padapter)
{
u32 counter = 0;
u32 value32;
+ int res;
/* polling CheckSum report */
do {
- value32 = rtw_read32(padapter, REG_MCUFWDL);
+ res = rtw_read32(padapter, REG_MCUFWDL, &value32);
+ if (res)
+ continue;
+
if (value32 & FWDL_CHKSUM_RPT)
break;
} while (counter++ < POLLING_READY_TIMEOUT_COUNT);
@@ -186,7 +209,10 @@ static int fw_free_to_go(struct adapter *padapter)
if (counter >= POLLING_READY_TIMEOUT_COUNT)
return _FAIL;
- value32 = rtw_read32(padapter, REG_MCUFWDL);
+ res = rtw_read32(padapter, REG_MCUFWDL, &value32);
+ if (res)
+ return _FAIL;
+
value32 |= MCUFWDL_RDY;
value32 &= ~WINTINI_RDY;
rtw_write32(padapter, REG_MCUFWDL, value32);
@@ -196,9 +222,10 @@ static int fw_free_to_go(struct adapter *padapter)
/* polling for FW ready */
counter = 0;
do {
- value32 = rtw_read32(padapter, REG_MCUFWDL);
- if (value32 & WINTINI_RDY)
+ res = rtw_read32(padapter, REG_MCUFWDL, &value32);
+ if (!res && value32 & WINTINI_RDY)
return _SUCCESS;
+
udelay(5);
} while (counter++ < POLLING_READY_TIMEOUT_COUNT);
@@ -239,7 +266,7 @@ exit:
int rtl8188e_firmware_download(struct adapter *padapter)
{
int ret = _SUCCESS;
- u8 write_fw_retry = 0;
+ u8 reg;
unsigned long fwdl_timeout;
struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
struct device *device = dvobj_to_dev(dvobj);
@@ -259,9 +286,9 @@ int rtl8188e_firmware_download(struct adapter *padapter)
fwhdr = (struct rt_firmware_hdr *)dvobj->firmware.data;
if (IS_FW_HEADER_EXIST(fwhdr)) {
- pr_info_once("R8188EU: Firmware Version %d, SubVersion %d, Signature 0x%x\n",
- le16_to_cpu(fwhdr->version), fwhdr->subversion,
- le16_to_cpu(fwhdr->signature));
+ dev_info_once(device, "Firmware Version %d, SubVersion %d, Signature 0x%x\n",
+ le16_to_cpu(fwhdr->version), fwhdr->subversion,
+ le16_to_cpu(fwhdr->signature));
fw_data = fw_data + sizeof(struct rt_firmware_hdr);
fw_size = fw_size - sizeof(struct rt_firmware_hdr);
@@ -269,23 +296,34 @@ int rtl8188e_firmware_download(struct adapter *padapter)
/* Suggested by Filen. If 8051 is running in RAM code, driver should inform Fw to reset by itself, */
/* or it will cause download Fw fail. 2010.02.01. by tynli. */
- if (rtw_read8(padapter, REG_MCUFWDL) & RAM_DL_SEL) { /* 8051 RAM code */
+ ret = rtw_read8(padapter, REG_MCUFWDL, &reg);
+ if (ret) {
+ ret = _FAIL;
+ goto exit;
+ }
+
+ if (reg & RAM_DL_SEL) { /* 8051 RAM code */
rtw_write8(padapter, REG_MCUFWDL, 0x00);
rtw_reset_8051(padapter);
}
fw_download_enable(padapter, true);
fwdl_timeout = jiffies + msecs_to_jiffies(500);
- while (1) {
+ do {
/* reset the FWDL chksum */
- rtw_write8(padapter, REG_MCUFWDL, rtw_read8(padapter, REG_MCUFWDL) | FWDL_CHKSUM_RPT);
+ ret = rtw_read8(padapter, REG_MCUFWDL, &reg);
+ if (ret) {
+ ret = _FAIL;
+ continue;
+ }
- ret = write_fw(padapter, fw_data, fw_size);
+ rtw_write8(padapter, REG_MCUFWDL, reg | FWDL_CHKSUM_RPT);
- if (ret == _SUCCESS ||
- (time_after(jiffies, fwdl_timeout) && write_fw_retry++ >= 3))
+ ret = write_fw(padapter, fw_data, fw_size);
+ if (ret == _SUCCESS)
break;
- }
+ } while (!time_after(jiffies, fwdl_timeout));
+
fw_download_enable(padapter, false);
if (ret != _SUCCESS)
goto exit;
diff --git a/drivers/staging/r8188eu/core/rtw_ieee80211.c b/drivers/staging/r8188eu/core/rtw_ieee80211.c
index 385a9ed8eff7..bc8543ea2e66 100644
--- a/drivers/staging/r8188eu/core/rtw_ieee80211.c
+++ b/drivers/staging/r8188eu/core/rtw_ieee80211.c
@@ -1048,6 +1048,7 @@ static int rtw_get_cipher_info(struct wlan_network *pnetwork)
unsigned char *pbuf;
int group_cipher = 0, pairwise_cipher = 0, is8021x = 0;
int ret = _FAIL;
+
pbuf = rtw_get_wpa_ie(&pnetwork->network.IEs[12], &wpa_ielen, pnetwork->network.IELength - 12);
if (pbuf && (wpa_ielen > 0)) {
diff --git a/drivers/staging/r8188eu/core/rtw_ioctl_set.c b/drivers/staging/r8188eu/core/rtw_ioctl_set.c
index 7ba75f73e47e..17f6bcbeebf4 100644
--- a/drivers/staging/r8188eu/core/rtw_ioctl_set.c
+++ b/drivers/staging/r8188eu/core/rtw_ioctl_set.c
@@ -71,7 +71,6 @@ u8 rtw_do_join(struct adapter *padapter)
pibss = padapter->registrypriv.dev_network.MacAddress;
- memset(&pdev_network->Ssid, 0, sizeof(struct ndis_802_11_ssid));
memcpy(&pdev_network->Ssid, &pmlmepriv->assoc_ssid, sizeof(struct ndis_802_11_ssid));
rtw_update_registrypriv_dev_network(padapter);
diff --git a/drivers/staging/r8188eu/core/rtw_iol.c b/drivers/staging/r8188eu/core/rtw_iol.c
index af8e84a41b85..31e196ccd899 100644
--- a/drivers/staging/r8188eu/core/rtw_iol.c
+++ b/drivers/staging/r8188eu/core/rtw_iol.c
@@ -67,7 +67,7 @@ bool rtw_IOL_applied(struct adapter *adapter)
return false;
}
-int _rtw_IOL_append_WB_cmd(struct xmit_frame *xmit_frame, u16 addr, u8 value, u8 mask)
+int rtw_IOL_append_WB_cmd(struct xmit_frame *xmit_frame, u16 addr, u8 value, u8 mask)
{
struct ioreg_cfg cmd = {8, IOREG_CMD_WB_REG, 0x0, 0x0, 0x0};
@@ -81,7 +81,7 @@ int _rtw_IOL_append_WB_cmd(struct xmit_frame *xmit_frame, u16 addr, u8 value, u8
return rtw_IOL_append_cmds(xmit_frame, (u8 *)&cmd, cmd.length);
}
-int _rtw_IOL_append_WW_cmd(struct xmit_frame *xmit_frame, u16 addr, u16 value, u16 mask)
+int rtw_IOL_append_WW_cmd(struct xmit_frame *xmit_frame, u16 addr, u16 value, u16 mask)
{
struct ioreg_cfg cmd = {8, IOREG_CMD_WW_REG, 0x0, 0x0, 0x0};
@@ -95,7 +95,7 @@ int _rtw_IOL_append_WW_cmd(struct xmit_frame *xmit_frame, u16 addr, u16 value, u
return rtw_IOL_append_cmds(xmit_frame, (u8 *)&cmd, cmd.length);
}
-int _rtw_IOL_append_WD_cmd(struct xmit_frame *xmit_frame, u16 addr, u32 value, u32 mask)
+int rtw_IOL_append_WD_cmd(struct xmit_frame *xmit_frame, u16 addr, u32 value, u32 mask)
{
struct ioreg_cfg cmd = {8, IOREG_CMD_WD_REG, 0x0, 0x0, 0x0};
@@ -109,7 +109,7 @@ int _rtw_IOL_append_WD_cmd(struct xmit_frame *xmit_frame, u16 addr, u32 value, u
return rtw_IOL_append_cmds(xmit_frame, (u8 *)&cmd, cmd.length);
}
-int _rtw_IOL_append_WRF_cmd(struct xmit_frame *xmit_frame, u8 rf_path, u16 addr, u32 value, u32 mask)
+int rtw_IOL_append_WRF_cmd(struct xmit_frame *xmit_frame, u8 rf_path, u16 addr, u32 value, u32 mask)
{
struct ioreg_cfg cmd = {8, IOREG_CMD_W_RF, 0x0, 0x0, 0x0};
diff --git a/drivers/staging/r8188eu/core/rtw_led.c b/drivers/staging/r8188eu/core/rtw_led.c
index 2f3000428af7..d5c6c5e29621 100644
--- a/drivers/staging/r8188eu/core/rtw_led.c
+++ b/drivers/staging/r8188eu/core/rtw_led.c
@@ -16,7 +16,7 @@
(l)->CurrLedState == LED_BLINK_WPS_STOP || \
(l)->bLedWPSBlinkInProgress)
-static void ResetLedStatus(struct LED_871x *pLed)
+static void ResetLedStatus(struct led_priv *pLed)
{
pLed->CurrLedState = RTW_LED_OFF; /* Current LED state. */
pLed->bLedOn = false; /* true if LED is ON, false if LED is OFF. */
@@ -32,30 +32,40 @@ static void ResetLedStatus(struct LED_871x *pLed)
pLed->bLedScanBlinkInProgress = false;
}
-static void SwLedOn(struct adapter *padapter, struct LED_871x *pLed)
+static void SwLedOn(struct adapter *padapter, struct led_priv *pLed)
{
u8 LedCfg;
+ int res;
if (padapter->bSurpriseRemoved || padapter->bDriverStopped)
return;
- LedCfg = rtw_read8(padapter, REG_LEDCFG2);
+ res = rtw_read8(padapter, REG_LEDCFG2, &LedCfg);
+ if (res)
+ return;
+
rtw_write8(padapter, REG_LEDCFG2, (LedCfg & 0xf0) | BIT(5) | BIT(6)); /* SW control led0 on. */
pLed->bLedOn = true;
}
-static void SwLedOff(struct adapter *padapter, struct LED_871x *pLed)
+static void SwLedOff(struct adapter *padapter, struct led_priv *pLed)
{
u8 LedCfg;
+ int res;
if (padapter->bSurpriseRemoved || padapter->bDriverStopped)
goto exit;
- LedCfg = rtw_read8(padapter, REG_LEDCFG2);/* 0x4E */
+ res = rtw_read8(padapter, REG_LEDCFG2, &LedCfg);/* 0x4E */
+ if (res)
+ goto exit;
LedCfg &= 0x90; /* Set to software control. */
rtw_write8(padapter, REG_LEDCFG2, (LedCfg | BIT(3)));
- LedCfg = rtw_read8(padapter, REG_MAC_PINMUX_CFG);
+ res = rtw_read8(padapter, REG_MAC_PINMUX_CFG, &LedCfg);
+ if (res)
+ goto exit;
+
LedCfg &= 0xFE;
rtw_write8(padapter, REG_MAC_PINMUX_CFG, LedCfg);
exit:
@@ -65,7 +75,7 @@ exit:
static void blink_work(struct work_struct *work)
{
struct delayed_work *dwork = to_delayed_work(work);
- struct LED_871x *pLed = container_of(dwork, struct LED_871x, blink_work);
+ struct led_priv *pLed = container_of(dwork, struct led_priv, blink_work);
struct adapter *padapter = pLed->padapter;
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
@@ -172,35 +182,32 @@ static void blink_work(struct work_struct *work)
void rtl8188eu_InitSwLeds(struct adapter *padapter)
{
struct led_priv *pledpriv = &padapter->ledpriv;
- struct LED_871x *pLed = &pledpriv->SwLed0;
- pLed->padapter = padapter;
- ResetLedStatus(pLed);
- INIT_DELAYED_WORK(&pLed->blink_work, blink_work);
+ pledpriv->padapter = padapter;
+ ResetLedStatus(pledpriv);
+ INIT_DELAYED_WORK(&pledpriv->blink_work, blink_work);
}
void rtl8188eu_DeInitSwLeds(struct adapter *padapter)
{
struct led_priv *ledpriv = &padapter->ledpriv;
- struct LED_871x *pLed = &ledpriv->SwLed0;
- cancel_delayed_work_sync(&pLed->blink_work);
- ResetLedStatus(pLed);
- SwLedOff(padapter, pLed);
+ cancel_delayed_work_sync(&ledpriv->blink_work);
+ ResetLedStatus(ledpriv);
+ SwLedOff(padapter, ledpriv);
}
void rtw_led_control(struct adapter *padapter, enum LED_CTL_MODE LedAction)
{
- struct led_priv *ledpriv = &padapter->ledpriv;
+ struct led_priv *pLed = &padapter->ledpriv;
struct registry_priv *registry_par;
- struct LED_871x *pLed = &ledpriv->SwLed0;
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
if ((padapter->bSurpriseRemoved) || (padapter->bDriverStopped) ||
(!padapter->hw_init_completed))
return;
- if (!ledpriv->bRegUseLed)
+ if (!pLed->bRegUseLed)
return;
registry_par = &padapter->registrypriv;
diff --git a/drivers/staging/r8188eu/core/rtw_mlme.c b/drivers/staging/r8188eu/core/rtw_mlme.c
index 5a815642c3f6..2705c9d87b14 100644
--- a/drivers/staging/r8188eu/core/rtw_mlme.c
+++ b/drivers/staging/r8188eu/core/rtw_mlme.c
@@ -676,7 +676,6 @@ void rtw_surveydone_event_callback(struct adapter *adapter, u8 *pbuf)
_clr_fwstate_(pmlmepriv, _FW_UNDER_SURVEY);
- memset(&pdev_network->Ssid, 0, sizeof(struct ndis_802_11_ssid));
memcpy(&pdev_network->Ssid, &pmlmepriv->assoc_ssid, sizeof(struct ndis_802_11_ssid));
rtw_update_registrypriv_dev_network(adapter);
@@ -1118,7 +1117,7 @@ void rtw_sta_media_status_rpt(struct adapter *adapter, struct sta_info *psta,
/* MACID|OPMODE:1 connect */
media_status_rpt = (u16)((psta->mac_id << 8) | mstatus);
- SetHwReg8188EU(adapter, HW_VAR_H2C_MEDIA_STATUS_RPT, (u8 *)&media_status_rpt);
+ rtl8188e_set_FwMediaStatus_cmd(adapter, media_status_rpt);
}
void rtw_stassoc_event_callback(struct adapter *adapter, u8 *pbuf)
@@ -1196,7 +1195,7 @@ void rtw_stadel_event_callback(struct adapter *adapter, u8 *pbuf)
u16 media_status;
media_status = (mac_id << 8) | 0; /* MACID|OPMODE:0 means disconnect */
/* for STA, AP, ADHOC mode, report disconnect stauts to FW */
- SetHwReg8188EU(adapter, HW_VAR_H2C_MEDIA_STATUS_RPT, (u8 *)&media_status);
+ rtl8188e_set_FwMediaStatus_cmd(adapter, media_status);
}
if (check_fwstate(pmlmepriv, WIFI_AP_STATE))
@@ -1253,7 +1252,6 @@ void rtw_stadel_event_callback(struct adapter *adapter, u8 *pbuf)
memcpy(pdev_network, &tgt_network->network, get_wlan_bssid_ex_sz(&tgt_network->network));
- memset(&pdev_network->Ssid, 0, sizeof(struct ndis_802_11_ssid));
memcpy(&pdev_network->Ssid, &pmlmepriv->assoc_ssid, sizeof(struct ndis_802_11_ssid));
rtw_update_registrypriv_dev_network(adapter);
diff --git a/drivers/staging/r8188eu/core/rtw_mlme_ext.c b/drivers/staging/r8188eu/core/rtw_mlme_ext.c
index faf23fc950c5..32d0e101d0c2 100644
--- a/drivers/staging/r8188eu/core/rtw_mlme_ext.c
+++ b/drivers/staging/r8188eu/core/rtw_mlme_ext.c
@@ -428,6 +428,58 @@ static u32 p2p_listen_state_process(struct adapter *padapter, unsigned char *da)
return _SUCCESS;
}
+static void update_TSF(struct mlme_ext_priv *pmlmeext, u8 *pframe)
+{
+ u8 *pIE;
+ __le32 *pbuf;
+
+ pIE = pframe + sizeof(struct ieee80211_hdr_3addr);
+ pbuf = (__le32 *)pIE;
+
+ pmlmeext->TSFValue = le32_to_cpu(*(pbuf + 1));
+
+ pmlmeext->TSFValue = pmlmeext->TSFValue << 32;
+
+ pmlmeext->TSFValue |= le32_to_cpu(*pbuf);
+}
+
+static void correct_TSF(struct adapter *padapter)
+{
+ u8 reg;
+ int res;
+ u64 tsf;
+ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
+ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
+
+ tsf = pmlmeext->TSFValue - do_div(pmlmeext->TSFValue,
+ pmlmeinfo->bcn_interval * 1024) - 1024; /* us */
+
+ if (((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE) ||
+ ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE))
+ rtw_stop_tx_beacon(padapter);
+
+ /* disable related TSF function */
+ res = rtw_read8(padapter, REG_BCN_CTRL, &reg);
+ if (res)
+ return;
+
+ rtw_write8(padapter, REG_BCN_CTRL, reg & (~BIT(3)));
+
+ rtw_write32(padapter, REG_TSFTR, tsf);
+ rtw_write32(padapter, REG_TSFTR + 4, tsf >> 32);
+
+ /* enable related TSF function */
+ res = rtw_read8(padapter, REG_BCN_CTRL, &reg);
+ if (res)
+ return;
+
+ rtw_write8(padapter, REG_BCN_CTRL, reg | BIT(3));
+
+ if (((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE) ||
+ ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE))
+ rtw_resume_tx_beacon(padapter);
+}
+
/****************************************************************************
Following are the callback functions for each subtype of the management frames
@@ -582,7 +634,7 @@ unsigned int OnBeacon(struct adapter *padapter, struct recv_frame *precv_frame)
pmlmeinfo->assoc_AP_vendor = check_assoc_AP(pframe + sizeof(struct ieee80211_hdr_3addr), len - sizeof(struct ieee80211_hdr_3addr));
/* update TSF Value */
- update_TSF(pmlmeext, pframe, len);
+ update_TSF(pmlmeext, pframe);
/* start auth */
start_clnt_auth(padapter);
@@ -625,7 +677,7 @@ unsigned int OnBeacon(struct adapter *padapter, struct recv_frame *precv_frame)
}
/* update TSF Value */
- update_TSF(pmlmeext, pframe, len);
+ update_TSF(pmlmeext, pframe);
/* report sta add event */
report_add_sta_event(padapter, GetAddr2Ptr(pframe), cam_idx);
@@ -5363,26 +5415,20 @@ exit:
return ret;
}
-void issue_action_BA(struct adapter *padapter, unsigned char *raddr, unsigned char action, unsigned short status)
+void issue_action_BA(struct adapter *padapter, unsigned char *raddr, u8 action, u16 status)
{
- u8 category = WLAN_CATEGORY_BACK;
u16 start_seq;
- u16 BA_para_set;
- u16 reason_code;
- u16 BA_timeout_value;
- __le16 le_tmp;
u16 BA_starting_seqctrl = 0;
struct xmit_frame *pmgntframe;
struct pkt_attrib *pattrib;
- u8 *pframe;
- struct ieee80211_hdr *pwlanhdr;
- __le16 *fctrl;
struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
struct sta_info *psta;
struct sta_priv *pstapriv = &padapter->stapriv;
struct registry_priv *pregpriv = &padapter->registrypriv;
+ struct ieee80211_mgmt *mgmt;
+ u16 capab, params;
pmgntframe = alloc_mgtxmitframe(pxmitpriv);
if (!pmgntframe)
@@ -5394,81 +5440,70 @@ void issue_action_BA(struct adapter *padapter, unsigned char *raddr, unsigned ch
memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
- pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
- pwlanhdr = (struct ieee80211_hdr *)pframe;
+ mgmt = (struct ieee80211_mgmt *)(pmgntframe->buf_addr + TXDESC_OFFSET);
- fctrl = &pwlanhdr->frame_control;
- *(fctrl) = 0;
+ mgmt->frame_control = cpu_to_le16(IEEE80211_STYPE_ACTION | IEEE80211_FTYPE_MGMT);
- /* memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN); */
- memcpy(pwlanhdr->addr1, raddr, ETH_ALEN);
- memcpy(pwlanhdr->addr2, myid(&padapter->eeprompriv), ETH_ALEN);
- memcpy(pwlanhdr->addr3, get_my_bssid(&pmlmeinfo->network), ETH_ALEN);
+ memcpy(mgmt->da, raddr, ETH_ALEN);
+ memcpy(mgmt->sa, myid(&padapter->eeprompriv), ETH_ALEN);
+ memcpy(mgmt->bssid, get_my_bssid(&pmlmeinfo->network), ETH_ALEN);
- SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
+ mgmt->seq_ctrl = cpu_to_le16(pmlmeext->mgnt_seq);
pmlmeext->mgnt_seq++;
- SetFrameSubType(pframe, WIFI_ACTION);
-
- pframe += sizeof(struct ieee80211_hdr_3addr);
- pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr);
- pframe = rtw_set_fixed_ie(pframe, 1, &(category), &pattrib->pktlen);
- pframe = rtw_set_fixed_ie(pframe, 1, &(action), &pattrib->pktlen);
+ mgmt->u.action.category = WLAN_CATEGORY_BACK;
- if (category == 3) {
- switch (action) {
- case 0: /* ADDBA req */
- do {
- pmlmeinfo->dialogToken++;
- } while (pmlmeinfo->dialogToken == 0);
- pframe = rtw_set_fixed_ie(pframe, 1, &pmlmeinfo->dialogToken, &pattrib->pktlen);
+ switch (action) {
+ case WLAN_ACTION_ADDBA_REQ:
+ mgmt->u.action.u.addba_req.action_code = WLAN_ACTION_ADDBA_REQ;
+ do {
+ pmlmeinfo->dialogToken++;
+ } while (pmlmeinfo->dialogToken == 0);
+ mgmt->u.action.u.addba_req.dialog_token = pmlmeinfo->dialogToken;
- BA_para_set = (0x1002 | ((status & 0xf) << 2)); /* immediate ack & 64 buffer size */
- le_tmp = cpu_to_le16(BA_para_set);
- pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)&le_tmp, &pattrib->pktlen);
+ /* immediate ack & 64 buffer size */
+ capab = u16_encode_bits(64, IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK);
+ capab |= u16_encode_bits(1, IEEE80211_ADDBA_PARAM_POLICY_MASK);
+ capab |= u16_encode_bits(status, IEEE80211_ADDBA_PARAM_TID_MASK);
+ mgmt->u.action.u.addba_req.capab = cpu_to_le16(capab);
- BA_timeout_value = 5000;/* 5ms */
- le_tmp = cpu_to_le16(BA_timeout_value);
- pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)&le_tmp, &pattrib->pktlen);
+ mgmt->u.action.u.addba_req.timeout = cpu_to_le16(5000); /* 5 ms */
- psta = rtw_get_stainfo(pstapriv, raddr);
- if (psta) {
- start_seq = (psta->sta_xmitpriv.txseq_tid[status & 0x07] & 0xfff) + 1;
+ psta = rtw_get_stainfo(pstapriv, raddr);
+ if (psta) {
+ start_seq = (psta->sta_xmitpriv.txseq_tid[status & 0x07] & 0xfff) + 1;
- psta->BA_starting_seqctrl[status & 0x07] = start_seq;
+ psta->BA_starting_seqctrl[status & 0x07] = start_seq;
- BA_starting_seqctrl = start_seq << 4;
- }
- le_tmp = cpu_to_le16(BA_starting_seqctrl);
- pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)&le_tmp, &pattrib->pktlen);
- break;
- case 1: /* ADDBA rsp */
- pframe = rtw_set_fixed_ie(pframe, 1, &pmlmeinfo->ADDBA_req.dialog_token, &pattrib->pktlen);
- pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)&status, &pattrib->pktlen);
- BA_para_set = le16_to_cpu(pmlmeinfo->ADDBA_req.BA_para_set) & 0x3f;
- BA_para_set |= 0x1000; /* 64 buffer size */
-
- if (pregpriv->ampdu_amsdu == 0)/* disabled */
- BA_para_set = BA_para_set & ~BIT(0);
- else if (pregpriv->ampdu_amsdu == 1)/* enabled */
- BA_para_set = BA_para_set | BIT(0);
- le_tmp = cpu_to_le16(BA_para_set);
-
- pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)&le_tmp, &pattrib->pktlen);
- pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)&pmlmeinfo->ADDBA_req.BA_timeout_value, &pattrib->pktlen);
- break;
- case 2:/* DELBA */
- BA_para_set = (status & 0x1F) << 3;
- le_tmp = cpu_to_le16(BA_para_set);
- pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)&le_tmp, &pattrib->pktlen);
-
- reason_code = 37;/* Requested from peer STA as it does not want to use the mechanism */
- le_tmp = cpu_to_le16(reason_code);
- pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)&le_tmp, &pattrib->pktlen);
- break;
- default:
- break;
+ BA_starting_seqctrl = start_seq << 4;
}
+ mgmt->u.action.u.addba_req.start_seq_num = cpu_to_le16(BA_starting_seqctrl);
+
+ pattrib->pktlen = offsetofend(struct ieee80211_mgmt,
+ u.action.u.addba_req.start_seq_num);
+ break;
+ case WLAN_ACTION_ADDBA_RESP:
+ mgmt->u.action.u.addba_resp.action_code = WLAN_ACTION_ADDBA_RESP;
+ mgmt->u.action.u.addba_resp.dialog_token = pmlmeinfo->ADDBA_req.dialog_token;
+ mgmt->u.action.u.addba_resp.status = cpu_to_le16(status);
+ capab = le16_to_cpu(pmlmeinfo->ADDBA_req.BA_para_set) & 0x3f;
+ capab |= u16_encode_bits(64, IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK);
+ capab |= u16_encode_bits(pregpriv->ampdu_amsdu, IEEE80211_ADDBA_PARAM_AMSDU_MASK);
+ mgmt->u.action.u.addba_req.capab = cpu_to_le16(capab);
+ mgmt->u.action.u.addba_resp.timeout = pmlmeinfo->ADDBA_req.BA_timeout_value;
+ pattrib->pktlen = offsetofend(struct ieee80211_mgmt, u.action.u.addba_resp.timeout);
+ break;
+ case WLAN_ACTION_DELBA:
+ mgmt->u.action.u.delba.action_code = WLAN_ACTION_DELBA;
+ mgmt->u.action.u.delba.params = cpu_to_le16((status & 0x1F) << 3);
+ params = u16_encode_bits((status & 0x1), IEEE80211_DELBA_PARAM_INITIATOR_MASK);
+ params |= u16_encode_bits((status >> 1) & 0xF, IEEE80211_DELBA_PARAM_TID_MASK);
+ mgmt->u.action.u.delba.params = cpu_to_le16(params);
+ mgmt->u.action.u.delba.reason_code = cpu_to_le16(WLAN_STATUS_REQUEST_DECLINED);
+ pattrib->pktlen = offsetofend(struct ieee80211_mgmt, u.action.u.delba.reason_code);
+ break;
+ default:
+ break;
}
pattrib->last_txcmdsz = pattrib->pktlen;
@@ -5623,7 +5658,7 @@ unsigned int send_delba(struct adapter *padapter, u8 initiator, u8 *addr)
if (initiator == 0) { /* recipient */
for (tid = 0; tid < MAXTID; tid++) {
if (psta->recvreorder_ctrl[tid].enable) {
- issue_action_BA(padapter, addr, RTW_WLAN_ACTION_DELBA, (((tid << 1) | initiator) & 0x1F));
+ issue_action_BA(padapter, addr, WLAN_ACTION_DELBA, (((tid << 1) | initiator) & 0x1F));
psta->recvreorder_ctrl[tid].enable = false;
psta->recvreorder_ctrl[tid].indicate_seq = 0xffff;
}
@@ -5631,7 +5666,7 @@ unsigned int send_delba(struct adapter *padapter, u8 initiator, u8 *addr)
} else if (initiator == 1) { /* originator */
for (tid = 0; tid < MAXTID; tid++) {
if (psta->htpriv.agg_enable_bitmap & BIT(tid)) {
- issue_action_BA(padapter, addr, RTW_WLAN_ACTION_DELBA, (((tid << 1) | initiator) & 0x1F));
+ issue_action_BA(padapter, addr, WLAN_ACTION_DELBA, (((tid << 1) | initiator) & 0x1F));
psta->htpriv.agg_enable_bitmap &= ~BIT(tid);
psta->htpriv.candidate_tid_bitmap &= ~BIT(tid);
}
@@ -5667,14 +5702,129 @@ unsigned int send_beacon(struct adapter *padapter)
bool get_beacon_valid_bit(struct adapter *adapter)
{
+ int res;
+ u8 reg;
+
+ res = rtw_read8(adapter, REG_TDECTRL + 2, &reg);
+ if (res)
+ return false;
+
/* BIT(16) of REG_TDECTRL = BIT(0) of REG_TDECTRL+2 */
- return BIT(0) & rtw_read8(adapter, REG_TDECTRL + 2);
+ return BIT(0) & reg;
}
void clear_beacon_valid_bit(struct adapter *adapter)
{
+ int res;
+ u8 reg;
+
+ res = rtw_read8(adapter, REG_TDECTRL + 2, &reg);
+ if (res)
+ return;
+
/* BIT(16) of REG_TDECTRL = BIT(0) of REG_TDECTRL+2, write 1 to clear, Clear by sw */
- rtw_write8(adapter, REG_TDECTRL + 2, rtw_read8(adapter, REG_TDECTRL + 2) | BIT(0));
+ rtw_write8(adapter, REG_TDECTRL + 2, reg | BIT(0));
+}
+
+void rtw_resume_tx_beacon(struct adapter *adapt)
+{
+ struct hal_data_8188e *haldata = &adapt->haldata;
+
+ /* 2010.03.01. Marked by tynli. No need to call workitem beacause we record the value */
+ /* which should be read from register to a global variable. */
+
+ rtw_write8(adapt, REG_FWHW_TXQ_CTRL + 2, (haldata->RegFwHwTxQCtrl) | BIT(6));
+ haldata->RegFwHwTxQCtrl |= BIT(6);
+ rtw_write8(adapt, REG_TBTT_PROHIBIT + 1, 0xff);
+ haldata->RegReg542 |= BIT(0);
+ rtw_write8(adapt, REG_TBTT_PROHIBIT + 2, haldata->RegReg542);
+}
+
+void rtw_stop_tx_beacon(struct adapter *adapt)
+{
+ struct hal_data_8188e *haldata = &adapt->haldata;
+
+ /* 2010.03.01. Marked by tynli. No need to call workitem beacause we record the value */
+ /* which should be read from register to a global variable. */
+
+ rtw_write8(adapt, REG_FWHW_TXQ_CTRL + 2, (haldata->RegFwHwTxQCtrl) & (~BIT(6)));
+ haldata->RegFwHwTxQCtrl &= (~BIT(6));
+ rtw_write8(adapt, REG_TBTT_PROHIBIT + 1, 0x64);
+ haldata->RegReg542 &= ~(BIT(0));
+ rtw_write8(adapt, REG_TBTT_PROHIBIT + 2, haldata->RegReg542);
+
+ /* todo: CheckFwRsvdPageContent(Adapter); 2010.06.23. Added by tynli. */
+}
+
+static void rtw_set_opmode(struct adapter *adapter, u8 mode)
+{
+ u8 val8;
+ int res;
+
+ /* disable Port0 TSF update */
+ res = rtw_read8(adapter, REG_BCN_CTRL, &val8);
+ if (res)
+ return;
+
+ rtw_write8(adapter, REG_BCN_CTRL, val8 | BIT(4));
+
+ /* set net_type */
+ res = rtw_read8(adapter, MSR, &val8);
+ if (res)
+ return;
+
+ val8 &= 0x0c;
+ val8 |= mode;
+ rtw_write8(adapter, MSR, val8);
+
+ if ((mode == _HW_STATE_STATION_) || (mode == _HW_STATE_NOLINK_)) {
+ rtw_stop_tx_beacon(adapter);
+
+ rtw_write8(adapter, REG_BCN_CTRL, 0x19);/* disable atim wnd */
+ } else if (mode == _HW_STATE_ADHOC_) {
+ rtw_resume_tx_beacon(adapter);
+ rtw_write8(adapter, REG_BCN_CTRL, 0x1a);
+ } else if (mode == _HW_STATE_AP_) {
+ rtw_resume_tx_beacon(adapter);
+
+ rtw_write8(adapter, REG_BCN_CTRL, 0x12);
+
+ /* Set RCR */
+ rtw_write32(adapter, REG_RCR, 0x7000208e);/* CBSSID_DATA must set to 0,reject ICV_ERR packet */
+ /* enable to rx data frame */
+ rtw_write16(adapter, REG_RXFLTMAP2, 0xFFFF);
+ /* enable to rx ps-poll */
+ rtw_write16(adapter, REG_RXFLTMAP1, 0x0400);
+
+ /* Beacon Control related register for first time */
+ rtw_write8(adapter, REG_BCNDMATIM, 0x02); /* 2ms */
+
+ rtw_write8(adapter, REG_ATIMWND, 0x0a); /* 10ms */
+ rtw_write16(adapter, REG_BCNTCFG, 0x00);
+ rtw_write16(adapter, REG_TBTT_PROHIBIT, 0xff04);
+ rtw_write16(adapter, REG_TSFTR_SYN_OFFSET, 0x7fff);/* +32767 (~32ms) */
+
+ /* reset TSF */
+ rtw_write8(adapter, REG_DUAL_TSF_RST, BIT(0));
+
+ /* BIT(3) - If set 0, hw will clr bcnq when tx becon ok/fail or port 0 */
+ res = rtw_read8(adapter, REG_MBID_NUM, &val8);
+ if (res)
+ return;
+
+ rtw_write8(adapter, REG_MBID_NUM, val8 | BIT(3) | BIT(4));
+
+ /* enable BCN0 Function for if1 */
+ /* don't enable update TSF0 for if1 (due to TSF update when beacon/probe rsp are received) */
+ rtw_write8(adapter, REG_BCN_CTRL, (DIS_TSF_UDT0_NORMAL_CHIP | EN_BCN_FUNCTION | BIT(1)));
+
+ /* dis BCN1 ATIM WND if if2 is station */
+ res = rtw_read8(adapter, REG_BCN_CTRL_1, &val8);
+ if (res)
+ return;
+
+ rtw_write8(adapter, REG_BCN_CTRL_1, val8 | BIT(0));
+ }
}
/****************************************************************************
@@ -5698,9 +5848,70 @@ static void rtw_set_initial_gain(struct adapter *adapter, u8 gain)
}
}
+void rtw_mlme_under_site_survey(struct adapter *adapter)
+{
+ /* config RCR to receive different BSSID & not to receive data frame */
+
+ int res;
+ u8 reg;
+ u32 v;
+
+ res = rtw_read32(adapter, REG_RCR, &v);
+ if (res)
+ return;
+
+ v &= ~(RCR_CBSSID_BCN);
+ rtw_write32(adapter, REG_RCR, v);
+ /* reject all data frame */
+ rtw_write16(adapter, REG_RXFLTMAP2, 0x00);
+
+ /* disable update TSF */
+ res = rtw_read8(adapter, REG_BCN_CTRL, &reg);
+ if (res)
+ return;
+
+ rtw_write8(adapter, REG_BCN_CTRL, reg | BIT(4));
+}
+
+void rtw_mlme_site_survey_done(struct adapter *adapter)
+{
+ struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
+ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
+ u32 reg32;
+ int res;
+ u8 reg;
+
+ if ((is_client_associated_to_ap(adapter)) ||
+ ((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE)) {
+ /* enable to rx data frame */
+ rtw_write16(adapter, REG_RXFLTMAP2, 0xFFFF);
+
+ /* enable update TSF */
+ res = rtw_read8(adapter, REG_BCN_CTRL, &reg);
+ if (res)
+ return;
+
+ rtw_write8(adapter, REG_BCN_CTRL, reg & (~BIT(4)));
+ } else if ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) {
+ rtw_write16(adapter, REG_RXFLTMAP2, 0xFFFF);
+ /* enable update TSF */
+ res = rtw_read8(adapter, REG_BCN_CTRL, &reg);
+ if (res)
+ return;
+
+ rtw_write8(adapter, REG_BCN_CTRL, reg & (~BIT(4)));
+ }
+
+ res = rtw_read32(adapter, REG_RCR, &reg32);
+ if (res)
+ return;
+
+ rtw_write32(adapter, REG_RCR, reg32 | RCR_CBSSID_BCN);
+}
+
void site_survey(struct adapter *padapter)
{
- unsigned char survey_channel = 0, val8;
+ unsigned char survey_channel = 0;
enum rt_scan_type ScanType = SCAN_PASSIVE;
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
@@ -5824,8 +6035,7 @@ void site_survey(struct adapter *padapter)
if (is_client_associated_to_ap(padapter))
issue_nulldata(padapter, NULL, 0, 3, 500);
- val8 = 0; /* survey done */
- SetHwReg8188EU(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8));
+ rtw_mlme_site_survey_done(padapter);
report_surveydone_event(padapter);
@@ -6002,7 +6212,9 @@ static void rtw_set_bssid(struct adapter *adapter, u8 *bssid)
static void mlme_join(struct adapter *adapter, int type)
{
struct mlme_priv *mlmepriv = &adapter->mlmepriv;
- u8 retry_limit = 0x30;
+ u8 retry_limit = 0x30, reg;
+ u32 reg32;
+ int res;
switch (type) {
case 0:
@@ -6010,8 +6222,12 @@ static void mlme_join(struct adapter *adapter, int type)
/* enable to rx data frame, accept all data frame */
rtw_write16(adapter, REG_RXFLTMAP2, 0xFFFF);
+ res = rtw_read32(adapter, REG_RCR, &reg32);
+ if (res)
+ return;
+
rtw_write32(adapter, REG_RCR,
- rtw_read32(adapter, REG_RCR) | RCR_CBSSID_DATA | RCR_CBSSID_BCN);
+ reg32 | RCR_CBSSID_DATA | RCR_CBSSID_BCN);
if (check_fwstate(mlmepriv, WIFI_STATION_STATE)) {
retry_limit = 48;
@@ -6027,7 +6243,11 @@ static void mlme_join(struct adapter *adapter, int type)
case 2:
/* sta add event call back */
/* enable update TSF */
- rtw_write8(adapter, REG_BCN_CTRL, rtw_read8(adapter, REG_BCN_CTRL) & (~BIT(4)));
+ res = rtw_read8(adapter, REG_BCN_CTRL, &reg);
+ if (res)
+ return;
+
+ rtw_write8(adapter, REG_BCN_CTRL, reg & (~BIT(4)));
if (check_fwstate(mlmepriv, WIFI_ADHOC_STATE | WIFI_ADHOC_MASTER_STATE))
retry_limit = 0x7;
@@ -6184,14 +6404,14 @@ void start_clnt_assoc(struct adapter *padapter)
set_link_timer(pmlmeext, REASSOC_TO);
}
-unsigned int receive_disconnect(struct adapter *padapter, unsigned char *MacAddr, unsigned short reason)
+void receive_disconnect(struct adapter *padapter, unsigned char *MacAddr, unsigned short reason)
{
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
/* check A3 */
if (!(!memcmp(MacAddr, get_my_bssid(&pmlmeinfo->network), ETH_ALEN)))
- return _SUCCESS;
+ return;
if ((pmlmeinfo->state & 0x03) == WIFI_FW_STATION_STATE) {
if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS) {
@@ -6202,7 +6422,6 @@ unsigned int receive_disconnect(struct adapter *padapter, unsigned char *MacAddr
report_join_res(padapter, -2);
}
}
- return _SUCCESS;
}
static void process_80211d(struct adapter *padapter, struct wlan_bssid_ex *bssid)
@@ -6640,6 +6859,23 @@ void update_sta_info(struct adapter *padapter, struct sta_info *psta)
psta->state = _FW_LINKED;
}
+static void rtw_reset_dm_func_flag(struct adapter *adapter)
+{
+ struct hal_data_8188e *haldata = &adapter->haldata;
+ struct dm_priv *dmpriv = &haldata->dmpriv;
+ struct odm_dm_struct *odmpriv = &haldata->odmpriv;
+
+ odmpriv->SupportAbility = dmpriv->InitODMFlag;
+}
+
+static void rtw_clear_dm_func_flag(struct adapter *adapter)
+{
+ struct hal_data_8188e *haldata = &adapter->haldata;
+ struct odm_dm_struct *odmpriv = &haldata->odmpriv;
+
+ odmpriv->SupportAbility = 0;
+}
+
void mlmeext_joinbss_event_callback(struct adapter *padapter, int join_res)
{
struct sta_info *psta, *psta_bmc;
@@ -6670,12 +6906,12 @@ void mlmeext_joinbss_event_callback(struct adapter *padapter, int join_res)
}
/* turn on dynamic functions */
- SetHwReg8188EU(padapter, HW_VAR_DM_FUNC_RESET, NULL);
+ rtw_reset_dm_func_flag(padapter);
/* update IOT-releated issue */
update_IOT_info(padapter);
- SetHwReg8188EU(padapter, HW_VAR_BASIC_RATE, cur_network->SupportedRates);
+ rtw_set_basic_rate(padapter, cur_network->SupportedRates);
/* BCN interval */
rtw_write16(padapter, REG_BCN_INTERVAL, pmlmeinfo->bcn_interval);
@@ -6702,14 +6938,14 @@ void mlmeext_joinbss_event_callback(struct adapter *padapter, int join_res)
rtw_set_max_rpt_macid(padapter, psta->mac_id);
media_status = (psta->mac_id << 8) | 1; /* MACID|OPMODE: 1 means connect */
- SetHwReg8188EU(padapter, HW_VAR_H2C_MEDIA_STATUS_RPT, (u8 *)&media_status);
+ rtl8188e_set_FwMediaStatus_cmd(padapter, media_status);
}
mlme_join(padapter, 2);
if ((pmlmeinfo->state & 0x03) == WIFI_FW_STATION_STATE) {
/* correcting TSF */
- correct_TSF(padapter, pmlmeext);
+ correct_TSF(padapter);
}
rtw_lps_ctrl_wk_cmd(padapter, LPS_CTRL_CONNECT, 0);
}
@@ -6724,7 +6960,7 @@ void mlmeext_sta_add_event_callback(struct adapter *padapter, struct sta_info *p
/* nothing to do */
} else { /* adhoc client */
/* correcting TSF */
- correct_TSF(padapter, pmlmeext);
+ correct_TSF(padapter);
/* start beacon */
if (send_beacon(padapter) == _FAIL) {
@@ -6748,6 +6984,9 @@ void mlmeext_sta_add_event_callback(struct adapter *padapter, struct sta_info *p
static void mlme_disconnect(struct adapter *adapter)
{
+ int res;
+ u8 reg;
+
/* Set RCR to not to receive data frame when NO LINK state */
/* reject all data frames */
rtw_write16(adapter, REG_RXFLTMAP2, 0x00);
@@ -6756,7 +6995,12 @@ static void mlme_disconnect(struct adapter *adapter)
rtw_write8(adapter, REG_DUAL_TSF_RST, (BIT(0) | BIT(1)));
/* disable update TSF */
- rtw_write8(adapter, REG_BCN_CTRL, rtw_read8(adapter, REG_BCN_CTRL) | BIT(4));
+
+ res = rtw_read8(adapter, REG_BCN_CTRL, &reg);
+ if (res)
+ return;
+
+ rtw_write8(adapter, REG_BCN_CTRL, reg | BIT(4));
}
void mlmeext_sta_del_event_callback(struct adapter *padapter)
@@ -6810,14 +7054,20 @@ static u8 chk_ap_is_alive(struct sta_info *psta)
return ret;
}
-static void rtl8188e_sreset_linked_status_check(struct adapter *padapter)
+static int rtl8188e_sreset_linked_status_check(struct adapter *padapter)
{
- u32 rx_dma_status = rtw_read32(padapter, REG_RXDMA_STATUS);
+ u32 rx_dma_status;
+ int res;
+ u8 reg;
+
+ res = rtw_read32(padapter, REG_RXDMA_STATUS, &rx_dma_status);
+ if (res)
+ return res;
if (rx_dma_status != 0x00)
rtw_write32(padapter, REG_RXDMA_STATUS, rx_dma_status);
- rtw_read8(padapter, REG_FMETHR);
+ return rtw_read8(padapter, REG_FMETHR, &reg);
}
void linked_status_chk(struct adapter *padapter)
@@ -7045,7 +7295,7 @@ u8 setopmode_hdl(struct adapter *padapter, u8 *pbuf)
type = _HW_STATE_NOLINK_;
}
- SetHwReg8188EU(padapter, HW_VAR_SET_OPMODE, (u8 *)(&type));
+ rtw_set_opmode(padapter, type);
return H2C_SUCCESS;
}
@@ -7081,7 +7331,7 @@ u8 createbss_hdl(struct adapter *padapter, u8 *pbuf)
/* disable dynamic functions, such as high power, DIG */
Save_DM_Func_Flag(padapter);
- SetHwReg8188EU(padapter, HW_VAR_DM_FUNC_CLR, NULL);
+ rtw_clear_dm_func_flag(padapter);
/* cancel link timer */
_cancel_timer_ex(&pmlmeext->link_timer);
@@ -7089,7 +7339,7 @@ u8 createbss_hdl(struct adapter *padapter, u8 *pbuf)
/* clear CAM */
flush_all_cam_entry(padapter);
- memcpy(pnetwork, pbuf, FIELD_OFFSET(struct wlan_bssid_ex, IELength));
+ memcpy(pnetwork, pbuf, offsetof(struct wlan_bssid_ex, IELength));
pnetwork->IELength = ((struct wlan_bssid_ex *)pbuf)->IELength;
if (pnetwork->IELength > MAX_IE_SZ)/* Check pbuf->IELength */
@@ -7146,7 +7396,7 @@ u8 join_cmd_hdl(struct adapter *padapter, u8 *pbuf)
pmlmeinfo->candidate_tid_bitmap = 0;
pmlmeinfo->bwmode_updated = false;
- memcpy(pnetwork, pbuf, FIELD_OFFSET(struct wlan_bssid_ex, IELength));
+ memcpy(pnetwork, pbuf, offsetof(struct wlan_bssid_ex, IELength));
pnetwork->IELength = ((struct wlan_bssid_ex *)pbuf)->IELength;
if (pnetwork->IELength > MAX_IE_SZ)/* Check pbuf->IELength */
@@ -7219,6 +7469,7 @@ u8 disconnect_hdl(struct adapter *padapter, unsigned char *pbuf)
struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
struct wlan_bssid_ex *pnetwork = (struct wlan_bssid_ex *)(&pmlmeinfo->network);
u8 val8;
+ int res;
if (is_client_associated_to_ap(padapter))
issue_deauth_ex(padapter, pnetwork->MacAddress, WLAN_REASON_DEAUTH_LEAVING, param->deauth_timeout_ms / 100, 100);
@@ -7231,7 +7482,10 @@ u8 disconnect_hdl(struct adapter *padapter, unsigned char *pbuf)
if (((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE) || ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE)) {
/* Stop BCN */
- val8 = rtw_read8(padapter, REG_BCN_CTRL);
+ res = rtw_read8(padapter, REG_BCN_CTRL, &val8);
+ if (res)
+ return H2C_DROPPED;
+
rtw_write8(padapter, REG_BCN_CTRL, val8 & (~(EN_BCN_FUNCTION | EN_TXBCN_RPT)));
}
@@ -7302,7 +7556,6 @@ u8 sitesurvey_cmd_hdl(struct adapter *padapter, u8 *pbuf)
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
struct sitesurvey_parm *pparm = (struct sitesurvey_parm *)pbuf;
u8 bdelayscan = false;
- u8 val8;
u32 i;
struct wifidirect_info *pwdinfo = &padapter->wdinfo;
@@ -7347,7 +7600,7 @@ u8 sitesurvey_cmd_hdl(struct adapter *padapter, u8 *pbuf)
if ((pmlmeext->sitesurvey_res.state == SCAN_START) || (pmlmeext->sitesurvey_res.state == SCAN_TXNULL)) {
/* disable dynamic functions, such as high power, DIG */
Save_DM_Func_Flag(padapter);
- SetHwReg8188EU(padapter, HW_VAR_DM_FUNC_CLR, NULL);
+ rtw_clear_dm_func_flag(padapter);
/* config the initial gain under scanning, need to write the BB registers */
if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
@@ -7359,8 +7612,7 @@ u8 sitesurvey_cmd_hdl(struct adapter *padapter, u8 *pbuf)
/* set MSR to no link state */
Set_MSR(padapter, _HW_STATE_NOLINK_);
- val8 = 1; /* under site survey */
- SetHwReg8188EU(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8));
+ rtw_mlme_under_site_survey(padapter);
pmlmeext->sitesurvey_res.state = SCAN_PROCESS;
}
@@ -7475,7 +7727,7 @@ u8 add_ba_hdl(struct adapter *padapter, unsigned char *pbuf)
if (((pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS) && (pmlmeinfo->HT_enable)) ||
((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE)) {
- issue_action_BA(padapter, pparm->addr, RTW_WLAN_ACTION_ADDBA_REQ, (u16)pparm->tid);
+ issue_action_BA(padapter, pparm->addr, WLAN_ACTION_ADDBA_REQ, (u16)pparm->tid);
_set_timer(&psta->addba_retry_timer, ADDBA_TO);
} else {
psta->htpriv.candidate_tid_bitmap &= ~BIT(pparm->tid);
diff --git a/drivers/staging/r8188eu/core/rtw_p2p.c b/drivers/staging/r8188eu/core/rtw_p2p.c
index beffe5b16f1e..bd654d4ff8b4 100644
--- a/drivers/staging/r8188eu/core/rtw_p2p.c
+++ b/drivers/staging/r8188eu/core/rtw_p2p.c
@@ -1450,10 +1450,9 @@ static void restore_p2p_state_handler(struct adapter *padapter)
static void pre_tx_invitereq_handler(struct adapter *padapter)
{
struct wifidirect_info *pwdinfo = &padapter->wdinfo;
- u8 val8 = 1;
set_channel_bwmode(padapter, pwdinfo->invitereq_info.peer_ch, HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20);
- SetHwReg8188EU(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8));
+ rtw_mlme_under_site_survey(padapter);
issue_probereq_p2p(padapter, NULL);
_set_timer(&pwdinfo->pre_tx_scan_timer, P2P_TX_PRESCAN_TIMEOUT);
@@ -1462,10 +1461,9 @@ static void pre_tx_invitereq_handler(struct adapter *padapter)
static void pre_tx_provdisc_handler(struct adapter *padapter)
{
struct wifidirect_info *pwdinfo = &padapter->wdinfo;
- u8 val8 = 1;
set_channel_bwmode(padapter, pwdinfo->tx_prov_disc_info.peer_channel_num[0], HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20);
- SetHwReg8188EU(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8));
+ rtw_mlme_under_site_survey(padapter);
issue_probereq_p2p(padapter, NULL);
_set_timer(&pwdinfo->pre_tx_scan_timer, P2P_TX_PRESCAN_TIMEOUT);
@@ -1474,10 +1472,9 @@ static void pre_tx_provdisc_handler(struct adapter *padapter)
static void pre_tx_negoreq_handler(struct adapter *padapter)
{
struct wifidirect_info *pwdinfo = &padapter->wdinfo;
- u8 val8 = 1;
set_channel_bwmode(padapter, pwdinfo->nego_req_info.peer_channel_num[0], HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20);
- SetHwReg8188EU(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8));
+ rtw_mlme_under_site_survey(padapter);
issue_probereq_p2p(padapter, NULL);
_set_timer(&pwdinfo->pre_tx_scan_timer, P2P_TX_PRESCAN_TIMEOUT);
@@ -1891,7 +1888,7 @@ int rtw_p2p_enable(struct adapter *padapter, enum P2P_ROLE role)
if (role == P2P_ROLE_DEVICE || role == P2P_ROLE_CLIENT || role == P2P_ROLE_GO) {
/* leave IPS/Autosuspend */
- if (rtw_pwr_wakeup(padapter) == _FAIL) {
+ if (rtw_pwr_wakeup(padapter)) {
ret = _FAIL;
goto exit;
}
@@ -1905,7 +1902,7 @@ int rtw_p2p_enable(struct adapter *padapter, enum P2P_ROLE role)
init_wifidirect_info(padapter, role);
} else if (role == P2P_ROLE_DISABLE) {
- if (rtw_pwr_wakeup(padapter) == _FAIL) {
+ if (rtw_pwr_wakeup(padapter)) {
ret = _FAIL;
goto exit;
}
diff --git a/drivers/staging/r8188eu/core/rtw_pwrctrl.c b/drivers/staging/r8188eu/core/rtw_pwrctrl.c
index 7b816b824947..10550bd2c16d 100644
--- a/drivers/staging/r8188eu/core/rtw_pwrctrl.c
+++ b/drivers/staging/r8188eu/core/rtw_pwrctrl.c
@@ -229,6 +229,9 @@ void rtw_set_ps_mode(struct adapter *padapter, u8 ps_mode, u8 smart_ps, u8 bcn_a
static bool lps_rf_on(struct adapter *adapter)
{
+ int res;
+ u32 reg;
+
/* When we halt NIC, we should check if FW LPS is leave. */
if (adapter->pwrctrlpriv.rf_pwrstate == rf_off) {
/* If it is in HW/SW Radio OFF or IPS state, we do not check Fw LPS Leave, */
@@ -236,7 +239,11 @@ static bool lps_rf_on(struct adapter *adapter)
return true;
}
- if (rtw_read32(adapter, REG_RCR) & 0x00070000)
+ res = rtw_read32(adapter, REG_RCR, &reg);
+ if (res)
+ return false;
+
+ if (reg & 0x00070000)
return false;
return true;
@@ -266,7 +273,7 @@ static s32 LPS_RF_ON_check(struct adapter *padapter, u32 delay_ms)
err = -1;
break;
}
- rtw_usleep_os(100);
+ msleep(1);
}
return err;
@@ -374,24 +381,24 @@ int rtw_pwr_wakeup(struct adapter *padapter)
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
unsigned long timeout = jiffies + msecs_to_jiffies(3000);
unsigned long deny_time;
- int ret = _SUCCESS;
+ int ret;
while (pwrpriv->ps_processing && time_before(jiffies, timeout))
msleep(10);
/* I think this should be check in IPS, LPS, autosuspend functions... */
- if (check_fwstate(pmlmepriv, _FW_LINKED)) {
- ret = _SUCCESS;
+ /* Below goto is a success path taken for already linked devices */
+ ret = 0;
+ if (check_fwstate(pmlmepriv, _FW_LINKED))
goto exit;
- }
if (pwrpriv->rf_pwrstate == rf_off && ips_leave(padapter) == _FAIL) {
- ret = _FAIL;
+ ret = -ENOMEM;
goto exit;
}
if (padapter->bDriverStopped || !padapter->bup || !padapter->hw_init_completed) {
- ret = _FAIL;
+ ret = -EBUSY;
goto exit;
}
@@ -432,7 +439,7 @@ int rtw_pm_set_ips(struct adapter *padapter, u8 mode)
return 0;
} else if (mode == IPS_NONE) {
rtw_ips_mode_req(pwrctrlpriv, mode);
- if ((padapter->bSurpriseRemoved == 0) && (rtw_pwr_wakeup(padapter) == _FAIL))
+ if ((padapter->bSurpriseRemoved == 0) && rtw_pwr_wakeup(padapter))
return -EFAULT;
} else {
return -EINVAL;
diff --git a/drivers/staging/r8188eu/core/rtw_recv.c b/drivers/staging/r8188eu/core/rtw_recv.c
index df518439aea2..e5a7b7dfc387 100644
--- a/drivers/staging/r8188eu/core/rtw_recv.c
+++ b/drivers/staging/r8188eu/core/rtw_recv.c
@@ -17,14 +17,14 @@ static u8 SNAP_ETH_TYPE_APPLETALK_AARP[2] = {0x80, 0xf3};
/* Bridge-Tunnel header (for EtherTypes ETH_P_AARP and ETH_P_IPX) */
static u8 rtw_bridge_tunnel_header[] = {
- 0xaa, 0xaa, 0x03, 0x00, 0x00, 0xf8
+ 0xaa, 0xaa, 0x03, 0x00, 0x00, 0xf8
};
static u8 rtw_rfc1042_header[] = {
- 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00
+ 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00
};
-void rtw_signal_stat_timer_hdl(struct timer_list *);
+static void rtw_signal_stat_timer_hdl(struct timer_list *t);
void _rtw_init_sta_recv_priv(struct sta_recv_priv *psta_recvpriv)
{
@@ -62,7 +62,7 @@ int _rtw_init_recv_priv(struct recv_priv *precvpriv, struct adapter *padapter)
goto exit;
}
- precvpriv->precv_frame_buf = (u8 *)N_BYTE_ALIGMENT((size_t)(precvpriv->pallocated_frame_buf), RXFRAME_ALIGN_SZ);
+ precvpriv->precv_frame_buf = (u8 *)ALIGN((size_t)(precvpriv->pallocated_frame_buf), RXFRAME_ALIGN_SZ);
precvframe = (struct recv_frame *)precvpriv->precv_frame_buf;
@@ -166,10 +166,8 @@ int rtw_free_recvframe(struct recv_frame *precvframe, struct __queue *pfree_recv
list_add_tail(&precvframe->list, get_list_head(pfree_recv_queue));
- if (padapter) {
- if (pfree_recv_queue == &precvpriv->free_recv_queue)
- precvpriv->free_recvframe_cnt++;
- }
+ if (padapter && (pfree_recv_queue == &precvpriv->free_recv_queue))
+ precvpriv->free_recvframe_cnt++;
spin_unlock_bh(&pfree_recv_queue->lock);
@@ -204,12 +202,12 @@ int rtw_enqueue_recvframe(struct recv_frame *precvframe, struct __queue *queue)
}
/*
-caller : defrag ; recvframe_chk_defrag in recv_thread (passive)
-pframequeue: defrag_queue : will be accessed in recv_thread (passive)
-
-using spinlock to protect
-
-*/
+ * caller : defrag ; recvframe_chk_defrag in recv_thread (passive)
+ * pframequeue: defrag_queue : will be accessed in recv_thread (passive)
+ *
+ * using spinlock to protect
+ *
+ */
void rtw_free_recvframe_queue(struct __queue *pframequeue, struct __queue *pfree_recv_queue)
{
@@ -237,6 +235,7 @@ u32 rtw_free_uc_swdec_pending_queue(struct adapter *adapter)
{
u32 cnt = 0;
struct recv_frame *pending_frame;
+
while ((pending_frame = rtw_alloc_recvframe(&adapter->recvpriv.uc_swdec_pending_queue))) {
rtw_free_recvframe(pending_frame, &adapter->recvpriv.free_recv_queue);
cnt++;
@@ -327,6 +326,7 @@ static struct recv_frame *decryptor(struct adapter *padapter, struct recv_frame
if (prxattrib->encrypt > 0) {
u8 *iv = precv_frame->rx_data + prxattrib->hdrlen;
+
prxattrib->key_index = (((iv[3]) >> 6) & 0x3);
if (prxattrib->key_index > WEP_KEYS) {
@@ -452,8 +452,7 @@ static int recv_decache(struct recv_frame *precv_frame, u8 bretry, struct stainf
return _SUCCESS;
}
-void process_pwrbit_data(struct adapter *padapter, struct recv_frame *precv_frame);
-void process_pwrbit_data(struct adapter *padapter, struct recv_frame *precv_frame)
+static void process_pwrbit_data(struct adapter *padapter, struct recv_frame *precv_frame)
{
unsigned char pwrbit;
u8 *ptr = precv_frame->rx_data;
@@ -557,15 +556,9 @@ static void count_rx_stats(struct adapter *padapter, struct recv_frame *prframe,
}
}
-int sta2sta_data_frame(
- struct adapter *adapter,
- struct recv_frame *precv_frame,
- struct sta_info **psta
-);
-
-int sta2sta_data_frame(struct adapter *adapter, struct recv_frame *precv_frame, struct sta_info **psta)
+static int sta2sta_data_frame(struct adapter *adapter,
+ struct recv_frame *precv_frame, struct sta_info **psta)
{
- u8 *ptr = precv_frame->rx_data;
int ret = _SUCCESS;
struct rx_pkt_attrib *pattrib = &precv_frame->attrib;
struct sta_priv *pstapriv = &adapter->stapriv;
@@ -620,12 +613,6 @@ int sta2sta_data_frame(struct adapter *adapter, struct recv_frame *precv_frame,
sta_addr = pattrib->src;
}
} else if (check_fwstate(pmlmepriv, WIFI_MP_STATE)) {
- memcpy(pattrib->dst, GetAddr1Ptr(ptr), ETH_ALEN);
- memcpy(pattrib->src, GetAddr2Ptr(ptr), ETH_ALEN);
- memcpy(pattrib->bssid, GetAddr3Ptr(ptr), ETH_ALEN);
- memcpy(pattrib->ra, pattrib->dst, ETH_ALEN);
- memcpy(pattrib->ta, pattrib->src, ETH_ALEN);
-
sta_addr = mybssid;
} else {
ret = _FAIL;
@@ -650,6 +637,7 @@ static int ap2sta_data_frame(
struct sta_info **psta)
{
u8 *ptr = precv_frame->rx_data;
+ struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)precv_frame->rx_data;
struct rx_pkt_attrib *pattrib = &precv_frame->attrib;
int ret = _SUCCESS;
struct sta_priv *pstapriv = &adapter->stapriv;
@@ -694,24 +682,16 @@ static int ap2sta_data_frame(
goto exit;
}
- /* if ((GetFrameSubType(ptr) & WIFI_QOS_DATA_TYPE) == WIFI_QOS_DATA_TYPE) { */
- /* */
-
- if (GetFrameSubType(ptr) & BIT(6)) {
- /* No data, will not indicate to upper layer, temporily count it here */
+ if (ieee80211_is_nullfunc(hdr->frame_control)) {
+ /* We count the nullfunc frame, but we'll not pass it on to higher layers. */
count_rx_stats(adapter, precv_frame, *psta);
ret = RTW_RX_HANDLED;
goto exit;
}
} else if (check_fwstate(pmlmepriv, WIFI_MP_STATE) &&
check_fwstate(pmlmepriv, _FW_LINKED)) {
- memcpy(pattrib->dst, GetAddr1Ptr(ptr), ETH_ALEN);
memcpy(pattrib->src, GetAddr2Ptr(ptr), ETH_ALEN);
- memcpy(pattrib->bssid, GetAddr3Ptr(ptr), ETH_ALEN);
- memcpy(pattrib->ra, pattrib->dst, ETH_ALEN);
- memcpy(pattrib->ta, pattrib->src, ETH_ALEN);
- /* */
memcpy(pattrib->bssid, mybssid, ETH_ALEN);
*psta = rtw_get_stainfo(pstapriv, pattrib->bssid); /* get sta_info */
@@ -778,6 +758,7 @@ static int sta2ap_data_frame(struct adapter *adapter,
}
} else {
u8 *myhwaddr = myid(&adapter->eeprompriv);
+
if (memcmp(pattrib->ra, myhwaddr, ETH_ALEN)) {
ret = RTW_RX_HANDLED;
goto exit;
@@ -1023,6 +1004,7 @@ static int validate_recv_frame(struct adapter *adapter, struct recv_frame *precv
if (pmlmeext->sitesurvey_res.state == SCAN_PROCESS) {
int ch_set_idx = rtw_ch_set_search_ch(pmlmeext->channel_set, rtw_get_oper_ch(adapter));
+
if (ch_set_idx >= 0)
pmlmeext->channel_set[ch_set_idx].rx_count++;
}
@@ -1050,6 +1032,7 @@ static int validate_recv_frame(struct adapter *adapter, struct recv_frame *precv
retval = validate_recv_data_frame(adapter, precv_frame);
if (retval == _FAIL) {
struct recv_priv *precvpriv = &adapter->recvpriv;
+
precvpriv->rx_drop++;
}
}
@@ -1313,9 +1296,11 @@ static int amsdu_to_msdu(struct adapter *padapter, struct recv_frame *prframe)
struct rx_pkt_attrib *pattrib;
unsigned char *data_ptr;
struct sk_buff *sub_skb, *subframes[MAX_SUBFRAME_COUNT];
+
struct recv_priv *precvpriv = &padapter->recvpriv;
struct __queue *pfree_recv_queue = &precvpriv->free_recv_queue;
int ret = _SUCCESS;
+
nr_subframes = 0;
pattrib = &prframe->attrib;
@@ -1366,13 +1351,12 @@ static int amsdu_to_msdu(struct adapter *padapter, struct recv_frame *prframe)
a_len -= nSubframe_Length;
if (a_len != 0) {
padding_len = 4 - ((nSubframe_Length + ETH_HLEN) & (4 - 1));
- if (padding_len == 4) {
+ if (padding_len == 4)
padding_len = 0;
- }
- if (a_len < padding_len) {
+ if (a_len < padding_len)
goto exit;
- }
+
pdata += padding_len;
a_len -= padding_len;
}
@@ -1747,9 +1731,11 @@ static int recv_func(struct adapter *padapter, struct recv_frame *rframe)
!psecuritypriv->busetkipkey) {
rtw_enqueue_recvframe(rframe, &padapter->recvpriv.uc_swdec_pending_queue);
if (recvpriv->free_recvframe_cnt < NR_RECVFRAME / 4) {
- /* to prevent from recvframe starvation,
+ /*
+ * to prevent from recvframe starvation,
* get recvframe from uc_swdec_pending_queue to
- * free_recvframe_cnt */
+ * free_recvframe_cnt
+ */
rframe = rtw_alloc_recvframe(&padapter->recvpriv.uc_swdec_pending_queue);
if (rframe)
goto do_posthandle;
@@ -1787,7 +1773,7 @@ _recv_entry_drop:
return ret;
}
-void rtw_signal_stat_timer_hdl(struct timer_list *t)
+static void rtw_signal_stat_timer_hdl(struct timer_list *t)
{
struct adapter *adapter = from_timer(adapter, t, recvpriv.signal_stat_timer);
struct recv_priv *recvpriv = &adapter->recvpriv;
diff --git a/drivers/staging/r8188eu/core/rtw_wlan_util.c b/drivers/staging/r8188eu/core/rtw_wlan_util.c
index 392a65783f32..3a002cb6834f 100644
--- a/drivers/staging/r8188eu/core/rtw_wlan_util.c
+++ b/drivers/staging/r8188eu/core/rtw_wlan_util.c
@@ -264,23 +264,30 @@ void UpdateBrateTblForSoftAP(u8 *bssrateset, u32 bssratelen)
void Save_DM_Func_Flag(struct adapter *padapter)
{
- u8 saveflag = true;
+ struct hal_data_8188e *haldata = &padapter->haldata;
+ struct odm_dm_struct *odmpriv = &haldata->odmpriv;
- SetHwReg8188EU(padapter, HW_VAR_DM_FUNC_OP, (u8 *)(&saveflag));
+ odmpriv->BK_SupportAbility = odmpriv->SupportAbility;
}
void Restore_DM_Func_Flag(struct adapter *padapter)
{
- u8 saveflag = false;
+ struct hal_data_8188e *haldata = &padapter->haldata;
+ struct odm_dm_struct *odmpriv = &haldata->odmpriv;
- SetHwReg8188EU(padapter, HW_VAR_DM_FUNC_OP, (u8 *)(&saveflag));
+ odmpriv->SupportAbility = odmpriv->BK_SupportAbility;
}
void Set_MSR(struct adapter *padapter, u8 type)
{
u8 val8;
+ int res;
+
+ res = rtw_read8(padapter, MSR, &val8);
+ if (res)
+ return;
- val8 = rtw_read8(padapter, MSR) & 0x0c;
+ val8 &= 0x0c;
val8 |= type;
rtw_write8(padapter, MSR, val8);
}
@@ -505,7 +512,11 @@ int WMM_param_handler(struct adapter *padapter, struct ndis_802_11_var_ie *pIE)
static void set_acm_ctrl(struct adapter *adapter, u8 acm_mask)
{
- u8 acmctrl = rtw_read8(adapter, REG_ACMHWCTRL);
+ u8 acmctrl;
+ int res = rtw_read8(adapter, REG_ACMHWCTRL, &acmctrl);
+
+ if (res)
+ return;
if (acm_mask > 1)
acmctrl = acmctrl | 0x1;
@@ -765,6 +776,7 @@ void HT_info_handler(struct adapter *padapter, struct ndis_802_11_var_ie *pIE)
static void set_min_ampdu_spacing(struct adapter *adapter, u8 spacing)
{
u8 sec_spacing;
+ int res;
if (spacing <= 7) {
switch (adapter->securitypriv.dot11PrivacyAlgrthm) {
@@ -786,8 +798,38 @@ static void set_min_ampdu_spacing(struct adapter *adapter, u8 spacing)
if (spacing < sec_spacing)
spacing = sec_spacing;
+ res = rtw_read8(adapter, REG_AMPDU_MIN_SPACE, &sec_spacing);
+ if (res)
+ return;
+
rtw_write8(adapter, REG_AMPDU_MIN_SPACE,
- (rtw_read8(adapter, REG_AMPDU_MIN_SPACE) & 0xf8) | spacing);
+ (sec_spacing & 0xf8) | spacing);
+ }
+}
+
+static void set_ampdu_factor(struct adapter *adapter, u8 factor)
+{
+ u8 RegToSet_Normal[4] = {0x41, 0xa8, 0x72, 0xb9};
+ u8 FactorToSet;
+ u8 *pRegToSet;
+ u8 index = 0;
+
+ pRegToSet = RegToSet_Normal; /* 0xb972a841; */
+ FactorToSet = factor;
+ if (FactorToSet <= 3) {
+ FactorToSet = (1 << (FactorToSet + 2));
+ if (FactorToSet > 0xf)
+ FactorToSet = 0xf;
+
+ for (index = 0; index < 4; index++) {
+ if ((pRegToSet[index] & 0xf0) > (FactorToSet << 4))
+ pRegToSet[index] = (pRegToSet[index] & 0x0f) | (FactorToSet << 4);
+
+ if ((pRegToSet[index] & 0x0f) > FactorToSet)
+ pRegToSet[index] = (pRegToSet[index] & 0xf0) | (FactorToSet);
+
+ rtw_write8(adapter, (REG_AGGLEN_LMT + index), pRegToSet[index]);
+ }
}
}
@@ -817,7 +859,7 @@ void HTOnAssocRsp(struct adapter *padapter)
set_min_ampdu_spacing(padapter, min_MPDU_spacing);
- SetHwReg8188EU(padapter, HW_VAR_AMPDU_FACTOR, (u8 *)(&max_AMPDU_len));
+ set_ampdu_factor(padapter, max_AMPDU_len);
}
void ERP_IE_handler(struct adapter *padapter, struct ndis_802_11_var_ie *pIE)
@@ -1225,6 +1267,45 @@ void set_sta_rate(struct adapter *padapter, struct sta_info *psta)
enable_rate_adaptive(padapter, psta->mac_id);
}
+void rtw_set_basic_rate(struct adapter *adapter, u8 *rates)
+{
+ u16 BrateCfg = 0;
+ u8 RateIndex = 0;
+ int res;
+ u8 reg;
+
+ /* 2007.01.16, by Emily */
+ /* Select RRSR (in Legacy-OFDM and CCK) */
+ /* For 8190, we select only 24M, 12M, 6M, 11M, 5.5M, 2M, and 1M from the Basic rate. */
+ /* We do not use other rates. */
+ HalSetBrateCfg(adapter, rates, &BrateCfg);
+
+ /* 2011.03.30 add by Luke Lee */
+ /* CCK 2M ACK should be disabled for some BCM and Atheros AP IOT */
+ /* because CCK 2M has poor TXEVM */
+ /* CCK 5.5M & 11M ACK should be enabled for better performance */
+
+ BrateCfg = (BrateCfg | 0xd) & 0x15d;
+
+ BrateCfg |= 0x01; /* default enable 1M ACK rate */
+ /* Set RRSR rate table. */
+ rtw_write8(adapter, REG_RRSR, BrateCfg & 0xff);
+ rtw_write8(adapter, REG_RRSR + 1, (BrateCfg >> 8) & 0xff);
+ res = rtw_read8(adapter, REG_RRSR + 2, &reg);
+ if (res)
+ return;
+
+ rtw_write8(adapter, REG_RRSR + 2, reg & 0xf0);
+
+ /* Set RTS initial rate */
+ while (BrateCfg > 0x1) {
+ BrateCfg = (BrateCfg >> 1);
+ RateIndex++;
+ }
+ /* Ziv - Check */
+ rtw_write8(adapter, REG_INIRTS_RATE_SEL, RateIndex);
+}
+
/* Update RRSR and Rate for USERATE */
void update_tx_basic_rate(struct adapter *padapter, u8 wirelessmode)
{
@@ -1250,7 +1331,7 @@ void update_tx_basic_rate(struct adapter *padapter, u8 wirelessmode)
else
update_mgnt_tx_rate(padapter, IEEE80211_OFDM_RATE_6MB);
- SetHwReg8188EU(padapter, HW_VAR_BASIC_RATE, supported_rates);
+ rtw_set_basic_rate(padapter, supported_rates);
}
unsigned char check_assoc_AP(u8 *pframe, uint len)
@@ -1348,6 +1429,30 @@ static void set_ack_preamble(struct adapter *adapter, bool short_preamble)
rtw_write8(adapter, REG_RRSR + 2, val8);
};
+static void set_slot_time(struct adapter *adapter, u8 slot_time)
+{
+ u8 u1bAIFS, aSifsTime;
+ struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
+ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
+
+ rtw_write8(adapter, REG_SLOT, slot_time);
+
+ if (pmlmeinfo->WMM_enable == 0) {
+ if (pmlmeext->cur_wireless_mode == WIRELESS_11B)
+ aSifsTime = 10;
+ else
+ aSifsTime = 16;
+
+ u1bAIFS = aSifsTime + (2 * pmlmeinfo->slotTime);
+
+ /* <Roger_EXP> Temporary removed, 2008.06.20. */
+ rtw_write8(adapter, REG_EDCA_VO_PARAM, u1bAIFS);
+ rtw_write8(adapter, REG_EDCA_VI_PARAM, u1bAIFS);
+ rtw_write8(adapter, REG_EDCA_BE_PARAM, u1bAIFS);
+ rtw_write8(adapter, REG_EDCA_BK_PARAM, u1bAIFS);
+ }
+}
+
void update_capinfo(struct adapter *Adapter, u16 updateCap)
{
struct mlme_ext_priv *pmlmeext = &Adapter->mlmeextpriv;
@@ -1386,7 +1491,7 @@ void update_capinfo(struct adapter *Adapter, u16 updateCap)
}
}
- SetHwReg8188EU(Adapter, HW_VAR_SLOT_TIME, &pmlmeinfo->slotTime);
+ set_slot_time(Adapter, pmlmeinfo->slotTime);
}
void update_wireless_mode(struct adapter *padapter)
@@ -1466,26 +1571,6 @@ int update_sta_support_rate(struct adapter *padapter, u8 *pvar_ie, uint var_ie_l
return _SUCCESS;
}
-void update_TSF(struct mlme_ext_priv *pmlmeext, u8 *pframe, uint len)
-{
- u8 *pIE;
- __le32 *pbuf;
-
- pIE = pframe + sizeof(struct ieee80211_hdr_3addr);
- pbuf = (__le32 *)pIE;
-
- pmlmeext->TSFValue = le32_to_cpu(*(pbuf + 1));
-
- pmlmeext->TSFValue = pmlmeext->TSFValue << 32;
-
- pmlmeext->TSFValue |= le32_to_cpu(*pbuf);
-}
-
-void correct_TSF(struct adapter *padapter, struct mlme_ext_priv *pmlmeext)
-{
- SetHwReg8188EU(padapter, HW_VAR_CORRECT_TSF, NULL);
-}
-
void beacon_timing_control(struct adapter *padapter)
{
SetBeaconRelatedRegisters8188EUsb(padapter);
diff --git a/drivers/staging/r8188eu/core/rtw_xmit.c b/drivers/staging/r8188eu/core/rtw_xmit.c
index 7135d89caac1..24401f3ae2a0 100644
--- a/drivers/staging/r8188eu/core/rtw_xmit.c
+++ b/drivers/staging/r8188eu/core/rtw_xmit.c
@@ -16,16 +16,13 @@ static u8 RFC1042_OUI[P80211_OUI_LEN] = { 0x00, 0x00, 0x00 };
static void _init_txservq(struct tx_servq *ptxservq)
{
-
INIT_LIST_HEAD(&ptxservq->tx_pending);
rtw_init_queue(&ptxservq->sta_pending);
ptxservq->qcnt = 0;
-
}
void _rtw_init_sta_xmit_priv(struct sta_xmit_priv *psta_xmitpriv)
{
-
memset((unsigned char *)psta_xmitpriv, 0, sizeof(struct sta_xmit_priv));
spin_lock_init(&psta_xmitpriv->lock);
_init_txservq(&psta_xmitpriv->be_q);
@@ -34,7 +31,6 @@ void _rtw_init_sta_xmit_priv(struct sta_xmit_priv *psta_xmitpriv)
_init_txservq(&psta_xmitpriv->vo_q);
INIT_LIST_HEAD(&psta_xmitpriv->legacy_dz);
INIT_LIST_HEAD(&psta_xmitpriv->apsd);
-
}
s32 _rtw_init_xmit_priv(struct xmit_priv *pxmitpriv, struct adapter *padapter)
@@ -78,7 +74,7 @@ s32 _rtw_init_xmit_priv(struct xmit_priv *pxmitpriv, struct adapter *padapter)
res = _FAIL;
goto exit;
}
- pxmitpriv->pxmit_frame_buf = (u8 *)N_BYTE_ALIGMENT((size_t)(pxmitpriv->pallocated_frame_buf), 4);
+ pxmitpriv->pxmit_frame_buf = (u8 *)ALIGN((size_t)(pxmitpriv->pallocated_frame_buf), 4);
/* pxmitpriv->pxmit_frame_buf = pxmitpriv->pallocated_frame_buf + 4 - */
/* ((size_t) (pxmitpriv->pallocated_frame_buf) &3); */
@@ -115,7 +111,7 @@ s32 _rtw_init_xmit_priv(struct xmit_priv *pxmitpriv, struct adapter *padapter)
goto exit;
}
- pxmitpriv->pxmitbuf = (u8 *)N_BYTE_ALIGMENT((size_t)(pxmitpriv->pallocated_xmitbuf), 4);
+ pxmitpriv->pxmitbuf = (u8 *)ALIGN((size_t)(pxmitpriv->pallocated_xmitbuf), 4);
/* pxmitpriv->pxmitbuf = pxmitpriv->pallocated_xmitbuf + 4 - */
/* ((size_t) (pxmitpriv->pallocated_xmitbuf) &3); */
@@ -155,7 +151,7 @@ s32 _rtw_init_xmit_priv(struct xmit_priv *pxmitpriv, struct adapter *padapter)
goto exit;
}
- pxmitpriv->pxmit_extbuf = (u8 *)N_BYTE_ALIGMENT((size_t)(pxmitpriv->pallocated_xmit_extbuf), 4);
+ pxmitpriv->pxmit_extbuf = (u8 *)ALIGN((size_t)(pxmitpriv->pallocated_xmit_extbuf), 4);
pxmitbuf = (struct xmit_buf *)pxmitpriv->pxmit_extbuf;
@@ -299,6 +295,7 @@ static void update_attrib_vcs_info(struct adapter *padapter, struct xmit_frame *
/* check HT op mode */
if (pattrib->ht_en) {
u8 htopmode = pmlmeinfo->HT_protection;
+
if ((pmlmeext->cur_bwmode && (htopmode == 2 || htopmode == 3)) ||
(!pmlmeext->cur_bwmode && htopmode == 3)) {
pattrib->vcs_mode = RTS_CTS;
@@ -445,10 +442,11 @@ static s32 update_attrib(struct adapter *padapter, struct sk_buff *pkt, struct p
pattrib->pktlen = pktfile.pkt_len;
- if (ETH_P_IP == pattrib->ether_type) {
+ if (pattrib->ether_type == ETH_P_IP) {
/* The following is for DHCP and ARP packet, we use cck1M to tx these packets and let LPS awake some time */
/* to prevent DHCP protocol fail */
u8 tmp[24];
+
_rtw_pktfile_read(&pktfile, &tmp[0], 24);
pattrib->dhcp_pkt = 0;
if (pktfile.pkt_len > 282) {/* MINIMUM_DHCP_PACKET_SIZE) { */
@@ -627,7 +625,7 @@ static s32 xmitframe_addmic(struct adapter *padapter, struct xmit_frame *pxmitfr
if (pframe[1] & 2) /* From Ds == 1 */
rtw_secmicappend(&micdata, &pframe[24], 6);
else
- rtw_secmicappend(&micdata, &pframe[10], 6);
+ rtw_secmicappend(&micdata, &pframe[10], 6);
} else { /* ToDS == 0 */
rtw_secmicappend(&micdata, &pframe[4], 6); /* DA */
if (pframe[1] & 2) /* From Ds == 1 */
@@ -953,12 +951,11 @@ s32 rtw_xmitframe_coalesce(struct adapter *padapter, struct sk_buff *pkt, struct
mpdu_len -= llc_sz;
}
- if ((pattrib->icv_len > 0) && (pattrib->bswenc)) {
+ if ((pattrib->icv_len > 0) && (pattrib->bswenc))
mpdu_len -= pattrib->icv_len;
- }
if (bmcst) {
- /* don't do fragment to broadcat/multicast packets */
+ /* don't do fragment to broadcast/multicast packets */
mem_sz = _rtw_pktfile_read(&pktfile, pframe, pattrib->pktlen);
} else {
mem_sz = _rtw_pktfile_read(&pktfile, pframe, mpdu_len);
@@ -1068,7 +1065,6 @@ void rtw_update_protection(struct adapter *padapter, u8 *ie, uint ie_len)
}
break;
}
-
}
void rtw_count_tx_stats(struct adapter *padapter, struct xmit_frame *pxmitframe, int sz)
@@ -1315,7 +1311,6 @@ void rtw_free_xmitframe_queue(struct xmit_priv *pxmitpriv, struct __queue *pfram
rtw_free_xmitframe(pxmitpriv, pxmitframe);
}
spin_unlock_bh(&pframequeue->lock);
-
}
s32 rtw_xmitframe_enqueue(struct adapter *padapter, struct xmit_frame *pxmitframe)
@@ -1505,7 +1500,6 @@ void rtw_init_hwxmits(struct hw_xmit *phwxmit, int entry)
for (i = 0; i < entry; i++, phwxmit++)
phwxmit->accnt = 0;
-
}
static int rtw_br_client_tx(struct adapter *padapter, struct sk_buff **pskb)
@@ -1732,7 +1726,7 @@ int xmitframe_enqueue_for_sleeping_sta(struct adapter *padapter, struct xmit_fra
bool bmcst = is_multicast_ether_addr(pattrib->ra);
if (!check_fwstate(pmlmepriv, WIFI_AP_STATE))
- return ret;
+ return ret;
if (pattrib->psta)
psta = pattrib->psta;
@@ -1760,8 +1754,8 @@ int xmitframe_enqueue_for_sleeping_sta(struct adapter *padapter, struct xmit_fra
pstapriv->tim_bitmap |= BIT(0);/* */
pstapriv->sta_dz_bitmap |= BIT(0);
-
- update_beacon(padapter, _TIM_IE_, NULL, false);/* tx bc/mc packets after upate bcn */
+ /* tx bc/mc packets after update bcn */
+ update_beacon(padapter, _TIM_IE_, NULL, false);
ret = true;
}
@@ -1811,7 +1805,7 @@ int xmitframe_enqueue_for_sleeping_sta(struct adapter *padapter, struct xmit_fra
pstapriv->tim_bitmap |= BIT(psta->aid);
if (psta->sleepq_len == 1) {
- /* upate BCN for TIM IE */
+ /* update BCN for TIM IE */
update_beacon(padapter, _TIM_IE_, NULL, false);
}
}
@@ -2080,7 +2074,7 @@ void xmit_delivery_enabled_frames(struct adapter *padapter, struct sta_info *pst
if ((psta->sleepq_ac_len == 0) && (!psta->has_legacy_ac) && (wmmps_ac)) {
pstapriv->tim_bitmap &= ~BIT(psta->aid);
- /* upate BCN for TIM IE */
+ /* update BCN for TIM IE */
update_beacon(padapter, _TIM_IE_, NULL, false);
}
}
diff --git a/drivers/staging/r8188eu/hal/Hal8188EPwrSeq.c b/drivers/staging/r8188eu/hal/Hal8188EPwrSeq.c
deleted file mode 100644
index 6505e1fcb070..000000000000
--- a/drivers/staging/r8188eu/hal/Hal8188EPwrSeq.c
+++ /dev/null
@@ -1,45 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/* Copyright(c) 2007 - 2011 Realtek Corporation. */
-
-#include "../include/Hal8188EPwrSeq.h"
-#include "../include/rtl8188e_hal.h"
-
-struct wl_pwr_cfg rtl8188E_power_on_flow[] = {
- { 0x0006, PWR_CMD_POLLING, BIT(1), BIT(1) },
- { 0x0002, PWR_CMD_WRITE, BIT(0) | BIT(1), 0 }, /* reset BB */
- { 0x0026, PWR_CMD_WRITE, BIT(7), BIT(7) }, /* schmitt trigger */
- { 0x0005, PWR_CMD_WRITE, BIT(7), 0 }, /* disable HWPDN (control by DRV)*/
- { 0x0005, PWR_CMD_WRITE, BIT(4) | BIT(3), 0 }, /* disable WL suspend*/
- { 0x0005, PWR_CMD_WRITE, BIT(0), BIT(0) },
- { 0x0005, PWR_CMD_POLLING, BIT(0), 0 },
- { 0x0023, PWR_CMD_WRITE, BIT(4), 0 },
- { 0xFFFF, PWR_CMD_END, 0, 0 },
-};
-
-struct wl_pwr_cfg rtl8188E_card_disable_flow[] = {
- { 0x001F, PWR_CMD_WRITE, 0xFF, 0 }, /* turn off RF */
- { 0x0023, PWR_CMD_WRITE, BIT(4), BIT(4) }, /* LDO Sleep mode */
- { 0x0005, PWR_CMD_WRITE, BIT(1), BIT(1) }, /* turn off MAC by HW state machine */
- { 0x0005, PWR_CMD_POLLING, BIT(1), 0 },
- { 0x0026, PWR_CMD_WRITE, BIT(7), BIT(7) }, /* schmitt trigger */
- { 0x0005, PWR_CMD_WRITE, BIT(3) | BIT(4), BIT(3) }, /* enable WL suspend */
- { 0x0007, PWR_CMD_WRITE, 0xFF, 0 }, /* enable bandgap mbias in suspend */
- { 0x0041, PWR_CMD_WRITE, BIT(4), 0 }, /* Clear SIC_EN register */
- { 0xfe10, PWR_CMD_WRITE, BIT(4), BIT(4) }, /* Set USB suspend enable local register */
- { 0xFFFF, PWR_CMD_END, 0, 0 },
-};
-
-/* This is used by driver for LPSRadioOff Procedure, not for FW LPS Step */
-struct wl_pwr_cfg rtl8188E_enter_lps_flow[] = {
- { 0x0522, PWR_CMD_WRITE, 0xFF, 0x7F },/* Tx Pause */
- { 0x05F8, PWR_CMD_POLLING, 0xFF, 0 }, /* Should be zero if no packet is transmitted */
- { 0x05F9, PWR_CMD_POLLING, 0xFF, 0 }, /* Should be zero if no packet is transmitted */
- { 0x05FA, PWR_CMD_POLLING, 0xFF, 0 }, /* Should be zero if no packet is transmitted */
- { 0x05FB, PWR_CMD_POLLING, 0xFF, 0 }, /* Should be zero if no packet is transmitted */
- { 0x0002, PWR_CMD_WRITE, BIT(0), 0 }, /* CCK and OFDM are disabled, clocks are gated */
- { 0x0002, PWR_CMD_DELAY, 0, PWRSEQ_DELAY_US },
- { 0x0100, PWR_CMD_WRITE, 0xFF, 0x3F }, /* Reset MAC TRX */
- { 0x0101, PWR_CMD_WRITE, BIT(1), 0 }, /* check if removed later */
- { 0x0553, PWR_CMD_WRITE, BIT(5), BIT(5) }, /* Respond TxOK to scheduler */
- { 0xFFFF, PWR_CMD_END, 0, 0 },
-};
diff --git a/drivers/staging/r8188eu/hal/Hal8188ERateAdaptive.c b/drivers/staging/r8188eu/hal/Hal8188ERateAdaptive.c
index 57e8f5573846..1e04de3a6622 100644
--- a/drivers/staging/r8188eu/hal/Hal8188ERateAdaptive.c
+++ b/drivers/staging/r8188eu/hal/Hal8188ERateAdaptive.c
@@ -279,6 +279,7 @@ static int odm_ARFBRefresh_8188E(struct odm_dm_struct *dm_odm, struct odm_ra_inf
{ /* Wilson 2011/10/26 */
u32 MaskFromReg;
s8 i;
+ int res;
switch (pRaInfo->RateID) {
case RATR_INX_WIRELESS_NGB:
@@ -303,19 +304,31 @@ static int odm_ARFBRefresh_8188E(struct odm_dm_struct *dm_odm, struct odm_ra_inf
pRaInfo->RAUseRate = (pRaInfo->RateMask) & 0x0000000d;
break;
case 12:
- MaskFromReg = rtw_read32(dm_odm->Adapter, REG_ARFR0);
+ res = rtw_read32(dm_odm->Adapter, REG_ARFR0, &MaskFromReg);
+ if (res)
+ return res;
+
pRaInfo->RAUseRate = (pRaInfo->RateMask) & MaskFromReg;
break;
case 13:
- MaskFromReg = rtw_read32(dm_odm->Adapter, REG_ARFR1);
+ res = rtw_read32(dm_odm->Adapter, REG_ARFR1, &MaskFromReg);
+ if (res)
+ return res;
+
pRaInfo->RAUseRate = (pRaInfo->RateMask) & MaskFromReg;
break;
case 14:
- MaskFromReg = rtw_read32(dm_odm->Adapter, REG_ARFR2);
+ res = rtw_read32(dm_odm->Adapter, REG_ARFR2, &MaskFromReg);
+ if (res)
+ return res;
+
pRaInfo->RAUseRate = (pRaInfo->RateMask) & MaskFromReg;
break;
case 15:
- MaskFromReg = rtw_read32(dm_odm->Adapter, REG_ARFR3);
+ res = rtw_read32(dm_odm->Adapter, REG_ARFR3, &MaskFromReg);
+ if (res)
+ return res;
+
pRaInfo->RAUseRate = (pRaInfo->RateMask) & MaskFromReg;
break;
default:
@@ -601,12 +614,12 @@ void ODM_RA_TxRPT2Handle_8188E(struct odm_dm_struct *dm_odm, u8 *TxRPT_Buf, u16
pRAInfo = &dm_odm->RAInfo[MacId];
if (valid) {
- pRAInfo->RTY[0] = (u16)GET_TX_REPORT_TYPE1_RERTY_0(pBuffer);
- pRAInfo->RTY[1] = (u16)GET_TX_REPORT_TYPE1_RERTY_1(pBuffer);
- pRAInfo->RTY[2] = (u16)GET_TX_REPORT_TYPE1_RERTY_2((u8 *)pBuffer);
- pRAInfo->RTY[3] = (u16)GET_TX_REPORT_TYPE1_RERTY_3(pBuffer);
- pRAInfo->RTY[4] = (u16)GET_TX_REPORT_TYPE1_RERTY_4(pBuffer);
- pRAInfo->DROP = (u16)GET_TX_REPORT_TYPE1_DROP_0(pBuffer);
+ pRAInfo->RTY[0] = le16_to_cpup((__le16 *)pBuffer);
+ pRAInfo->RTY[1] = pBuffer[2];
+ pRAInfo->RTY[2] = pBuffer[3];
+ pRAInfo->RTY[3] = pBuffer[4];
+ pRAInfo->RTY[4] = pBuffer[5];
+ pRAInfo->DROP = pBuffer[6];
pRAInfo->TOTAL = pRAInfo->RTY[0] + pRAInfo->RTY[1] +
pRAInfo->RTY[2] + pRAInfo->RTY[3] +
pRAInfo->RTY[4] + pRAInfo->DROP;
diff --git a/drivers/staging/r8188eu/hal/HalPhyRf_8188e.c b/drivers/staging/r8188eu/hal/HalPhyRf_8188e.c
index b944c8071a3b..525deab10820 100644
--- a/drivers/staging/r8188eu/hal/HalPhyRf_8188e.c
+++ b/drivers/staging/r8188eu/hal/HalPhyRf_8188e.c
@@ -463,6 +463,7 @@ void _PHY_SaveADDARegisters(struct adapter *adapt, u32 *ADDAReg, u32 *ADDABackup
}
}
+/* FIXME: return an error to caller */
static void _PHY_SaveMACRegisters(
struct adapter *adapt,
u32 *MACReg,
@@ -470,11 +471,20 @@ static void _PHY_SaveMACRegisters(
)
{
u32 i;
+ int res;
- for (i = 0; i < (IQK_MAC_REG_NUM - 1); i++)
- MACBackup[i] = rtw_read8(adapt, MACReg[i]);
+ for (i = 0; i < (IQK_MAC_REG_NUM - 1); i++) {
+ u8 reg;
+
+ res = rtw_read8(adapt, MACReg[i], &reg);
+ if (res)
+ return;
- MACBackup[i] = rtw_read32(adapt, MACReg[i]);
+ MACBackup[i] = reg;
+ }
+
+ res = rtw_read32(adapt, MACReg[i], MACBackup + i);
+ (void)res;
}
static void reload_adda_reg(struct adapter *adapt, u32 *ADDAReg, u32 *ADDABackup, u32 RegiesterNum)
@@ -739,9 +749,12 @@ static void phy_LCCalibrate_8188E(struct adapter *adapt)
{
u8 tmpreg;
u32 RF_Amode = 0, LC_Cal;
+ int res;
/* Check continuous TX and Packet TX */
- tmpreg = rtw_read8(adapt, 0xd03);
+ res = rtw_read8(adapt, 0xd03, &tmpreg);
+ if (res)
+ return;
if ((tmpreg & 0x70) != 0) /* Deal with contisuous TX case */
rtw_write8(adapt, 0xd03, tmpreg & 0x8F); /* disable all continuous TX */
diff --git a/drivers/staging/r8188eu/hal/HalPwrSeqCmd.c b/drivers/staging/r8188eu/hal/HalPwrSeqCmd.c
index 150ea380c39e..6c0b1368383d 100644
--- a/drivers/staging/r8188eu/hal/HalPwrSeqCmd.c
+++ b/drivers/staging/r8188eu/hal/HalPwrSeqCmd.c
@@ -3,25 +3,116 @@
#include "../include/HalPwrSeqCmd.h"
-u8 HalPwrSeqCmdParsing(struct adapter *padapter, struct wl_pwr_cfg pwrseqcmd[])
+#define PWR_CMD_WRITE 0x01
+ /* offset: the read register offset */
+ /* msk: the mask of the write bits */
+ /* value: write value */
+ /* note: driver shall implement this cmd by read & msk after write */
+
+#define PWR_CMD_POLLING 0x02
+ /* offset: the read register offset */
+ /* msk: the mask of the polled value */
+ /* value: the value to be polled, masked by the msd field. */
+ /* note: driver shall implement this cmd by */
+ /* do{ */
+ /* if ( (Read(offset) & msk) == (value & msk) ) */
+ /* break; */
+ /* } while (not timeout); */
+
+#define PWR_CMD_DELAY 0x03
+ /* offset: the value to delay (in us) */
+ /* msk: N/A */
+ /* value: N/A */
+
+struct wl_pwr_cfg {
+ u16 offset;
+ u8 cmd:4;
+ u8 msk;
+ u8 value;
+};
+
+#define GET_PWR_CFG_OFFSET(__PWR_CMD) __PWR_CMD.offset
+#define GET_PWR_CFG_CMD(__PWR_CMD) __PWR_CMD.cmd
+#define GET_PWR_CFG_MASK(__PWR_CMD) __PWR_CMD.msk
+#define GET_PWR_CFG_VALUE(__PWR_CMD) __PWR_CMD.value
+
+static struct wl_pwr_cfg rtl8188E_power_on_flow[] = {
+ { 0x0006, PWR_CMD_POLLING, BIT(1), BIT(1) },
+ { 0x0002, PWR_CMD_WRITE, BIT(0) | BIT(1), 0 }, /* reset BB */
+ { 0x0026, PWR_CMD_WRITE, BIT(7), BIT(7) }, /* schmitt trigger */
+ { 0x0005, PWR_CMD_WRITE, BIT(7), 0 }, /* disable HWPDN (control by DRV)*/
+ { 0x0005, PWR_CMD_WRITE, BIT(4) | BIT(3), 0 }, /* disable WL suspend*/
+ { 0x0005, PWR_CMD_WRITE, BIT(0), BIT(0) },
+ { 0x0005, PWR_CMD_POLLING, BIT(0), 0 },
+ { 0x0023, PWR_CMD_WRITE, BIT(4), 0 },
+};
+
+static struct wl_pwr_cfg rtl8188E_card_disable_flow[] = {
+ { 0x001F, PWR_CMD_WRITE, 0xFF, 0 }, /* turn off RF */
+ { 0x0023, PWR_CMD_WRITE, BIT(4), BIT(4) }, /* LDO Sleep mode */
+ { 0x0005, PWR_CMD_WRITE, BIT(1), BIT(1) }, /* turn off MAC by HW state machine */
+ { 0x0005, PWR_CMD_POLLING, BIT(1), 0 },
+ { 0x0026, PWR_CMD_WRITE, BIT(7), BIT(7) }, /* schmitt trigger */
+ { 0x0005, PWR_CMD_WRITE, BIT(3) | BIT(4), BIT(3) }, /* enable WL suspend */
+ { 0x0007, PWR_CMD_WRITE, 0xFF, 0 }, /* enable bandgap mbias in suspend */
+ { 0x0041, PWR_CMD_WRITE, BIT(4), 0 }, /* Clear SIC_EN register */
+ { 0xfe10, PWR_CMD_WRITE, BIT(4), BIT(4) }, /* Set USB suspend enable local register */
+};
+
+/* This is used by driver for LPSRadioOff Procedure, not for FW LPS Step */
+static struct wl_pwr_cfg rtl8188E_enter_lps_flow[] = {
+ { 0x0522, PWR_CMD_WRITE, 0xFF, 0x7F },/* Tx Pause */
+ { 0x05F8, PWR_CMD_POLLING, 0xFF, 0 }, /* Should be zero if no packet is transmitted */
+ { 0x05F9, PWR_CMD_POLLING, 0xFF, 0 }, /* Should be zero if no packet is transmitted */
+ { 0x05FA, PWR_CMD_POLLING, 0xFF, 0 }, /* Should be zero if no packet is transmitted */
+ { 0x05FB, PWR_CMD_POLLING, 0xFF, 0 }, /* Should be zero if no packet is transmitted */
+ { 0x0002, PWR_CMD_WRITE, BIT(0), 0 }, /* CCK and OFDM are disabled, clocks are gated */
+ { 0x0002, PWR_CMD_DELAY, 0, 0 },
+ { 0x0100, PWR_CMD_WRITE, 0xFF, 0x3F }, /* Reset MAC TRX */
+ { 0x0101, PWR_CMD_WRITE, BIT(1), 0 }, /* check if removed later */
+ { 0x0553, PWR_CMD_WRITE, BIT(5), BIT(5) }, /* Respond TxOK to scheduler */
+};
+
+u8 HalPwrSeqCmdParsing(struct adapter *padapter, enum r8188eu_pwr_seq seq)
{
struct wl_pwr_cfg pwrcfgcmd = {0};
+ struct wl_pwr_cfg *pwrseqcmd;
u8 poll_bit = false;
- u32 aryidx = 0;
+ u8 idx, num_steps;
u8 value = 0;
u32 offset = 0;
u32 poll_count = 0; /* polling autoload done. */
u32 max_poll_count = 5000;
+ int res;
+
+ switch (seq) {
+ case PWR_ON_FLOW:
+ pwrseqcmd = rtl8188E_power_on_flow;
+ num_steps = ARRAY_SIZE(rtl8188E_power_on_flow);
+ break;
+ case DISABLE_FLOW:
+ pwrseqcmd = rtl8188E_card_disable_flow;
+ num_steps = ARRAY_SIZE(rtl8188E_card_disable_flow);
+ break;
+ case LPS_ENTER_FLOW:
+ pwrseqcmd = rtl8188E_enter_lps_flow;
+ num_steps = ARRAY_SIZE(rtl8188E_enter_lps_flow);
+ break;
+ default:
+ return false;
+ }
- do {
- pwrcfgcmd = pwrseqcmd[aryidx];
+ for (idx = 0; idx < num_steps; idx++) {
+ pwrcfgcmd = pwrseqcmd[idx];
switch (GET_PWR_CFG_CMD(pwrcfgcmd)) {
case PWR_CMD_WRITE:
offset = GET_PWR_CFG_OFFSET(pwrcfgcmd);
/* Read the value from system register */
- value = rtw_read8(padapter, offset);
+ res = rtw_read8(padapter, offset, &value);
+ if (res)
+ return false;
value &= ~(GET_PWR_CFG_MASK(pwrcfgcmd));
value |= (GET_PWR_CFG_VALUE(pwrcfgcmd) & GET_PWR_CFG_MASK(pwrcfgcmd));
@@ -33,7 +124,9 @@ u8 HalPwrSeqCmdParsing(struct adapter *padapter, struct wl_pwr_cfg pwrseqcmd[])
poll_bit = false;
offset = GET_PWR_CFG_OFFSET(pwrcfgcmd);
do {
- value = rtw_read8(padapter, offset);
+ res = rtw_read8(padapter, offset, &value);
+ if (res)
+ return false;
value &= GET_PWR_CFG_MASK(pwrcfgcmd);
if (value == (GET_PWR_CFG_VALUE(pwrcfgcmd) & GET_PWR_CFG_MASK(pwrcfgcmd)))
@@ -46,20 +139,11 @@ u8 HalPwrSeqCmdParsing(struct adapter *padapter, struct wl_pwr_cfg pwrseqcmd[])
} while (!poll_bit);
break;
case PWR_CMD_DELAY:
- if (GET_PWR_CFG_VALUE(pwrcfgcmd) == PWRSEQ_DELAY_US)
- udelay(GET_PWR_CFG_OFFSET(pwrcfgcmd));
- else
- udelay(GET_PWR_CFG_OFFSET(pwrcfgcmd) * 1000);
- break;
- case PWR_CMD_END:
- /* When this command is parsed, end the process */
- return true;
+ udelay(GET_PWR_CFG_OFFSET(pwrcfgcmd));
break;
default:
break;
}
-
- aryidx++;/* Add Array Index */
- } while (1);
+ }
return true;
}
diff --git a/drivers/staging/r8188eu/hal/hal_com.c b/drivers/staging/r8188eu/hal/hal_com.c
index 910cc07f656c..6a1cdc67335b 100644
--- a/drivers/staging/r8188eu/hal/hal_com.c
+++ b/drivers/staging/r8188eu/hal/hal_com.c
@@ -10,45 +10,6 @@
#define _HAL_INIT_C_
-void dump_chip_info(struct HAL_VERSION chip_vers)
-{
- uint cnt = 0;
- char buf[128];
-
- cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8188E_");
- cnt += sprintf((buf + cnt), "%s_", IS_NORMAL_CHIP(chip_vers) ?
- "Normal_Chip" : "Test_Chip");
- cnt += sprintf((buf + cnt), "%s_", IS_CHIP_VENDOR_TSMC(chip_vers) ?
- "TSMC" : "UMC");
-
- switch (chip_vers.CUTVersion) {
- case A_CUT_VERSION:
- cnt += sprintf((buf + cnt), "A_CUT_");
- break;
- case B_CUT_VERSION:
- cnt += sprintf((buf + cnt), "B_CUT_");
- break;
- case C_CUT_VERSION:
- cnt += sprintf((buf + cnt), "C_CUT_");
- break;
- case D_CUT_VERSION:
- cnt += sprintf((buf + cnt), "D_CUT_");
- break;
- case E_CUT_VERSION:
- cnt += sprintf((buf + cnt), "E_CUT_");
- break;
- default:
- cnt += sprintf((buf + cnt), "UNKNOWN_CUT(%d)_", chip_vers.CUTVersion);
- break;
- }
-
- cnt += sprintf((buf + cnt), "1T1R_");
-
- cnt += sprintf((buf + cnt), "RomVer(%d)\n", 0);
-
- pr_info("%s", buf);
-}
-
#define CHAN_PLAN_HW 0x80
u8 /* return the final channel plan decision */
@@ -303,7 +264,9 @@ s32 c2h_evt_read(struct adapter *adapter, u8 *buf)
if (!buf)
goto exit;
- trigger = rtw_read8(adapter, REG_C2HEVT_CLEAR);
+ ret = rtw_read8(adapter, REG_C2HEVT_CLEAR, &trigger);
+ if (ret)
+ return _FAIL;
if (trigger == C2H_EVT_HOST_CLOSE)
goto exit; /* Not ready */
@@ -314,13 +277,26 @@ s32 c2h_evt_read(struct adapter *adapter, u8 *buf)
memset(c2h_evt, 0, 16);
- *buf = rtw_read8(adapter, REG_C2HEVT_MSG_NORMAL);
- *(buf + 1) = rtw_read8(adapter, REG_C2HEVT_MSG_NORMAL + 1);
+ ret = rtw_read8(adapter, REG_C2HEVT_MSG_NORMAL, buf);
+ if (ret) {
+ ret = _FAIL;
+ goto clear_evt;
+ }
+ ret = rtw_read8(adapter, REG_C2HEVT_MSG_NORMAL + 1, buf + 1);
+ if (ret) {
+ ret = _FAIL;
+ goto clear_evt;
+ }
/* Read the content */
- for (i = 0; i < c2h_evt->plen; i++)
- c2h_evt->payload[i] = rtw_read8(adapter, REG_C2HEVT_MSG_NORMAL +
- sizeof(*c2h_evt) + i);
+ for (i = 0; i < c2h_evt->plen; i++) {
+ ret = rtw_read8(adapter, REG_C2HEVT_MSG_NORMAL +
+ sizeof(*c2h_evt) + i, c2h_evt->payload + i);
+ if (ret) {
+ ret = _FAIL;
+ goto clear_evt;
+ }
+ }
ret = _SUCCESS;
diff --git a/drivers/staging/r8188eu/hal/rtl8188e_cmd.c b/drivers/staging/r8188eu/hal/rtl8188e_cmd.c
index 475650dc7301..b01ee1695fee 100644
--- a/drivers/staging/r8188eu/hal/rtl8188e_cmd.c
+++ b/drivers/staging/r8188eu/hal/rtl8188e_cmd.c
@@ -18,13 +18,18 @@
static u8 _is_fw_read_cmd_down(struct adapter *adapt, u8 msgbox_num)
{
- u8 read_down = false;
+ u8 read_down = false, reg;
int retry_cnts = 100;
+ int res;
u8 valid;
do {
- valid = rtw_read8(adapt, REG_HMETFR) & BIT(msgbox_num);
+ res = rtw_read8(adapt, REG_HMETFR, &reg);
+ if (res)
+ continue;
+
+ valid = reg & BIT(msgbox_num);
if (0 == valid)
read_down = true;
} while ((!read_down) && (retry_cnts--));
@@ -533,6 +538,8 @@ void rtl8188e_set_FwJoinBssReport_cmd(struct adapter *adapt, u8 mstatus)
bool bcn_valid = false;
u8 DLBcnCount = 0;
u32 poll = 0;
+ u8 reg;
+ int res;
if (mstatus == 1) {
/* We should set AID, correct TSF, HW seq enable before set JoinBssReport to Fw in 88/92C. */
@@ -547,8 +554,17 @@ void rtl8188e_set_FwJoinBssReport_cmd(struct adapter *adapt, u8 mstatus)
/* Disable Hw protection for a time which revserd for Hw sending beacon. */
/* Fix download reserved page packet fail that access collision with the protection time. */
/* 2010.05.11. Added by tynli. */
- rtw_write8(adapt, REG_BCN_CTRL, rtw_read8(adapt, REG_BCN_CTRL) & (~BIT(3)));
- rtw_write8(adapt, REG_BCN_CTRL, rtw_read8(adapt, REG_BCN_CTRL) | BIT(4));
+ res = rtw_read8(adapt, REG_BCN_CTRL, &reg);
+ if (res)
+ return;
+
+ rtw_write8(adapt, REG_BCN_CTRL, reg & (~BIT(3)));
+
+ res = rtw_read8(adapt, REG_BCN_CTRL, &reg);
+ if (res)
+ return;
+
+ rtw_write8(adapt, REG_BCN_CTRL, reg | BIT(4));
if (haldata->RegFwHwTxQCtrl & BIT(6))
bSendBeacon = true;
@@ -581,8 +597,17 @@ void rtl8188e_set_FwJoinBssReport_cmd(struct adapter *adapt, u8 mstatus)
/* */
/* Enable Bcn */
- rtw_write8(adapt, REG_BCN_CTRL, rtw_read8(adapt, REG_BCN_CTRL) | BIT(3));
- rtw_write8(adapt, REG_BCN_CTRL, rtw_read8(adapt, REG_BCN_CTRL) & (~BIT(4)));
+ res = rtw_read8(adapt, REG_BCN_CTRL, &reg);
+ if (res)
+ return;
+
+ rtw_write8(adapt, REG_BCN_CTRL, reg | BIT(3));
+
+ res = rtw_read8(adapt, REG_BCN_CTRL, &reg);
+ if (res)
+ return;
+
+ rtw_write8(adapt, REG_BCN_CTRL, reg & (~BIT(4)));
/* To make sure that if there exists an adapter which would like to send beacon. */
/* If exists, the origianl value of 0x422[6] will be 1, we should check this to */
diff --git a/drivers/staging/r8188eu/hal/rtl8188e_dm.c b/drivers/staging/r8188eu/hal/rtl8188e_dm.c
index 6d28e3dc0d26..0399872c4546 100644
--- a/drivers/staging/r8188eu/hal/rtl8188e_dm.c
+++ b/drivers/staging/r8188eu/hal/rtl8188e_dm.c
@@ -12,8 +12,12 @@
static void dm_InitGPIOSetting(struct adapter *Adapter)
{
u8 tmp1byte;
+ int res;
+
+ res = rtw_read8(Adapter, REG_GPIO_MUXCFG, &tmp1byte);
+ if (res)
+ return;
- tmp1byte = rtw_read8(Adapter, REG_GPIO_MUXCFG);
tmp1byte &= (GPIOSEL_GPIO | ~GPIOSEL_ENBT);
rtw_write8(Adapter, REG_GPIO_MUXCFG, tmp1byte);
diff --git a/drivers/staging/r8188eu/hal/rtl8188e_hal_init.c b/drivers/staging/r8188eu/hal/rtl8188e_hal_init.c
index e17375a74f17..5b8f1a912bbb 100644
--- a/drivers/staging/r8188eu/hal/rtl8188e_hal_init.c
+++ b/drivers/staging/r8188eu/hal/rtl8188e_hal_init.c
@@ -13,10 +13,14 @@
static void iol_mode_enable(struct adapter *padapter, u8 enable)
{
u8 reg_0xf0 = 0;
+ int res;
if (enable) {
/* Enable initial offload */
- reg_0xf0 = rtw_read8(padapter, REG_SYS_CFG);
+ res = rtw_read8(padapter, REG_SYS_CFG, &reg_0xf0);
+ if (res)
+ return;
+
rtw_write8(padapter, REG_SYS_CFG, reg_0xf0 | SW_OFFLOAD_EN);
if (!padapter->bFWReady)
@@ -24,7 +28,10 @@ static void iol_mode_enable(struct adapter *padapter, u8 enable)
} else {
/* disable initial offload */
- reg_0xf0 = rtw_read8(padapter, REG_SYS_CFG);
+ res = rtw_read8(padapter, REG_SYS_CFG, &reg_0xf0);
+ if (res)
+ return;
+
rtw_write8(padapter, REG_SYS_CFG, reg_0xf0 & ~SW_OFFLOAD_EN);
}
}
@@ -34,17 +41,31 @@ static s32 iol_execute(struct adapter *padapter, u8 control)
s32 status = _FAIL;
u8 reg_0x88 = 0;
unsigned long timeout;
+ int res;
control = control & 0x0f;
- reg_0x88 = rtw_read8(padapter, REG_HMEBOX_E0);
+ res = rtw_read8(padapter, REG_HMEBOX_E0, &reg_0x88);
+ if (res)
+ return _FAIL;
+
rtw_write8(padapter, REG_HMEBOX_E0, reg_0x88 | control);
timeout = jiffies + msecs_to_jiffies(1000);
- while ((reg_0x88 = rtw_read8(padapter, REG_HMEBOX_E0)) & control &&
- time_before(jiffies, timeout))
- ;
- reg_0x88 = rtw_read8(padapter, REG_HMEBOX_E0);
+ do {
+ res = rtw_read8(padapter, REG_HMEBOX_E0, &reg_0x88);
+ if (res)
+ continue;
+
+ if (!(reg_0x88 & control))
+ break;
+
+ } while (time_before(jiffies, timeout));
+
+ res = rtw_read8(padapter, REG_HMEBOX_E0, &reg_0x88);
+ if (res)
+ return _FAIL;
+
status = (reg_0x88 & control) ? _FAIL : _SUCCESS;
if (reg_0x88 & control << 4)
status = _FAIL;
@@ -62,7 +83,7 @@ static s32 iol_InitLLTTable(struct adapter *padapter, u8 txpktbuf_bndy)
}
static void
-efuse_phymap_to_logical(u8 *phymap, u16 _offset, u16 _size_byte, u8 *pbuf)
+efuse_phymap_to_logical(u8 *phymap, u16 _size_byte, u8 *pbuf)
{
u8 *efuseTbl = NULL;
u8 rtemp8;
@@ -70,7 +91,6 @@ efuse_phymap_to_logical(u8 *phymap, u16 _offset, u16 _size_byte, u8 *pbuf)
u8 offset, wren;
u16 i, j;
u16 **eFuseWord = NULL;
- u16 efuse_utilized = 0;
u8 u1temp = 0;
efuseTbl = kzalloc(EFUSE_MAP_LEN_88E, GFP_KERNEL);
@@ -92,7 +112,6 @@ efuse_phymap_to_logical(u8 *phymap, u16 _offset, u16 _size_byte, u8 *pbuf)
/* */
rtemp8 = *(phymap + eFuse_Addr);
if (rtemp8 != 0xFF) {
- efuse_utilized++;
eFuse_Addr++;
} else {
goto exit;
@@ -130,13 +149,11 @@ efuse_phymap_to_logical(u8 *phymap, u16 _offset, u16 _size_byte, u8 *pbuf)
if (!(wren & 0x01)) {
rtemp8 = *(phymap + eFuse_Addr);
eFuse_Addr++;
- efuse_utilized++;
eFuseWord[offset][i] = (rtemp8 & 0xff);
if (eFuse_Addr >= EFUSE_REAL_CONTENT_LEN_88E)
break;
rtemp8 = *(phymap + eFuse_Addr);
eFuse_Addr++;
- efuse_utilized++;
eFuseWord[offset][i] |= (((u16)rtemp8 << 8) & 0xff00);
if (eFuse_Addr >= EFUSE_REAL_CONTENT_LEN_88E)
@@ -149,7 +166,6 @@ efuse_phymap_to_logical(u8 *phymap, u16 _offset, u16 _size_byte, u8 *pbuf)
rtemp8 = *(phymap + eFuse_Addr);
if (rtemp8 != 0xFF && (eFuse_Addr < EFUSE_REAL_CONTENT_LEN_88E)) {
- efuse_utilized++;
eFuse_Addr++;
}
}
@@ -167,59 +183,70 @@ efuse_phymap_to_logical(u8 *phymap, u16 _offset, u16 _size_byte, u8 *pbuf)
/* */
/* 4. Copy from Efuse map to output pointer memory!!! */
/* */
- for (i = 0; i < _size_byte; i++)
- pbuf[i] = efuseTbl[_offset + i];
-
- /* */
- /* 5. Calculate Efuse utilization. */
- /* */
+ memcpy(pbuf, efuseTbl, _size_byte);
exit:
kfree(efuseTbl);
kfree(eFuseWord);
}
-static void efuse_read_phymap_from_txpktbuf(
+/* FIXME: add error handling in callers */
+static int efuse_read_phymap_from_txpktbuf(
struct adapter *adapter,
- int bcnhead, /* beacon head, where FW store len(2-byte) and efuse physical map. */
u8 *content, /* buffer to store efuse physical map */
u16 *size /* for efuse content: the max byte to read. will update to byte read */
)
{
unsigned long timeout;
- u16 dbg_addr = 0;
__le32 lo32 = 0, hi32 = 0;
u16 len = 0, count = 0;
- int i = 0;
+ int i = 0, res;
u16 limit = *size;
-
+ u8 reg;
u8 *pos = content;
-
- if (bcnhead < 0) /* if not valid */
- bcnhead = rtw_read8(adapter, REG_TDECTRL + 1);
+ u32 reg32;
rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL, TXPKT_BUF_SELECT);
- dbg_addr = bcnhead * 128 / 8; /* 8-bytes addressing */
-
while (1) {
- rtw_write16(adapter, REG_PKTBUF_DBG_ADDR, dbg_addr + i);
+ rtw_write16(adapter, REG_PKTBUF_DBG_ADDR, i);
rtw_write8(adapter, REG_TXPKTBUF_DBG, 0);
timeout = jiffies + msecs_to_jiffies(1000);
- while (!rtw_read8(adapter, REG_TXPKTBUF_DBG) && time_before(jiffies, timeout))
- rtw_usleep_os(100);
+ do {
+ res = rtw_read8(adapter, REG_TXPKTBUF_DBG, &reg);
+ if (res)
+ continue;
+
+ if (reg)
+ break;
+
+ msleep(1);
+ } while (time_before(jiffies, timeout));
/* data from EEPROM needs to be in LE */
- lo32 = cpu_to_le32(rtw_read32(adapter, REG_PKTBUF_DBG_DATA_L));
- hi32 = cpu_to_le32(rtw_read32(adapter, REG_PKTBUF_DBG_DATA_H));
+ res = rtw_read32(adapter, REG_PKTBUF_DBG_DATA_L, &reg32);
+ if (res)
+ return res;
+
+ lo32 = cpu_to_le32(reg32);
+
+ res = rtw_read32(adapter, REG_PKTBUF_DBG_DATA_H, &reg32);
+ if (res)
+ return res;
+
+ hi32 = cpu_to_le32(reg32);
if (i == 0) {
+ u16 reg;
+
/* Although lenc is only used in a debug statement,
* do not remove it as the rtw_read16() call consumes
* 2 bytes from the EEPROM source.
*/
- rtw_read16(adapter, REG_PKTBUF_DBG_DATA_L);
+ res = rtw_read16(adapter, REG_PKTBUF_DBG_DATA_L, &reg);
+ if (res)
+ return res;
len = le32_to_cpu(lo32) & 0x0000ffff;
@@ -246,21 +273,23 @@ static void efuse_read_phymap_from_txpktbuf(
}
rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL, DISABLE_TRXPKT_BUF_ACCESS);
*size = count;
+
+ return 0;
}
-static s32 iol_read_efuse(struct adapter *padapter, u8 txpktbuf_bndy, u16 offset, u16 size_byte, u8 *logical_map)
+static s32 iol_read_efuse(struct adapter *padapter, u16 size_byte, u8 *logical_map)
{
s32 status = _FAIL;
u8 physical_map[512];
u16 size = 512;
- rtw_write8(padapter, REG_TDECTRL + 1, txpktbuf_bndy);
+ rtw_write8(padapter, REG_TDECTRL + 1, 0);
memset(physical_map, 0xFF, 512);
rtw_write8(padapter, REG_PKT_BUFF_ACCESS_CTRL, TXPKT_BUF_SELECT);
status = iol_execute(padapter, CMD_READ_EFUSE_MAP);
if (status == _SUCCESS)
- efuse_read_phymap_from_txpktbuf(padapter, txpktbuf_bndy, physical_map, &size);
- efuse_phymap_to_logical(physical_map, offset, size_byte, logical_map);
+ efuse_read_phymap_from_txpktbuf(padapter, physical_map, &size);
+ efuse_phymap_to_logical(physical_map, size_byte, logical_map);
return status;
}
@@ -321,25 +350,35 @@ exit:
void rtl8188e_EfusePowerSwitch(struct adapter *pAdapter, u8 PwrState)
{
u16 tmpV16;
+ int res;
if (PwrState) {
rtw_write8(pAdapter, REG_EFUSE_ACCESS, EFUSE_ACCESS_ON);
/* 1.2V Power: From VDDON with Power Cut(0x0000h[15]), defualt valid */
- tmpV16 = rtw_read16(pAdapter, REG_SYS_ISO_CTRL);
+ res = rtw_read16(pAdapter, REG_SYS_ISO_CTRL, &tmpV16);
+ if (res)
+ return;
+
if (!(tmpV16 & PWC_EV12V)) {
tmpV16 |= PWC_EV12V;
rtw_write16(pAdapter, REG_SYS_ISO_CTRL, tmpV16);
}
/* Reset: 0x0000h[28], default valid */
- tmpV16 = rtw_read16(pAdapter, REG_SYS_FUNC_EN);
+ res = rtw_read16(pAdapter, REG_SYS_FUNC_EN, &tmpV16);
+ if (res)
+ return;
+
if (!(tmpV16 & FEN_ELDR)) {
tmpV16 |= FEN_ELDR;
rtw_write16(pAdapter, REG_SYS_FUNC_EN, tmpV16);
}
/* Clock: Gated(0x0008h[5]) 8M(0x0008h[1]) clock from ANA, default valid */
- tmpV16 = rtw_read16(pAdapter, REG_SYS_CLKR);
+ res = rtw_read16(pAdapter, REG_SYS_CLKR, &tmpV16);
+ if (res)
+ return;
+
if ((!(tmpV16 & LOADER_CLK_EN)) || (!(tmpV16 & ANA8M))) {
tmpV16 |= (LOADER_CLK_EN | ANA8M);
rtw_write16(pAdapter, REG_SYS_CLKR, tmpV16);
@@ -470,26 +509,60 @@ exit:
kfree(eFuseWord);
}
-static void ReadEFuseByIC(struct adapter *Adapter, u16 _offset, u16 _size_byte, u8 *pbuf)
+void rtl8188e_ReadEFuse(struct adapter *Adapter, u16 _size_byte, u8 *pbuf)
{
int ret = _FAIL;
if (rtw_IOL_applied(Adapter)) {
rtl8188eu_InitPowerOn(Adapter);
iol_mode_enable(Adapter, 1);
- ret = iol_read_efuse(Adapter, 0, _offset, _size_byte, pbuf);
+ ret = iol_read_efuse(Adapter, _size_byte, pbuf);
iol_mode_enable(Adapter, 0);
if (_SUCCESS == ret)
return;
}
- Hal_EfuseReadEFuse88E(Adapter, _offset, _size_byte, pbuf);
+ Hal_EfuseReadEFuse88E(Adapter, 0, _size_byte, pbuf);
}
-void rtl8188e_ReadEFuse(struct adapter *Adapter, u16 _offset, u16 _size_byte, u8 *pbuf)
+static void dump_chip_info(struct HAL_VERSION chip_vers)
{
- ReadEFuseByIC(Adapter, _offset, _size_byte, pbuf);
+ uint cnt = 0;
+ char buf[128];
+
+ cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8188E_");
+ cnt += sprintf((buf + cnt), "%s_", IS_NORMAL_CHIP(chip_vers) ?
+ "Normal_Chip" : "Test_Chip");
+ cnt += sprintf((buf + cnt), "%s_", IS_CHIP_VENDOR_TSMC(chip_vers) ?
+ "TSMC" : "UMC");
+
+ switch (chip_vers.CUTVersion) {
+ case A_CUT_VERSION:
+ cnt += sprintf((buf + cnt), "A_CUT_");
+ break;
+ case B_CUT_VERSION:
+ cnt += sprintf((buf + cnt), "B_CUT_");
+ break;
+ case C_CUT_VERSION:
+ cnt += sprintf((buf + cnt), "C_CUT_");
+ break;
+ case D_CUT_VERSION:
+ cnt += sprintf((buf + cnt), "D_CUT_");
+ break;
+ case E_CUT_VERSION:
+ cnt += sprintf((buf + cnt), "E_CUT_");
+ break;
+ default:
+ cnt += sprintf((buf + cnt), "UNKNOWN_CUT(%d)_", chip_vers.CUTVersion);
+ break;
+ }
+
+ cnt += sprintf((buf + cnt), "1T1R_");
+
+ cnt += sprintf((buf + cnt), "RomVer(%d)\n", 0);
+
+ pr_info("%s", buf);
}
void rtl8188e_read_chip_version(struct adapter *padapter)
@@ -497,8 +570,12 @@ void rtl8188e_read_chip_version(struct adapter *padapter)
u32 value32;
struct HAL_VERSION ChipVersion;
struct hal_data_8188e *pHalData = &padapter->haldata;
+ int res;
+
+ res = rtw_read32(padapter, REG_SYS_CFG, &value32);
+ if (res)
+ return;
- value32 = rtw_read32(padapter, REG_SYS_CFG);
ChipVersion.ChipType = ((value32 & RTL_ID) ? TEST_CHIP : NORMAL_CHIP);
ChipVersion.VendorType = ((value32 & VENDOR_ID) ? CHIP_VENDOR_UMC : CHIP_VENDOR_TSMC);
@@ -525,10 +602,17 @@ void rtl8188e_SetHalODMVar(struct adapter *Adapter, void *pValue1, bool bSet)
void hal_notch_filter_8188e(struct adapter *adapter, bool enable)
{
+ int res;
+ u8 reg;
+
+ res = rtw_read8(adapter, rOFDM0_RxDSP + 1, &reg);
+ if (res)
+ return;
+
if (enable)
- rtw_write8(adapter, rOFDM0_RxDSP + 1, rtw_read8(adapter, rOFDM0_RxDSP + 1) | BIT(1));
+ rtw_write8(adapter, rOFDM0_RxDSP + 1, reg | BIT(1));
else
- rtw_write8(adapter, rOFDM0_RxDSP + 1, rtw_read8(adapter, rOFDM0_RxDSP + 1) & ~BIT(1));
+ rtw_write8(adapter, rOFDM0_RxDSP + 1, reg & ~BIT(1));
}
/* */
@@ -538,26 +622,24 @@ void hal_notch_filter_8188e(struct adapter *adapter, bool enable)
/* */
static s32 _LLTWrite(struct adapter *padapter, u32 address, u32 data)
{
- s32 status = _SUCCESS;
- s32 count = 0;
+ s32 count;
u32 value = _LLT_INIT_ADDR(address) | _LLT_INIT_DATA(data) | _LLT_OP(_LLT_WRITE_ACCESS);
u16 LLTReg = REG_LLT_INIT;
+ int res;
rtw_write32(padapter, LLTReg, value);
/* polling */
- do {
- value = rtw_read32(padapter, LLTReg);
- if (_LLT_NO_ACTIVE == _LLT_OP_VALUE(value))
- break;
+ for (count = 0; count <= POLLING_LLT_THRESHOLD; count++) {
+ res = rtw_read32(padapter, LLTReg, &value);
+ if (res)
+ continue;
- if (count > POLLING_LLT_THRESHOLD) {
- status = _FAIL;
+ if (_LLT_NO_ACTIVE == _LLT_OP_VALUE(value))
break;
- }
- } while (count++);
+ }
- return status;
+ return count > POLLING_LLT_THRESHOLD ? _FAIL : _SUCCESS;
}
s32 InitLLTTable(struct adapter *padapter, u8 txpktbuf_bndy)
diff --git a/drivers/staging/r8188eu/hal/rtl8188e_phycfg.c b/drivers/staging/r8188eu/hal/rtl8188e_phycfg.c
index 4864dafd887b..dea6d915a1f4 100644
--- a/drivers/staging/r8188eu/hal/rtl8188e_phycfg.c
+++ b/drivers/staging/r8188eu/hal/rtl8188e_phycfg.c
@@ -56,8 +56,12 @@ rtl8188e_PHY_QueryBBReg(
)
{
u32 ReturnValue = 0, OriginalValue, BitShift;
+ int res;
+
+ res = rtw_read32(Adapter, RegAddr, &OriginalValue);
+ if (res)
+ return 0;
- OriginalValue = rtw_read32(Adapter, RegAddr);
BitShift = phy_CalculateBitShift(BitMask);
ReturnValue = (OriginalValue & BitMask) >> BitShift;
return ReturnValue;
@@ -84,9 +88,13 @@ rtl8188e_PHY_QueryBBReg(
void rtl8188e_PHY_SetBBReg(struct adapter *Adapter, u32 RegAddr, u32 BitMask, u32 Data)
{
u32 OriginalValue, BitShift;
+ int res;
if (BitMask != bMaskDWord) { /* if not "double word" write */
- OriginalValue = rtw_read32(Adapter, RegAddr);
+ res = rtw_read32(Adapter, RegAddr, &OriginalValue);
+ if (res)
+ return;
+
BitShift = phy_CalculateBitShift(BitMask);
Data = ((OriginalValue & (~BitMask)) | (Data << BitShift));
}
@@ -484,13 +492,17 @@ PHY_BBConfig8188E(
{
int rtStatus = _SUCCESS;
struct hal_data_8188e *pHalData = &Adapter->haldata;
- u32 RegVal;
+ u16 RegVal;
u8 CrystalCap;
+ int res;
phy_InitBBRFRegisterDefinition(Adapter);
/* Enable BB and RF */
- RegVal = rtw_read16(Adapter, REG_SYS_FUNC_EN);
+ res = rtw_read16(Adapter, REG_SYS_FUNC_EN, &RegVal);
+ if (res)
+ return _FAIL;
+
rtw_write16(Adapter, REG_SYS_FUNC_EN, (u16)(RegVal | BIT(13) | BIT(0) | BIT(1)));
/* 20090923 Joseph: Advised by Steven and Jenyu. Power sequence before init RF. */
@@ -594,6 +606,7 @@ _PHY_SetBWMode92C(
struct hal_data_8188e *pHalData = &Adapter->haldata;
u8 regBwOpMode;
u8 regRRSR_RSC;
+ int res;
if (Adapter->bDriverStopped)
return;
@@ -602,8 +615,13 @@ _PHY_SetBWMode92C(
/* 3<1>Set MAC register */
/* 3 */
- regBwOpMode = rtw_read8(Adapter, REG_BWOPMODE);
- regRRSR_RSC = rtw_read8(Adapter, REG_RRSR + 2);
+ res = rtw_read8(Adapter, REG_BWOPMODE, &regBwOpMode);
+ if (res)
+ return;
+
+ res = rtw_read8(Adapter, REG_RRSR + 2, &regRRSR_RSC);
+ if (res)
+ return;
switch (pHalData->CurrentChannelBW) {
case HT_CHANNEL_WIDTH_20:
diff --git a/drivers/staging/r8188eu/hal/rtl8188eu_recv.c b/drivers/staging/r8188eu/hal/rtl8188eu_recv.c
index 727e1adce1dc..def6d0d6e402 100644
--- a/drivers/staging/r8188eu/hal/rtl8188eu_recv.c
+++ b/drivers/staging/r8188eu/hal/rtl8188eu_recv.c
@@ -32,7 +32,7 @@ int rtl8188eu_init_recv_priv(struct adapter *padapter)
goto exit;
}
- precvpriv->precv_buf = (u8 *)N_BYTE_ALIGMENT((size_t)(precvpriv->pallocated_recv_buf), 4);
+ precvpriv->precv_buf = (u8 *)ALIGN((size_t)(precvpriv->pallocated_recv_buf), 4);
precvbuf = (struct recv_buf *)precvpriv->precv_buf;
diff --git a/drivers/staging/r8188eu/hal/usb_halinit.c b/drivers/staging/r8188eu/hal/usb_halinit.c
index a217272a07f8..ff074d246dab 100644
--- a/drivers/staging/r8188eu/hal/usb_halinit.c
+++ b/drivers/staging/r8188eu/hal/usb_halinit.c
@@ -11,7 +11,7 @@
#include "../include/rtw_iol.h"
#include "../include/usb_ops.h"
#include "../include/usb_osintf.h"
-#include "../include/Hal8188EPwrSeq.h"
+#include "../include/HalPwrSeqCmd.h"
static void _ConfigNormalChipOutEP_8188E(struct adapter *adapt, u8 NumOutPipe)
{
@@ -52,12 +52,14 @@ void rtl8188eu_interface_configure(struct adapter *adapt)
u32 rtl8188eu_InitPowerOn(struct adapter *adapt)
{
u16 value16;
+ int res;
+
/* HW Power on sequence */
struct hal_data_8188e *haldata = &adapt->haldata;
if (haldata->bMacPwrCtrlOn)
return _SUCCESS;
- if (!HalPwrSeqCmdParsing(adapt, Rtl8188E_NIC_PWR_ON_FLOW))
+ if (!HalPwrSeqCmdParsing(adapt, PWR_ON_FLOW))
return _FAIL;
/* Enable MAC DMA/WMAC/SCHEDULE/SEC block */
@@ -65,7 +67,10 @@ u32 rtl8188eu_InitPowerOn(struct adapter *adapt)
rtw_write16(adapt, REG_CR, 0x00); /* suggseted by zhouzhou, by page, 20111230 */
/* Enable MAC DMA/WMAC/SCHEDULE/SEC block */
- value16 = rtw_read16(adapt, REG_CR);
+ res = rtw_read16(adapt, REG_CR, &value16);
+ if (res)
+ return _FAIL;
+
value16 |= (HCI_TXDMA_EN | HCI_RXDMA_EN | TXDMA_EN | RXDMA_EN
| PROTOCOL_EN | SCHEDULE_EN | ENSEC | CALTMR_EN);
/* for SDIO - Set CR bit10 to enable 32k calibration. Suggested by SD1 Gimmy. Added by tynli. 2011.08.31. */
@@ -81,6 +86,7 @@ static void _InitInterrupt(struct adapter *Adapter)
{
u32 imr, imr_ex;
u8 usb_opt;
+ int res;
/* HISR write one to clear */
rtw_write32(Adapter, REG_HISR_88E, 0xFFFFFFFF);
@@ -94,7 +100,9 @@ static void _InitInterrupt(struct adapter *Adapter)
/* REG_USB_SPECIAL_OPTION - BIT(4) */
/* 0; Use interrupt endpoint to upload interrupt pkt */
/* 1; Use bulk endpoint to upload interrupt pkt, */
- usb_opt = rtw_read8(Adapter, REG_USB_SPECIAL_OPTION);
+ res = rtw_read8(Adapter, REG_USB_SPECIAL_OPTION, &usb_opt);
+ if (res)
+ return;
if (adapter_to_dvobj(Adapter)->pusbdev->speed == USB_SPEED_HIGH)
usb_opt = usb_opt | (INT_BULK_SEL);
@@ -163,7 +171,14 @@ static void _InitNormalChipRegPriority(struct adapter *Adapter, u16 beQ,
u16 bkQ, u16 viQ, u16 voQ, u16 mgtQ,
u16 hiQ)
{
- u16 value16 = (rtw_read16(Adapter, REG_TRXDMA_CTRL) & 0x7);
+ u16 value16;
+ int res;
+
+ res = rtw_read16(Adapter, REG_TRXDMA_CTRL, &value16);
+ if (res)
+ return;
+
+ value16 &= 0x7;
value16 |= _TXDMA_BEQ_MAP(beQ) | _TXDMA_BKQ_MAP(bkQ) |
_TXDMA_VIQ_MAP(viQ) | _TXDMA_VOQ_MAP(voQ) |
@@ -282,8 +297,12 @@ static void _InitQueuePriority(struct adapter *Adapter)
static void _InitNetworkType(struct adapter *Adapter)
{
u32 value32;
+ int res;
+
+ res = rtw_read32(Adapter, REG_CR, &value32);
+ if (res)
+ return;
- value32 = rtw_read32(Adapter, REG_CR);
/* TODO: use the other function to set network type */
value32 = (value32 & ~MASK_NETTYPE) | _NETTYPE(NT_LINK_AP);
@@ -323,9 +342,13 @@ static void _InitAdaptiveCtrl(struct adapter *Adapter)
{
u16 value16;
u32 value32;
+ int res;
/* Response Rate Set */
- value32 = rtw_read32(Adapter, REG_RRSR);
+ res = rtw_read32(Adapter, REG_RRSR, &value32);
+ if (res)
+ return;
+
value32 &= ~RATE_BITMAP_ALL;
value32 |= RATE_RRSR_CCK_ONLY_1M;
rtw_write32(Adapter, REG_RRSR, value32);
@@ -363,8 +386,12 @@ static void _InitEDCA(struct adapter *Adapter)
static void _InitRetryFunction(struct adapter *Adapter)
{
u8 value8;
+ int res;
+
+ res = rtw_read8(Adapter, REG_FWHW_TXQ_CTRL, &value8);
+ if (res)
+ return;
- value8 = rtw_read8(Adapter, REG_FWHW_TXQ_CTRL);
value8 |= EN_AMPDU_RTY_NEW;
rtw_write8(Adapter, REG_FWHW_TXQ_CTRL, value8);
@@ -390,11 +417,15 @@ static void _InitRetryFunction(struct adapter *Adapter)
static void usb_AggSettingTxUpdate(struct adapter *Adapter)
{
u32 value32;
+ int res;
if (Adapter->registrypriv.wifi_spec)
return;
- value32 = rtw_read32(Adapter, REG_TDECTRL);
+ res = rtw_read32(Adapter, REG_TDECTRL, &value32);
+ if (res)
+ return;
+
value32 = value32 & ~(BLK_DESC_NUM_MASK << BLK_DESC_NUM_SHIFT);
value32 |= ((USB_TXAGG_DESC_NUM & BLK_DESC_NUM_MASK) << BLK_DESC_NUM_SHIFT);
@@ -423,9 +454,15 @@ usb_AggSettingRxUpdate(
{
u8 valueDMA;
u8 valueUSB;
+ int res;
- valueDMA = rtw_read8(Adapter, REG_TRXDMA_CTRL);
- valueUSB = rtw_read8(Adapter, REG_USB_SPECIAL_OPTION);
+ res = rtw_read8(Adapter, REG_TRXDMA_CTRL, &valueDMA);
+ if (res)
+ return;
+
+ res = rtw_read8(Adapter, REG_USB_SPECIAL_OPTION, &valueUSB);
+ if (res)
+ return;
valueDMA |= RXDMA_AGG_EN;
valueUSB &= ~USB_AGG_EN;
@@ -446,9 +483,11 @@ static void InitUsbAggregationSetting(struct adapter *Adapter)
usb_AggSettingRxUpdate(Adapter);
}
-static void _InitBeaconParameters(struct adapter *Adapter)
+/* FIXME: add error handling in callers */
+static int _InitBeaconParameters(struct adapter *Adapter)
{
struct hal_data_8188e *haldata = &Adapter->haldata;
+ int res;
rtw_write16(Adapter, REG_BCN_CTRL, 0x1010);
@@ -461,9 +500,19 @@ static void _InitBeaconParameters(struct adapter *Adapter)
/* beacause test chip does not contension before sending beacon. by tynli. 2009.11.03 */
rtw_write16(Adapter, REG_BCNTCFG, 0x660F);
- haldata->RegFwHwTxQCtrl = rtw_read8(Adapter, REG_FWHW_TXQ_CTRL + 2);
- haldata->RegReg542 = rtw_read8(Adapter, REG_TBTT_PROHIBIT + 2);
- haldata->RegCR_1 = rtw_read8(Adapter, REG_CR + 1);
+ res = rtw_read8(Adapter, REG_FWHW_TXQ_CTRL + 2, &haldata->RegFwHwTxQCtrl);
+ if (res)
+ return res;
+
+ res = rtw_read8(Adapter, REG_TBTT_PROHIBIT + 2, &haldata->RegReg542);
+ if (res)
+ return res;
+
+ res = rtw_read8(Adapter, REG_CR + 1, &haldata->RegCR_1);
+ if (res)
+ return res;
+
+ return 0;
}
static void _BeaconFunctionEnable(struct adapter *Adapter,
@@ -484,11 +533,17 @@ static void _BBTurnOnBlock(struct adapter *Adapter)
static void _InitAntenna_Selection(struct adapter *Adapter)
{
struct hal_data_8188e *haldata = &Adapter->haldata;
+ int res;
+ u32 reg;
if (haldata->AntDivCfg == 0)
return;
- rtw_write32(Adapter, REG_LEDCFG0, rtw_read32(Adapter, REG_LEDCFG0) | BIT(23));
+ res = rtw_read32(Adapter, REG_LEDCFG0, &reg);
+ if (res)
+ return;
+
+ rtw_write32(Adapter, REG_LEDCFG0, reg | BIT(23));
rtl8188e_PHY_SetBBReg(Adapter, rFPGA0_XAB_RFParameter, BIT(13), 0x01);
if (rtl8188e_PHY_QueryBBReg(Adapter, rFPGA0_XA_RFInterfaceOE, 0x300) == Antenna_A)
@@ -514,9 +569,11 @@ u32 rtl8188eu_hal_init(struct adapter *Adapter)
u16 value16;
u8 txpktbuf_bndy;
u32 status = _SUCCESS;
+ int res;
struct hal_data_8188e *haldata = &Adapter->haldata;
struct pwrctrl_priv *pwrctrlpriv = &Adapter->pwrctrlpriv;
struct registry_priv *pregistrypriv = &Adapter->registrypriv;
+ u32 reg;
if (Adapter->pwrctrlpriv.bkeepfwalive) {
if (haldata->odmpriv.RFCalibrateInfo.bIQKInitialized) {
@@ -614,13 +671,19 @@ u32 rtl8188eu_hal_init(struct adapter *Adapter)
/* Hw bug which Hw initials RxFF boundary size to a value which is larger than the real Rx buffer size in 88E. */
/* */
/* Enable MACTXEN/MACRXEN block */
- value16 = rtw_read16(Adapter, REG_CR);
+ res = rtw_read16(Adapter, REG_CR, &value16);
+ if (res)
+ return _FAIL;
+
value16 |= (MACTXEN | MACRXEN);
rtw_write8(Adapter, REG_CR, value16);
/* Enable TX Report */
/* Enable Tx Report Timer */
- value8 = rtw_read8(Adapter, REG_TX_RPT_CTRL);
+ res = rtw_read8(Adapter, REG_TX_RPT_CTRL, &value8);
+ if (res)
+ return _FAIL;
+
rtw_write8(Adapter, REG_TX_RPT_CTRL, (value8 | BIT(1) | BIT(0)));
/* Set MAX RPT MACID */
rtw_write8(Adapter, REG_TX_RPT_CTRL + 1, 2);/* FOR sta mode ,0: bc/mc ,1:AP */
@@ -684,7 +747,11 @@ u32 rtl8188eu_hal_init(struct adapter *Adapter)
rtw_write16(Adapter, REG_TX_RPT_TIME, 0x3DF0);
/* enable tx DMA to drop the redundate data of packet */
- rtw_write16(Adapter, REG_TXDMA_OFFSET_CHK, (rtw_read16(Adapter, REG_TXDMA_OFFSET_CHK) | DROP_DATA_EN));
+ res = rtw_read16(Adapter, REG_TXDMA_OFFSET_CHK, &value16);
+ if (res)
+ return _FAIL;
+
+ rtw_write16(Adapter, REG_TXDMA_OFFSET_CHK, (value16 | DROP_DATA_EN));
/* 2010/08/26 MH Merge from 8192CE. */
if (pwrctrlpriv->rf_pwrstate == rf_on) {
@@ -704,7 +771,11 @@ u32 rtl8188eu_hal_init(struct adapter *Adapter)
rtw_write8(Adapter, REG_USB_HRPWM, 0);
/* ack for xmit mgmt frames. */
- rtw_write32(Adapter, REG_FWHW_TXQ_CTRL, rtw_read32(Adapter, REG_FWHW_TXQ_CTRL) | BIT(12));
+ res = rtw_read32(Adapter, REG_FWHW_TXQ_CTRL, &reg);
+ if (res)
+ return _FAIL;
+
+ rtw_write32(Adapter, REG_FWHW_TXQ_CTRL, reg | BIT(12));
exit:
return status;
@@ -714,23 +785,33 @@ static void CardDisableRTL8188EU(struct adapter *Adapter)
{
u8 val8;
struct hal_data_8188e *haldata = &Adapter->haldata;
+ int res;
/* Stop Tx Report Timer. 0x4EC[Bit1]=b'0 */
- val8 = rtw_read8(Adapter, REG_TX_RPT_CTRL);
+ res = rtw_read8(Adapter, REG_TX_RPT_CTRL, &val8);
+ if (res)
+ return;
+
rtw_write8(Adapter, REG_TX_RPT_CTRL, val8 & (~BIT(1)));
/* stop rx */
rtw_write8(Adapter, REG_CR, 0x0);
/* Run LPS WL RFOFF flow */
- HalPwrSeqCmdParsing(Adapter, Rtl8188E_NIC_LPS_ENTER_FLOW);
+ HalPwrSeqCmdParsing(Adapter, LPS_ENTER_FLOW);
/* 2. 0x1F[7:0] = 0 turn off RF */
- val8 = rtw_read8(Adapter, REG_MCUFWDL);
+ res = rtw_read8(Adapter, REG_MCUFWDL, &val8);
+ if (res)
+ return;
+
if ((val8 & RAM_DL_SEL) && Adapter->bFWReady) { /* 8051 RAM code */
/* Reset MCU 0x2[10]=0. */
- val8 = rtw_read8(Adapter, REG_SYS_FUNC_EN + 1);
+ res = rtw_read8(Adapter, REG_SYS_FUNC_EN + 1, &val8);
+ if (res)
+ return;
+
val8 &= ~BIT(2); /* 0x2[10], FEN_CPUEN */
rtw_write8(Adapter, REG_SYS_FUNC_EN + 1, val8);
}
@@ -740,26 +821,45 @@ static void CardDisableRTL8188EU(struct adapter *Adapter)
/* YJ,add,111212 */
/* Disable 32k */
- val8 = rtw_read8(Adapter, REG_32K_CTRL);
+ res = rtw_read8(Adapter, REG_32K_CTRL, &val8);
+ if (res)
+ return;
+
rtw_write8(Adapter, REG_32K_CTRL, val8 & (~BIT(0)));
/* Card disable power action flow */
- HalPwrSeqCmdParsing(Adapter, Rtl8188E_NIC_DISABLE_FLOW);
+ HalPwrSeqCmdParsing(Adapter, DISABLE_FLOW);
/* Reset MCU IO Wrapper */
- val8 = rtw_read8(Adapter, REG_RSV_CTRL + 1);
+ res = rtw_read8(Adapter, REG_RSV_CTRL + 1, &val8);
+ if (res)
+ return;
+
rtw_write8(Adapter, REG_RSV_CTRL + 1, (val8 & (~BIT(3))));
- val8 = rtw_read8(Adapter, REG_RSV_CTRL + 1);
+
+ res = rtw_read8(Adapter, REG_RSV_CTRL + 1, &val8);
+ if (res)
+ return;
+
rtw_write8(Adapter, REG_RSV_CTRL + 1, val8 | BIT(3));
/* YJ,test add, 111207. For Power Consumption. */
- val8 = rtw_read8(Adapter, GPIO_IN);
+ res = rtw_read8(Adapter, GPIO_IN, &val8);
+ if (res)
+ return;
+
rtw_write8(Adapter, GPIO_OUT, val8);
rtw_write8(Adapter, GPIO_IO_SEL, 0xFF);/* Reg0x46 */
- val8 = rtw_read8(Adapter, REG_GPIO_IO_SEL);
+ res = rtw_read8(Adapter, REG_GPIO_IO_SEL, &val8);
+ if (res)
+ return;
+
rtw_write8(Adapter, REG_GPIO_IO_SEL, (val8 << 4));
- val8 = rtw_read8(Adapter, REG_GPIO_IO_SEL + 1);
+ res = rtw_read8(Adapter, REG_GPIO_IO_SEL + 1, &val8);
+ if (res)
+ return;
+
rtw_write8(Adapter, REG_GPIO_IO_SEL + 1, val8 | 0x0F);/* Reg0x43 */
rtw_write32(Adapter, REG_BB_PAD_CTRL, 0x00080808);/* set LNA ,TRSW,EX_PA Pin to output mode */
haldata->bMacPwrCtrlOn = false;
@@ -812,13 +912,10 @@ exit:
static void Hal_EfuseParseMACAddr_8188EU(struct adapter *adapt, u8 *hwinfo, bool AutoLoadFail)
{
- u16 i;
- u8 sMacAddr[6] = {0x00, 0xE0, 0x4C, 0x81, 0x88, 0x02};
struct eeprom_priv *eeprom = &adapt->eeprompriv;
if (AutoLoadFail) {
- for (i = 0; i < 6; i++)
- eeprom->mac_addr[i] = sMacAddr[i];
+ eth_random_addr(eeprom->mac_addr);
} else {
/* Read Permanent MAC address */
memcpy(eeprom->mac_addr, &hwinfo[EEPROM_MAC_ADDR_88EU], ETH_ALEN);
@@ -829,285 +926,41 @@ void ReadAdapterInfo8188EU(struct adapter *Adapter)
{
struct eeprom_priv *eeprom = &Adapter->eeprompriv;
struct led_priv *ledpriv = &Adapter->ledpriv;
+ u8 *efuse_buf;
u8 eeValue;
+ int res;
/* check system boot selection */
- eeValue = rtw_read8(Adapter, REG_9346CR);
- eeprom->EepromOrEfuse = (eeValue & BOOT_FROM_EEPROM);
- eeprom->bautoload_fail_flag = !(eeValue & EEPROM_EN);
-
- if (!is_boot_from_eeprom(Adapter))
- EFUSE_ShadowMapUpdate(Adapter);
-
- /* parse the eeprom/efuse content */
- Hal_EfuseParseIDCode88E(Adapter, eeprom->efuse_eeprom_data);
- Hal_EfuseParseMACAddr_8188EU(Adapter, eeprom->efuse_eeprom_data, eeprom->bautoload_fail_flag);
-
- Hal_ReadPowerSavingMode88E(Adapter, eeprom->efuse_eeprom_data, eeprom->bautoload_fail_flag);
- Hal_ReadTxPowerInfo88E(Adapter, eeprom->efuse_eeprom_data, eeprom->bautoload_fail_flag);
- rtl8188e_EfuseParseChnlPlan(Adapter, eeprom->efuse_eeprom_data, eeprom->bautoload_fail_flag);
- Hal_EfuseParseXtal_8188E(Adapter, eeprom->efuse_eeprom_data, eeprom->bautoload_fail_flag);
- Hal_ReadAntennaDiversity88E(Adapter, eeprom->efuse_eeprom_data, eeprom->bautoload_fail_flag);
- Hal_ReadThermalMeter_88E(Adapter, eeprom->efuse_eeprom_data, eeprom->bautoload_fail_flag);
-
- ledpriv->bRegUseLed = true;
-}
-
-static void ResumeTxBeacon(struct adapter *adapt)
-{
- struct hal_data_8188e *haldata = &adapt->haldata;
-
- /* 2010.03.01. Marked by tynli. No need to call workitem beacause we record the value */
- /* which should be read from register to a global variable. */
-
- rtw_write8(adapt, REG_FWHW_TXQ_CTRL + 2, (haldata->RegFwHwTxQCtrl) | BIT(6));
- haldata->RegFwHwTxQCtrl |= BIT(6);
- rtw_write8(adapt, REG_TBTT_PROHIBIT + 1, 0xff);
- haldata->RegReg542 |= BIT(0);
- rtw_write8(adapt, REG_TBTT_PROHIBIT + 2, haldata->RegReg542);
-}
-
-static void StopTxBeacon(struct adapter *adapt)
-{
- struct hal_data_8188e *haldata = &adapt->haldata;
-
- /* 2010.03.01. Marked by tynli. No need to call workitem beacause we record the value */
- /* which should be read from register to a global variable. */
-
- rtw_write8(adapt, REG_FWHW_TXQ_CTRL + 2, (haldata->RegFwHwTxQCtrl) & (~BIT(6)));
- haldata->RegFwHwTxQCtrl &= (~BIT(6));
- rtw_write8(adapt, REG_TBTT_PROHIBIT + 1, 0x64);
- haldata->RegReg542 &= ~(BIT(0));
- rtw_write8(adapt, REG_TBTT_PROHIBIT + 2, haldata->RegReg542);
-
- /* todo: CheckFwRsvdPageContent(Adapter); 2010.06.23. Added by tynli. */
-}
-
-static void hw_var_set_opmode(struct adapter *Adapter, u8 *val)
-{
- u8 val8;
- u8 mode = *((u8 *)val);
-
- /* disable Port0 TSF update */
- rtw_write8(Adapter, REG_BCN_CTRL, rtw_read8(Adapter, REG_BCN_CTRL) | BIT(4));
-
- /* set net_type */
- val8 = rtw_read8(Adapter, MSR) & 0x0c;
- val8 |= mode;
- rtw_write8(Adapter, MSR, val8);
-
- if ((mode == _HW_STATE_STATION_) || (mode == _HW_STATE_NOLINK_)) {
- StopTxBeacon(Adapter);
-
- rtw_write8(Adapter, REG_BCN_CTRL, 0x19);/* disable atim wnd */
- } else if (mode == _HW_STATE_ADHOC_) {
- ResumeTxBeacon(Adapter);
- rtw_write8(Adapter, REG_BCN_CTRL, 0x1a);
- } else if (mode == _HW_STATE_AP_) {
- ResumeTxBeacon(Adapter);
-
- rtw_write8(Adapter, REG_BCN_CTRL, 0x12);
-
- /* Set RCR */
- rtw_write32(Adapter, REG_RCR, 0x7000208e);/* CBSSID_DATA must set to 0,reject ICV_ERR packet */
- /* enable to rx data frame */
- rtw_write16(Adapter, REG_RXFLTMAP2, 0xFFFF);
- /* enable to rx ps-poll */
- rtw_write16(Adapter, REG_RXFLTMAP1, 0x0400);
-
- /* Beacon Control related register for first time */
- rtw_write8(Adapter, REG_BCNDMATIM, 0x02); /* 2ms */
-
- rtw_write8(Adapter, REG_ATIMWND, 0x0a); /* 10ms */
- rtw_write16(Adapter, REG_BCNTCFG, 0x00);
- rtw_write16(Adapter, REG_TBTT_PROHIBIT, 0xff04);
- rtw_write16(Adapter, REG_TSFTR_SYN_OFFSET, 0x7fff);/* +32767 (~32ms) */
-
- /* reset TSF */
- rtw_write8(Adapter, REG_DUAL_TSF_RST, BIT(0));
+ res = rtw_read8(Adapter, REG_9346CR, &eeValue);
+ if (res)
+ return;
- /* BIT(3) - If set 0, hw will clr bcnq when tx becon ok/fail or port 0 */
- rtw_write8(Adapter, REG_MBID_NUM, rtw_read8(Adapter, REG_MBID_NUM) | BIT(3) | BIT(4));
+ eeprom->bautoload_fail_flag = !(eeValue & EEPROM_EN);
- /* enable BCN0 Function for if1 */
- /* don't enable update TSF0 for if1 (due to TSF update when beacon/probe rsp are received) */
- rtw_write8(Adapter, REG_BCN_CTRL, (DIS_TSF_UDT0_NORMAL_CHIP | EN_BCN_FUNCTION | BIT(1)));
+ efuse_buf = kmalloc(EFUSE_MAP_LEN_88E, GFP_KERNEL);
+ if (!efuse_buf)
+ return;
+ memset(efuse_buf, 0xFF, EFUSE_MAP_LEN_88E);
- /* dis BCN1 ATIM WND if if2 is station */
- rtw_write8(Adapter, REG_BCN_CTRL_1, rtw_read8(Adapter, REG_BCN_CTRL_1) | BIT(0));
+ if (!(eeValue & BOOT_FROM_EEPROM) && !eeprom->bautoload_fail_flag) {
+ rtl8188e_EfusePowerSwitch(Adapter, true);
+ rtl8188e_ReadEFuse(Adapter, EFUSE_MAP_LEN_88E, efuse_buf);
+ rtl8188e_EfusePowerSwitch(Adapter, false);
}
-}
-
-void SetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val)
-{
- struct hal_data_8188e *haldata = &Adapter->haldata;
- struct dm_priv *pdmpriv = &haldata->dmpriv;
- struct odm_dm_struct *podmpriv = &haldata->odmpriv;
-
- switch (variable) {
- case HW_VAR_SET_OPMODE:
- hw_var_set_opmode(Adapter, val);
- break;
- case HW_VAR_BASIC_RATE:
- {
- u16 BrateCfg = 0;
- u8 RateIndex = 0;
-
- /* 2007.01.16, by Emily */
- /* Select RRSR (in Legacy-OFDM and CCK) */
- /* For 8190, we select only 24M, 12M, 6M, 11M, 5.5M, 2M, and 1M from the Basic rate. */
- /* We do not use other rates. */
- HalSetBrateCfg(Adapter, val, &BrateCfg);
-
- /* 2011.03.30 add by Luke Lee */
- /* CCK 2M ACK should be disabled for some BCM and Atheros AP IOT */
- /* because CCK 2M has poor TXEVM */
- /* CCK 5.5M & 11M ACK should be enabled for better performance */
-
- BrateCfg = (BrateCfg | 0xd) & 0x15d;
-
- BrateCfg |= 0x01; /* default enable 1M ACK rate */
- /* Set RRSR rate table. */
- rtw_write8(Adapter, REG_RRSR, BrateCfg & 0xff);
- rtw_write8(Adapter, REG_RRSR + 1, (BrateCfg >> 8) & 0xff);
- rtw_write8(Adapter, REG_RRSR + 2, rtw_read8(Adapter, REG_RRSR + 2) & 0xf0);
-
- /* Set RTS initial rate */
- while (BrateCfg > 0x1) {
- BrateCfg = (BrateCfg >> 1);
- RateIndex++;
- }
- /* Ziv - Check */
- rtw_write8(Adapter, REG_INIRTS_RATE_SEL, RateIndex);
- }
- break;
- case HW_VAR_CORRECT_TSF:
- {
- u64 tsf;
- struct mlme_ext_priv *pmlmeext = &Adapter->mlmeextpriv;
- struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
-
- tsf = pmlmeext->TSFValue - do_div(pmlmeext->TSFValue,
- pmlmeinfo->bcn_interval * 1024) - 1024; /* us */
- if (((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE) || ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE))
- StopTxBeacon(Adapter);
-
- /* disable related TSF function */
- rtw_write8(Adapter, REG_BCN_CTRL, rtw_read8(Adapter, REG_BCN_CTRL) & (~BIT(3)));
-
- rtw_write32(Adapter, REG_TSFTR, tsf);
- rtw_write32(Adapter, REG_TSFTR + 4, tsf >> 32);
-
- /* enable related TSF function */
- rtw_write8(Adapter, REG_BCN_CTRL, rtw_read8(Adapter, REG_BCN_CTRL) | BIT(3));
+ /* parse the eeprom/efuse content */
+ Hal_EfuseParseIDCode88E(Adapter, efuse_buf);
+ Hal_EfuseParseMACAddr_8188EU(Adapter, efuse_buf, eeprom->bautoload_fail_flag);
- if (((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE) || ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE))
- ResumeTxBeacon(Adapter);
- }
- break;
- case HW_VAR_MLME_SITESURVEY:
- if (*((u8 *)val)) { /* under sitesurvey */
- /* config RCR to receive different BSSID & not to receive data frame */
- u32 v = rtw_read32(Adapter, REG_RCR);
- v &= ~(RCR_CBSSID_BCN);
- rtw_write32(Adapter, REG_RCR, v);
- /* reject all data frame */
- rtw_write16(Adapter, REG_RXFLTMAP2, 0x00);
-
- /* disable update TSF */
- rtw_write8(Adapter, REG_BCN_CTRL, rtw_read8(Adapter, REG_BCN_CTRL) | BIT(4));
- } else { /* sitesurvey done */
- struct mlme_ext_priv *pmlmeext = &Adapter->mlmeextpriv;
- struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
-
- if ((is_client_associated_to_ap(Adapter)) ||
- ((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE)) {
- /* enable to rx data frame */
- rtw_write16(Adapter, REG_RXFLTMAP2, 0xFFFF);
-
- /* enable update TSF */
- rtw_write8(Adapter, REG_BCN_CTRL, rtw_read8(Adapter, REG_BCN_CTRL) & (~BIT(4)));
- } else if ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) {
- rtw_write16(Adapter, REG_RXFLTMAP2, 0xFFFF);
- /* enable update TSF */
- rtw_write8(Adapter, REG_BCN_CTRL, rtw_read8(Adapter, REG_BCN_CTRL) & (~BIT(4)));
- }
- rtw_write32(Adapter, REG_RCR, rtw_read32(Adapter, REG_RCR) | RCR_CBSSID_BCN);
- }
- break;
- case HW_VAR_SLOT_TIME:
- {
- u8 u1bAIFS, aSifsTime;
- struct mlme_ext_priv *pmlmeext = &Adapter->mlmeextpriv;
- struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
-
- rtw_write8(Adapter, REG_SLOT, val[0]);
-
- if (pmlmeinfo->WMM_enable == 0) {
- if (pmlmeext->cur_wireless_mode == WIRELESS_11B)
- aSifsTime = 10;
- else
- aSifsTime = 16;
-
- u1bAIFS = aSifsTime + (2 * pmlmeinfo->slotTime);
-
- /* <Roger_EXP> Temporary removed, 2008.06.20. */
- rtw_write8(Adapter, REG_EDCA_VO_PARAM, u1bAIFS);
- rtw_write8(Adapter, REG_EDCA_VI_PARAM, u1bAIFS);
- rtw_write8(Adapter, REG_EDCA_BE_PARAM, u1bAIFS);
- rtw_write8(Adapter, REG_EDCA_BK_PARAM, u1bAIFS);
- }
- }
- break;
- case HW_VAR_DM_FLAG:
- podmpriv->SupportAbility = *((u8 *)val);
- break;
- case HW_VAR_DM_FUNC_OP:
- if (val[0])
- podmpriv->BK_SupportAbility = podmpriv->SupportAbility;
- else
- podmpriv->SupportAbility = podmpriv->BK_SupportAbility;
- break;
- case HW_VAR_DM_FUNC_RESET:
- podmpriv->SupportAbility = pdmpriv->InitODMFlag;
- break;
- case HW_VAR_DM_FUNC_CLR:
- podmpriv->SupportAbility = 0;
- break;
- case HW_VAR_AMPDU_FACTOR:
- {
- u8 RegToSet_Normal[4] = {0x41, 0xa8, 0x72, 0xb9};
- u8 FactorToSet;
- u8 *pRegToSet;
- u8 index = 0;
-
- pRegToSet = RegToSet_Normal; /* 0xb972a841; */
- FactorToSet = *((u8 *)val);
- if (FactorToSet <= 3) {
- FactorToSet = (1 << (FactorToSet + 2));
- if (FactorToSet > 0xf)
- FactorToSet = 0xf;
-
- for (index = 0; index < 4; index++) {
- if ((pRegToSet[index] & 0xf0) > (FactorToSet << 4))
- pRegToSet[index] = (pRegToSet[index] & 0x0f) | (FactorToSet << 4);
-
- if ((pRegToSet[index] & 0x0f) > FactorToSet)
- pRegToSet[index] = (pRegToSet[index] & 0xf0) | (FactorToSet);
-
- rtw_write8(Adapter, (REG_AGGLEN_LMT + index), pRegToSet[index]);
- }
- }
- }
- break;
- case HW_VAR_H2C_MEDIA_STATUS_RPT:
- rtl8188e_set_FwMediaStatus_cmd(Adapter, (*(__le16 *)val));
- break;
- default:
- break;
- }
+ Hal_ReadPowerSavingMode88E(Adapter, efuse_buf, eeprom->bautoload_fail_flag);
+ Hal_ReadTxPowerInfo88E(Adapter, efuse_buf, eeprom->bautoload_fail_flag);
+ rtl8188e_EfuseParseChnlPlan(Adapter, efuse_buf, eeprom->bautoload_fail_flag);
+ Hal_EfuseParseXtal_8188E(Adapter, efuse_buf, eeprom->bautoload_fail_flag);
+ Hal_ReadAntennaDiversity88E(Adapter, efuse_buf, eeprom->bautoload_fail_flag);
+ Hal_ReadThermalMeter_88E(Adapter, efuse_buf, eeprom->bautoload_fail_flag);
+ ledpriv->bRegUseLed = true;
+ kfree(efuse_buf);
}
void UpdateHalRAMask8188EUsb(struct adapter *adapt, u32 mac_id, u8 rssi_level)
@@ -1190,6 +1043,8 @@ void SetBeaconRelatedRegisters8188EUsb(struct adapter *adapt)
struct mlme_ext_priv *pmlmeext = &adapt->mlmeextpriv;
struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
u32 bcn_ctrl_reg = REG_BCN_CTRL;
+ int res;
+ u8 reg;
/* reset TSF, enable update TSF, correcting TSF On Beacon */
/* BCN interval */
@@ -1200,7 +1055,10 @@ void SetBeaconRelatedRegisters8188EUsb(struct adapter *adapt)
rtw_write8(adapt, REG_SLOT, 0x09);
- value32 = rtw_read32(adapt, REG_TCR);
+ res = rtw_read32(adapt, REG_TCR, &value32);
+ if (res)
+ return;
+
value32 &= ~TSFRST;
rtw_write32(adapt, REG_TCR, value32);
@@ -1213,9 +1071,13 @@ void SetBeaconRelatedRegisters8188EUsb(struct adapter *adapt)
_BeaconFunctionEnable(adapt, true, true);
- ResumeTxBeacon(adapt);
+ rtw_resume_tx_beacon(adapt);
+
+ res = rtw_read8(adapt, bcn_ctrl_reg, &reg);
+ if (res)
+ return;
- rtw_write8(adapt, bcn_ctrl_reg, rtw_read8(adapt, bcn_ctrl_reg) | BIT(1));
+ rtw_write8(adapt, bcn_ctrl_reg, reg | BIT(1));
}
void rtl8188eu_init_default_value(struct adapter *adapt)
diff --git a/drivers/staging/r8188eu/hal/usb_ops_linux.c b/drivers/staging/r8188eu/hal/usb_ops_linux.c
index d5e674542a78..c1a4d023f627 100644
--- a/drivers/staging/r8188eu/hal/usb_ops_linux.c
+++ b/drivers/staging/r8188eu/hal/usb_ops_linux.c
@@ -94,40 +94,47 @@ static int usb_write(struct intf_hdl *intf, u16 value, void *data, u8 size)
return status;
}
-u8 rtw_read8(struct adapter *adapter, u32 addr)
+int __must_check rtw_read8(struct adapter *adapter, u32 addr, u8 *data)
{
struct io_priv *io_priv = &adapter->iopriv;
struct intf_hdl *intf = &io_priv->intf;
u16 value = addr & 0xffff;
- u8 data;
- usb_read(intf, value, &data, 1);
-
- return data;
+ return usb_read(intf, value, data, 1);
}
-u16 rtw_read16(struct adapter *adapter, u32 addr)
+int __must_check rtw_read16(struct adapter *adapter, u32 addr, u16 *data)
{
struct io_priv *io_priv = &adapter->iopriv;
struct intf_hdl *intf = &io_priv->intf;
u16 value = addr & 0xffff;
- __le16 data;
+ __le16 le_data;
+ int res;
+
+ res = usb_read(intf, value, &le_data, 2);
+ if (res)
+ return res;
- usb_read(intf, value, &data, 2);
+ *data = le16_to_cpu(le_data);
- return le16_to_cpu(data);
+ return 0;
}
-u32 rtw_read32(struct adapter *adapter, u32 addr)
+int __must_check rtw_read32(struct adapter *adapter, u32 addr, u32 *data)
{
struct io_priv *io_priv = &adapter->iopriv;
struct intf_hdl *intf = &io_priv->intf;
u16 value = addr & 0xffff;
- __le32 data;
+ __le32 le_data;
+ int res;
+
+ res = usb_read(intf, value, &le_data, 4);
+ if (res)
+ return res;
- usb_read(intf, value, &data, 4);
+ *data = le32_to_cpu(le_data);
- return le32_to_cpu(data);
+ return 0;
}
int rtw_write8(struct adapter *adapter, u32 addr, u8 val)
diff --git a/drivers/staging/r8188eu/include/Hal8188EPwrSeq.h b/drivers/staging/r8188eu/include/Hal8188EPwrSeq.h
deleted file mode 100644
index e4c5b5d23cb4..000000000000
--- a/drivers/staging/r8188eu/include/Hal8188EPwrSeq.h
+++ /dev/null
@@ -1,13 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
-/* Copyright(c) 2007 - 2011 Realtek Corporation. */
-
-#ifndef __HAL8188EPWRSEQ_H__
-#define __HAL8188EPWRSEQ_H__
-
-#include "HalPwrSeqCmd.h"
-
-extern struct wl_pwr_cfg rtl8188E_power_on_flow[];
-extern struct wl_pwr_cfg rtl8188E_card_disable_flow[];
-extern struct wl_pwr_cfg rtl8188E_enter_lps_flow[];
-
-#endif /* __HAL8188EPWRSEQ_H__ */
diff --git a/drivers/staging/r8188eu/include/Hal8188ERateAdaptive.h b/drivers/staging/r8188eu/include/Hal8188ERateAdaptive.h
index 20d73ca781e8..c571ad9478ea 100644
--- a/drivers/staging/r8188eu/include/Hal8188ERateAdaptive.h
+++ b/drivers/staging/r8188eu/include/Hal8188ERateAdaptive.h
@@ -22,19 +22,6 @@
le32_to_cpu((*(__le32 *)(__rxstatusdesc + 16))
#define GET_TX_RPT2_DESC_MACID_VALID_2_88E(__rxstatusdesc) \
le32_to_cpu((*(__le32 *)(__rxstatusdesc + 20))
-
-#define GET_TX_REPORT_TYPE1_RERTY_0(__paddr) \
- le16_get_bits(*(__le16 *)__paddr, GENMASK(15, 0))
-#define GET_TX_REPORT_TYPE1_RERTY_1(__paddr) \
- LE_BITS_TO_1BYTE(__paddr + 2, 0, 8)
-#define GET_TX_REPORT_TYPE1_RERTY_2(__paddr) \
- LE_BITS_TO_1BYTE(__paddr + 3, 0, 8)
-#define GET_TX_REPORT_TYPE1_RERTY_3(__paddr) \
- LE_BITS_TO_1BYTE(__paddr + 4, 0, 8)
-#define GET_TX_REPORT_TYPE1_RERTY_4(__paddr) \
- LE_BITS_TO_1BYTE(__paddr + 5, 0, 8)
-#define GET_TX_REPORT_TYPE1_DROP_0(__paddr) \
- LE_BITS_TO_1BYTE(__paddr + 6, 0, 8)
/* End rate adaptive define */
int ODM_RAInfo_Init_all(struct odm_dm_struct *dm_odm);
diff --git a/drivers/staging/r8188eu/include/HalPwrSeqCmd.h b/drivers/staging/r8188eu/include/HalPwrSeqCmd.h
index 49c02cce569e..0886300d26bf 100644
--- a/drivers/staging/r8188eu/include/HalPwrSeqCmd.h
+++ b/drivers/staging/r8188eu/include/HalPwrSeqCmd.h
@@ -6,54 +6,13 @@
#include "drv_types.h"
-/*---------------------------------------------*/
-/* 3 The value of cmd: 4 bits */
-/*---------------------------------------------*/
-
-#define PWR_CMD_WRITE 0x01
- /* offset: the read register offset */
- /* msk: the mask of the write bits */
- /* value: write value */
- /* note: driver shall implement this cmd by read & msk after write */
-
-#define PWR_CMD_POLLING 0x02
- /* offset: the read register offset */
- /* msk: the mask of the polled value */
- /* value: the value to be polled, masked by the msd field. */
- /* note: driver shall implement this cmd by */
- /* do{ */
- /* if ( (Read(offset) & msk) == (value & msk) ) */
- /* break; */
- /* } while (not timeout); */
-
-#define PWR_CMD_DELAY 0x03
- /* offset: the value to delay */
- /* msk: N/A */
- /* value: the unit of delay, 0: us, 1: ms */
-
-#define PWR_CMD_END 0x04
- /* offset: N/A */
- /* msk: N/A */
- /* value: N/A */
-
-enum pwrseq_cmd_delat_unit {
- PWRSEQ_DELAY_US,
- PWRSEQ_DELAY_MS,
-};
-
-struct wl_pwr_cfg {
- u16 offset;
- u8 cmd:4;
- u8 msk;
- u8 value;
+enum r8188eu_pwr_seq {
+ PWR_ON_FLOW,
+ DISABLE_FLOW,
+ LPS_ENTER_FLOW,
};
-#define GET_PWR_CFG_OFFSET(__PWR_CMD) __PWR_CMD.offset
-#define GET_PWR_CFG_CMD(__PWR_CMD) __PWR_CMD.cmd
-#define GET_PWR_CFG_MASK(__PWR_CMD) __PWR_CMD.msk
-#define GET_PWR_CFG_VALUE(__PWR_CMD) __PWR_CMD.value
-
/* Prototype of protected function. */
-u8 HalPwrSeqCmdParsing(struct adapter *padapter, struct wl_pwr_cfg PwrCfgCmd[]);
+u8 HalPwrSeqCmdParsing(struct adapter *padapter, enum r8188eu_pwr_seq seq);
#endif
diff --git a/drivers/staging/r8188eu/include/basic_types.h b/drivers/staging/r8188eu/include/basic_types.h
deleted file mode 100644
index ffb21170e898..000000000000
--- a/drivers/staging/r8188eu/include/basic_types.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
-/* Copyright(c) 2007 - 2011 Realtek Corporation. */
-
-#ifndef __BASIC_TYPES_H__
-#define __BASIC_TYPES_H__
-
-#include <linux/types.h>
-#define NDIS_OID uint
-
-typedef void (*proc_t)(void *);
-
-#define FIELD_OFFSET(s, field) ((ssize_t)&((s *)(0))->field)
-
-/* port from fw */
-/* TODO: Macros Below are Sync from SD7-Driver. It is necessary
- * to check correctness */
-
-/*
- * Call endian free function when
- * 1. Read/write packet content.
- * 2. Before write integer to IO.
- * 3. After read integer from IO.
-*/
-
-/* Convert little data endian to host ordering */
-#define EF1BYTE(_val) \
- ((u8)(_val))
-
-/* Create a bit mask */
-#define BIT_LEN_MASK_8(__bitlen) \
- (0xFF >> (8 - (__bitlen)))
-
-/*Description:
- * Return 4-byte value in host byte ordering from
- * 4-byte pointer in little-endian system.
- */
-#define LE_P1BYTE_TO_HOST_1BYTE(__pstart) \
- (EF1BYTE(*((u8 *)(__pstart))))
-
-/*Description:
-Translate subfield (continuous bits in little-endian) of 4-byte
-value to host byte ordering.*/
-#define LE_BITS_TO_1BYTE(__pstart, __bitoffset, __bitlen) \
- ( \
- (LE_P1BYTE_TO_HOST_1BYTE(__pstart) >> (__bitoffset)) & \
- BIT_LEN_MASK_8(__bitlen) \
- )
-
-#define N_BYTE_ALIGMENT(__value, __aligment) ((__aligment == 1) ? \
- (__value) : (((__value + __aligment - 1) / __aligment) * __aligment))
-
-#endif /* __BASIC_TYPES_H__ */
diff --git a/drivers/staging/r8188eu/include/hal_com.h b/drivers/staging/r8188eu/include/hal_com.h
index 56ba356b5371..d7e333f6ce39 100644
--- a/drivers/staging/r8188eu/include/hal_com.h
+++ b/drivers/staging/r8188eu/include/hal_com.h
@@ -131,9 +131,6 @@
#define REG_NOA_DESC_START 0x05E8
#define REG_NOA_DESC_COUNT 0x05EC
-#include "HalVerDef.h"
-void dump_chip_info(struct HAL_VERSION ChipVersion);
-
/* return the final channel plan decision */
u8 hal_com_get_channel_plan(struct adapter *padapter,
u8 hw_channel_plan,
diff --git a/drivers/staging/r8188eu/include/hal_intf.h b/drivers/staging/r8188eu/include/hal_intf.h
index a56f3d6ca399..ab6856d8a090 100644
--- a/drivers/staging/r8188eu/include/hal_intf.h
+++ b/drivers/staging/r8188eu/include/hal_intf.h
@@ -8,31 +8,15 @@
#include "drv_types.h"
#include "Hal8188EPhyCfg.h"
-enum hw_variables {
- HW_VAR_SET_OPMODE,
- HW_VAR_BASIC_RATE,
- HW_VAR_CORRECT_TSF,
- HW_VAR_MLME_SITESURVEY,
- HW_VAR_SLOT_TIME,
- HW_VAR_DM_FLAG,
- HW_VAR_DM_FUNC_OP,
- HW_VAR_DM_FUNC_RESET,
- HW_VAR_DM_FUNC_CLR,
- HW_VAR_AMPDU_FACTOR,
- HW_VAR_H2C_MEDIA_STATUS_RPT,
-};
-
typedef s32 (*c2h_id_filter)(u8 id);
-#define is_boot_from_eeprom(adapter) (adapter->eeprompriv.EepromOrEfuse)
-
void rtl8188eu_interface_configure(struct adapter *adapt);
void ReadAdapterInfo8188EU(struct adapter *Adapter);
void rtl8188eu_init_default_value(struct adapter *adapt);
void rtl8188e_SetHalODMVar(struct adapter *Adapter, void *pValue1, bool bSet);
u32 rtl8188eu_InitPowerOn(struct adapter *adapt);
void rtl8188e_EfusePowerSwitch(struct adapter *pAdapter, u8 PwrState);
-void rtl8188e_ReadEFuse(struct adapter *Adapter, u16 _offset, u16 _size_byte, u8 *pbuf);
+void rtl8188e_ReadEFuse(struct adapter *Adapter, u16 _size_byte, u8 *pbuf);
void hal_notch_filter_8188e(struct adapter *adapter, bool enable);
@@ -44,8 +28,6 @@ int rtl8188e_IOL_exec_cmds_sync(struct adapter *adapter,
unsigned int rtl8188eu_inirp_init(struct adapter *Adapter);
-void SetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val);
-
uint rtw_hal_init(struct adapter *padapter);
uint rtw_hal_deinit(struct adapter *padapter);
void rtw_hal_stop(struct adapter *padapter);
diff --git a/drivers/staging/r8188eu/include/ieee80211.h b/drivers/staging/r8188eu/include/ieee80211.h
index 15636a808f52..e7a4f8af497a 100644
--- a/drivers/staging/r8188eu/include/ieee80211.h
+++ b/drivers/staging/r8188eu/include/ieee80211.h
@@ -624,13 +624,6 @@ enum _PUBLIC_ACTION {
ACT_PUBLIC_MAX
};
-/* BACK action code */
-enum rtw_ieee80211_back_actioncode {
- RTW_WLAN_ACTION_ADDBA_REQ = 0,
- RTW_WLAN_ACTION_ADDBA_RESP = 1,
- RTW_WLAN_ACTION_DELBA = 2,
-};
-
#define OUI_MICROSOFT 0x0050f2 /* Microsoft (also used in Wi-Fi specs)
* 00:50:F2 */
#define WME_OUI_TYPE 2
diff --git a/drivers/staging/r8188eu/include/osdep_service.h b/drivers/staging/r8188eu/include/osdep_service.h
index f1a703643e74..72990a1cdc66 100644
--- a/drivers/staging/r8188eu/include/osdep_service.h
+++ b/drivers/staging/r8188eu/include/osdep_service.h
@@ -5,7 +5,6 @@
#define __OSDEP_SERVICE_H_
#include <linux/sched/signal.h>
-#include "basic_types.h"
#define _FAIL 0
#define _SUCCESS 1
@@ -77,8 +76,6 @@ void *rtw_malloc2d(int h, int w, int size);
spin_lock_init(&((q)->lock)); \
} while (0)
-void rtw_usleep_os(int us);
-
static inline unsigned char _cancel_timer_ex(struct timer_list *ptimer)
{
return del_timer_sync(ptimer);
diff --git a/drivers/staging/r8188eu/include/rtl8188e_hal.h b/drivers/staging/r8188eu/include/rtl8188e_hal.h
index d2a069d4e1cc..5cd62b216720 100644
--- a/drivers/staging/r8188eu/include/rtl8188e_hal.h
+++ b/drivers/staging/r8188eu/include/rtl8188e_hal.h
@@ -26,11 +26,6 @@
#include "odm_RegConfig8188E.h"
#include "odm_RTL8188E.h"
-/* RTL8188E Power Configuration CMDs for USB/SDIO interfaces */
-#define Rtl8188E_NIC_PWR_ON_FLOW rtl8188E_power_on_flow
-#define Rtl8188E_NIC_DISABLE_FLOW rtl8188E_card_disable_flow
-#define Rtl8188E_NIC_LPS_ENTER_FLOW rtl8188E_enter_lps_flow
-
#define DRVINFO_SZ 4 /* unit is 8bytes */
#define PageNum_128(_Len) (u32)(((_Len)>>7) + ((_Len) & 0x7F ? 1 : 0))
diff --git a/drivers/staging/r8188eu/include/rtl8188e_spec.h b/drivers/staging/r8188eu/include/rtl8188e_spec.h
index ef42c4b2f20c..9e7b1f89037c 100644
--- a/drivers/staging/r8188eu/include/rtl8188e_spec.h
+++ b/drivers/staging/r8188eu/include/rtl8188e_spec.h
@@ -9,7 +9,6 @@
#define HAL_PS_TIMER_INT_DELAY 50 /* 50 microseconds */
#define HAL_92C_NAV_UPPER_UNIT 128 /* micro-second */
-#define MAC_ADDR_LEN 6
/* 8188E PKT_BUFF_ACCESS_CTRL value */
#define TXPKT_BUF_SELECT 0x69
#define RXPKT_BUF_SELECT 0xA5
@@ -427,12 +426,6 @@
#define MAX_MSS_DENSITY_2T 0x13
#define MAX_MSS_DENSITY_1T 0x0A
-/* EEPROM enable when set 1 */
-#define CmdEEPROM_En BIT(5)
-/* System EEPROM select, 0: boot from E-FUSE, 1: The EEPROM used is 9346 */
-#define CmdEERPOMSEL BIT(4)
-#define Cmd9346CR_9356SEL BIT(4)
-
/* 8192C GPIO MUX Configuration Register (offset 0x40, 4 byte) */
#define GPIOSEL_GPIO 0
#define GPIOSEL_ENBT BIT(5)
@@ -1059,142 +1052,6 @@ Current IOREG MAP
#define SCR_TXBCUSEDK BIT(6) /* Force Tx Bcast pkt Use Default Key */
#define SCR_RXBCUSEDK BIT(7) /* Force Rx Bcast pkt Use Default Key */
-/* RTL8188E SDIO Configuration */
-
-/* I/O bus domain address mapping */
-#define SDIO_LOCAL_BASE 0x10250000
-#define WLAN_IOREG_BASE 0x10260000
-#define FIRMWARE_FIFO_BASE 0x10270000
-#define TX_HIQ_BASE 0x10310000
-#define TX_MIQ_BASE 0x10320000
-#define TX_LOQ_BASE 0x10330000
-#define RX_RX0FF_BASE 0x10340000
-
-/* SDIO host local register space mapping. */
-#define SDIO_LOCAL_MSK 0x0FFF
-#define WLAN_IOREG_MSK 0x7FFF
-#define WLAN_FIFO_MSK 0x1FFF /* Aggregation Length[12:0] */
-#define WLAN_RX0FF_MSK 0x0003
-
-/* Without ref to the SDIO Device ID */
-#define SDIO_WITHOUT_REF_DEVICE_ID 0
-#define SDIO_LOCAL_DEVICE_ID 0 /* 0b[16], 000b[15:13] */
-#define WLAN_TX_HIQ_DEVICE_ID 4 /* 0b[16], 100b[15:13] */
-#define WLAN_TX_MIQ_DEVICE_ID 5 /* 0b[16], 101b[15:13] */
-#define WLAN_TX_LOQ_DEVICE_ID 6 /* 0b[16], 110b[15:13] */
-#define WLAN_RX0FF_DEVICE_ID 7 /* 0b[16], 111b[15:13] */
-#define WLAN_IOREG_DEVICE_ID 8 /* 1b[16] */
-
-/* SDIO Tx Free Page Index */
-#define HI_QUEUE_IDX 0
-#define MID_QUEUE_IDX 1
-#define LOW_QUEUE_IDX 2
-#define PUBLIC_QUEUE_IDX 3
-
-#define SDIO_MAX_TX_QUEUE 3 /* HIQ, MIQ and LOQ */
-#define SDIO_MAX_RX_QUEUE 1
-
-/* SDIO Tx Control */
-#define SDIO_REG_TX_CTRL 0x0000
-/* SDIO Host Interrupt Mask */
-#define SDIO_REG_HIMR 0x0014
-/* SDIO Host Interrupt Service Routine */
-#define SDIO_REG_HISR 0x0018
-/* HCI Current Power Mode */
-#define SDIO_REG_HCPWM 0x0019
-/* RXDMA Request Length */
-#define SDIO_REG_RX0_REQ_LEN 0x001C
-/* Free Tx Buffer Page */
-#define SDIO_REG_FREE_TXPG 0x0020
-/* HCI Current Power Mode 1 */
-#define SDIO_REG_HCPWM1 0x0024
-/* HCI Current Power Mode 2 */
-#define SDIO_REG_HCPWM2 0x0026
-/* HTSF Informaion */
-#define SDIO_REG_HTSFR_INFO 0x0030
-/* HCI Request Power Mode 1 */
-#define SDIO_REG_HRPWM1 0x0080
-/* HCI Request Power Mode 2 */
-#define SDIO_REG_HRPWM2 0x0082
-/* HCI Power Save Clock */
-#define SDIO_REG_HPS_CLKR 0x0084
-/* SDIO HCI Suspend Control */
-#define SDIO_REG_HSUS_CTRL 0x0086
-/* SDIO Host Extension Interrupt Mask Always */
-#define SDIO_REG_HIMR_ON 0x0090
-/* SDIO Host Extension Interrupt Status Always */
-#define SDIO_REG_HISR_ON 0x0091
-
-#define SDIO_HIMR_DISABLED 0
-
-/* RTL8188E SDIO Host Interrupt Mask Register */
-#define SDIO_HIMR_RX_REQUEST_MSK BIT(0)
-#define SDIO_HIMR_AVAL_MSK BIT(1)
-#define SDIO_HIMR_TXERR_MSK BIT(2)
-#define SDIO_HIMR_RXERR_MSK BIT(3)
-#define SDIO_HIMR_TXFOVW_MSK BIT(4)
-#define SDIO_HIMR_RXFOVW_MSK BIT(5)
-#define SDIO_HIMR_TXBCNOK_MSK BIT(6)
-#define SDIO_HIMR_TXBCNERR_MSK BIT(7)
-#define SDIO_HIMR_BCNERLY_INT_MSK BIT(16)
-#define SDIO_HIMR_C2HCMD_MSK BIT(17)
-#define SDIO_HIMR_CPWM1_MSK BIT(18)
-#define SDIO_HIMR_CPWM2_MSK BIT(19)
-#define SDIO_HIMR_HSISR_IND_MSK BIT(20)
-#define SDIO_HIMR_GTINT3_IND_MSK BIT(21)
-#define SDIO_HIMR_GTINT4_IND_MSK BIT(22)
-#define SDIO_HIMR_PSTIMEOUT_MSK BIT(23)
-#define SDIO_HIMR_OCPINT_MSK BIT(24)
-#define SDIO_HIMR_ATIMEND_MSK BIT(25)
-#define SDIO_HIMR_ATIMEND_E_MSK BIT(26)
-#define SDIO_HIMR_CTWEND_MSK BIT(27)
-
-/* RTL8188E SDIO Specific */
-#define SDIO_HIMR_MCU_ERR_MSK BIT(28)
-#define SDIO_HIMR_TSF_BIT32_TOGGLE_MSK BIT(29)
-
-/* SDIO Host Interrupt Service Routine */
-#define SDIO_HISR_RX_REQUEST BIT(0)
-#define SDIO_HISR_AVAL BIT(1)
-#define SDIO_HISR_TXERR BIT(2)
-#define SDIO_HISR_RXERR BIT(3)
-#define SDIO_HISR_TXFOVW BIT(4)
-#define SDIO_HISR_RXFOVW BIT(5)
-#define SDIO_HISR_TXBCNOK BIT(6)
-#define SDIO_HISR_TXBCNERR BIT(7)
-#define SDIO_HISR_BCNERLY_INT BIT(16)
-#define SDIO_HISR_C2HCMD BIT(17)
-#define SDIO_HISR_CPWM1 BIT(18)
-#define SDIO_HISR_CPWM2 BIT(19)
-#define SDIO_HISR_HSISR_IND BIT(20)
-#define SDIO_HISR_GTINT3_IND BIT(21)
-#define SDIO_HISR_GTINT4_IND BIT(22)
-#define SDIO_HISR_PSTIME BIT(23)
-#define SDIO_HISR_OCPINT BIT(24)
-#define SDIO_HISR_ATIMEND BIT(25)
-#define SDIO_HISR_ATIMEND_E BIT(26)
-#define SDIO_HISR_CTWEND BIT(27)
-
-/* RTL8188E SDIO Specific */
-#define SDIO_HISR_MCU_ERR BIT(28)
-#define SDIO_HISR_TSF_BIT32_TOGGLE BIT(29)
-
-#define MASK_SDIO_HISR_CLEAR \
- (SDIO_HISR_TXERR | SDIO_HISR_RXERR | SDIO_HISR_TXFOVW |\
- SDIO_HISR_RXFOVW | SDIO_HISR_TXBCNOK | SDIO_HISR_TXBCNERR |\
- SDIO_HISR_C2HCMD | SDIO_HISR_CPWM1 | SDIO_HISR_CPWM2 |\
- SDIO_HISR_HSISR_IND | SDIO_HISR_GTINT3_IND | SDIO_HISR_GTINT4_IND |\
- SDIO_HISR_PSTIMEOUT | SDIO_HISR_OCPINT)
-
-/* SDIO HCI Suspend Control Register */
-#define HCI_RESUME_PWR_RDY BIT(1)
-#define HCI_SUS_CTRL BIT(0)
-
-/* SDIO Tx FIFO related */
-/* The number of Tx FIFO free page */
-#define SDIO_TX_FREE_PG_QUEUE 4
-#define SDIO_TX_FIFO_PAGE_SZ 128
-
/* 0xFE00h ~ 0xFE55h USB Configuration */
/* 2 USB Information (0xFE17) */
diff --git a/drivers/staging/r8188eu/include/rtw_eeprom.h b/drivers/staging/r8188eu/include/rtw_eeprom.h
index d8d48ace356c..94d735b1d0db 100644
--- a/drivers/staging/r8188eu/include/rtw_eeprom.h
+++ b/drivers/staging/r8188eu/include/rtw_eeprom.h
@@ -7,19 +7,9 @@
#include "osdep_service.h"
#include "drv_types.h"
-#define HWSET_MAX_SIZE_512 512
-
struct eeprom_priv {
u8 bautoload_fail_flag;
u8 mac_addr[ETH_ALEN] __aligned(2); /* PermanentAddress */
- u8 EepromOrEfuse;
- u8 efuse_eeprom_data[HWSET_MAX_SIZE_512] __aligned(4);
};
-void eeprom_write16(struct adapter *padapter, u16 reg, u16 data);
-u16 eeprom_read16(struct adapter *padapter, u16 reg);
-void read_eeprom_content(struct adapter *padapter);
-void eeprom_read_sz(struct adapter *adapt, u16 reg, u8 *data, u32 sz);
-void read_eeprom_content_by_attrib(struct adapter *padapter);
-
#endif /* __RTL871X_EEPROM_H__ */
diff --git a/drivers/staging/r8188eu/include/rtw_efuse.h b/drivers/staging/r8188eu/include/rtw_efuse.h
index 2daf69f554d5..3d688a0e6dfb 100644
--- a/drivers/staging/r8188eu/include/rtw_efuse.h
+++ b/drivers/staging/r8188eu/include/rtw_efuse.h
@@ -8,6 +8,4 @@
void ReadEFuseByte(struct adapter *adapter, u16 _offset, u8 *pbuf);
-void EFUSE_ShadowMapUpdate(struct adapter *adapter);
-
#endif
diff --git a/drivers/staging/r8188eu/include/rtw_io.h b/drivers/staging/r8188eu/include/rtw_io.h
index 6910e2b430e2..925c7967ac04 100644
--- a/drivers/staging/r8188eu/include/rtw_io.h
+++ b/drivers/staging/r8188eu/include/rtw_io.h
@@ -220,9 +220,9 @@ void unregister_intf_hdl(struct intf_hdl *pintfhdl);
void _rtw_attrib_read(struct adapter *adapter, u32 addr, u32 cnt, u8 *pmem);
void _rtw_attrib_write(struct adapter *adapter, u32 addr, u32 cnt, u8 *pmem);
-u8 rtw_read8(struct adapter *adapter, u32 addr);
-u16 rtw_read16(struct adapter *adapter, u32 addr);
-u32 rtw_read32(struct adapter *adapter, u32 addr);
+int __must_check rtw_read8(struct adapter *adapter, u32 addr, u8 *data);
+int __must_check rtw_read16(struct adapter *adapter, u32 addr, u16 *data);
+int __must_check rtw_read32(struct adapter *adapter, u32 addr, u32 *data);
void _rtw_read_mem(struct adapter *adapter, u32 addr, u32 cnt, u8 *pmem);
u32 rtw_read_port(struct adapter *adapter, u8 *pmem);
void rtw_read_port_cancel(struct adapter *adapter);
@@ -283,7 +283,7 @@ void free_io_queue(struct adapter *adapter);
void async_bus_io(struct io_queue *pio_q);
void bus_sync_io(struct io_queue *pio_q);
u32 _ioreq2rwmem(struct io_queue *pio_q);
-void dev_power_down(struct adapter * Adapter, u8 bpwrup);
+void dev_power_down(struct adapter *Adapter, u8 bpwrup);
#define PlatformEFIOWrite1Byte(_a,_b,_c) \
rtw_write8(_a,_b,_c)
diff --git a/drivers/staging/r8188eu/include/rtw_iol.h b/drivers/staging/r8188eu/include/rtw_iol.h
index fb88ebc1dabb..099f5a075274 100644
--- a/drivers/staging/r8188eu/include/rtw_iol.h
+++ b/drivers/staging/r8188eu/include/rtw_iol.h
@@ -41,22 +41,14 @@ int rtw_IOL_append_END_cmd(struct xmit_frame *xmit_frame);
void read_efuse_from_txpktbuf(struct adapter *adapter, int bcnhead,
u8 *content, u16 *size);
-int _rtw_IOL_append_WB_cmd(struct xmit_frame *xmit_frame, u16 addr,
- u8 value, u8 mask);
-int _rtw_IOL_append_WW_cmd(struct xmit_frame *xmit_frame, u16 addr,
- u16 value, u16 mask);
-int _rtw_IOL_append_WD_cmd(struct xmit_frame *xmit_frame, u16 addr,
- u32 value, u32 mask);
-int _rtw_IOL_append_WRF_cmd(struct xmit_frame *xmit_frame, u8 rf_path,
- u16 addr, u32 value, u32 mask);
-#define rtw_IOL_append_WB_cmd(xmit_frame, addr, value, mask) \
- _rtw_IOL_append_WB_cmd((xmit_frame), (addr), (value) ,(mask))
-#define rtw_IOL_append_WW_cmd(xmit_frame, addr, value, mask) \
- _rtw_IOL_append_WW_cmd((xmit_frame), (addr), (value),(mask))
-#define rtw_IOL_append_WD_cmd(xmit_frame, addr, value, mask) \
- _rtw_IOL_append_WD_cmd((xmit_frame), (addr), (value), (mask))
-#define rtw_IOL_append_WRF_cmd(xmit_frame, rf_path, addr, value, mask) \
- _rtw_IOL_append_WRF_cmd((xmit_frame),(rf_path), (addr), (value), (mask))
+int rtw_IOL_append_WB_cmd(struct xmit_frame *xmit_frame, u16 addr,
+ u8 value, u8 mask);
+int rtw_IOL_append_WW_cmd(struct xmit_frame *xmit_frame, u16 addr,
+ u16 value, u16 mask);
+int rtw_IOL_append_WD_cmd(struct xmit_frame *xmit_frame, u16 addr,
+ u32 value, u32 mask);
+int rtw_IOL_append_WRF_cmd(struct xmit_frame *xmit_frame, u8 rf_path,
+ u16 addr, u32 value, u32 mask);
u8 rtw_IOL_cmd_boundary_handle(struct xmit_frame *pxmit_frame);
diff --git a/drivers/staging/r8188eu/include/rtw_led.h b/drivers/staging/r8188eu/include/rtw_led.h
index 2c14cb23d9ad..d6b0c1c2f9a2 100644
--- a/drivers/staging/r8188eu/include/rtw_led.h
+++ b/drivers/staging/r8188eu/include/rtw_led.h
@@ -37,9 +37,11 @@ enum LED_STATE_871x {
LED_BLINK_RUNTOP = 13, /* Customized for RunTop */
};
-struct LED_871x {
+struct led_priv {
struct adapter *padapter;
+ bool bRegUseLed;
+
enum LED_STATE_871x CurrLedState; /* Current LED state. */
enum LED_STATE_871x BlinkingLedState; /* Next state for blinking,
* either RTW_LED_ON or RTW_LED_OFF are. */
@@ -58,11 +60,6 @@ struct LED_871x {
struct delayed_work blink_work;
};
-struct led_priv{
- struct LED_871x SwLed0;
- bool bRegUseLed;
-};
-
void rtl8188eu_InitSwLeds(struct adapter *padapter);
void rtl8188eu_DeInitSwLeds(struct adapter *padapter);
diff --git a/drivers/staging/r8188eu/include/rtw_mlme_ext.h b/drivers/staging/r8188eu/include/rtw_mlme_ext.h
index 573d65b175cc..343ce1ce4b3d 100644
--- a/drivers/staging/r8188eu/include/rtw_mlme_ext.h
+++ b/drivers/staging/r8188eu/include/rtw_mlme_ext.h
@@ -424,6 +424,9 @@ void invalidate_cam_all(struct adapter *padapter);
int allocate_fw_sta_entry(struct adapter *padapter);
void flush_all_cam_entry(struct adapter *padapter);
+void rtw_mlme_under_site_survey(struct adapter *adapter);
+void rtw_mlme_site_survey_done(struct adapter *adapter);
+
void site_survey(struct adapter *padapter);
u8 collect_bss_info(struct adapter *padapter, struct recv_frame *precv_frame,
struct wlan_bssid_ex *bssid);
@@ -455,6 +458,7 @@ int rtw_check_bcn_info(struct adapter *Adapter, u8 *pframe, u32 packet_len);
void update_IOT_info(struct adapter *padapter);
void update_capinfo(struct adapter *adapter, u16 updatecap);
void update_wireless_mode(struct adapter *padapter);
+void rtw_set_basic_rate(struct adapter *adapter, u8 *rates);
void update_tx_basic_rate(struct adapter *padapter, u8 modulation);
void update_bmc_sta_support_rate(struct adapter *padapter, u32 mac_id);
int update_sta_support_rate(struct adapter *padapter, u8 *pvar_ie,
@@ -468,8 +472,7 @@ unsigned int update_MSC_rate(struct HT_caps_element *pHT_caps);
void Update_RA_Entry(struct adapter *padapter, u32 mac_id);
void set_sta_rate(struct adapter *padapter, struct sta_info *psta);
-unsigned int receive_disconnect(struct adapter *padapter,
- unsigned char *macaddr, unsigned short reason);
+void receive_disconnect(struct adapter *padapter, unsigned char *macaddr, unsigned short reason);
unsigned char get_highest_rate_idx(u32 mask);
int support_short_GI(struct adapter *padapter, struct HT_caps_element *caps);
@@ -524,12 +527,13 @@ int issue_deauth(struct adapter *padapter, unsigned char *da,
unsigned short reason);
int issue_deauth_ex(struct adapter *padapter, u8 *da, unsigned short reason,
int try_cnt, int wait_ms);
-void issue_action_BA(struct adapter *padapter, unsigned char *raddr,
- unsigned char action, unsigned short status);
+void issue_action_BA(struct adapter *padapter, unsigned char *raddr, u8 action, u16 status);
unsigned int send_delba(struct adapter *padapter, u8 initiator, u8 *addr);
unsigned int send_beacon(struct adapter *padapter);
bool get_beacon_valid_bit(struct adapter *adapter);
void clear_beacon_valid_bit(struct adapter *adapter);
+void rtw_resume_tx_beacon(struct adapter *adapt);
+void rtw_stop_tx_beacon(struct adapter *adapt);
void start_clnt_assoc(struct adapter *padapter);
void start_clnt_auth(struct adapter *padapter);
@@ -544,12 +548,8 @@ unsigned int OnProbeReq(struct adapter *padapter,
struct recv_frame *precv_frame);
unsigned int OnProbeRsp(struct adapter *padapter,
struct recv_frame *precv_frame);
-unsigned int DoReserved(struct adapter *padapter,
- struct recv_frame *precv_frame);
unsigned int OnBeacon(struct adapter *padapter,
struct recv_frame *precv_frame);
-unsigned int OnAtim(struct adapter *padapter,
- struct recv_frame *precv_frame);
unsigned int OnDisassoc(struct adapter *padapter,
struct recv_frame *precv_frame);
unsigned int OnAuth(struct adapter *padapter,
@@ -592,9 +592,6 @@ void addba_timer_hdl(struct sta_info *psta);
bool cckrates_included(unsigned char *rate, int ratelen);
bool cckratesonly_included(unsigned char *rate, int ratelen);
-void update_TSF(struct mlme_ext_priv *pmlmeext, u8 *pframe, uint len);
-void correct_TSF(struct adapter *padapter, struct mlme_ext_priv *pmlmeext);
-
struct cmd_hdl {
uint parmsize;
u8 (*h2cfuns)(struct adapter *padapter, u8 *pbuf);
diff --git a/drivers/staging/r8188eu/include/usb_ops_linux.h b/drivers/staging/r8188eu/include/usb_ops_linux.h
index 641f059ffaf7..966688eedf66 100644
--- a/drivers/staging/r8188eu/include/usb_ops_linux.h
+++ b/drivers/staging/r8188eu/include/usb_ops_linux.h
@@ -26,6 +26,4 @@
#define usb_read_interrupt_complete(purb, regs) \
usb_read_interrupt_complete(purb)
-unsigned int ffaddr2pipehdl(struct dvobj_priv *pdvobj, u32 addr);
-
#endif
diff --git a/drivers/staging/r8188eu/os_dep/ioctl_linux.c b/drivers/staging/r8188eu/os_dep/ioctl_linux.c
index 8dd280e2739a..7f91dac2e41b 100644
--- a/drivers/staging/r8188eu/os_dep/ioctl_linux.c
+++ b/drivers/staging/r8188eu/os_dep/ioctl_linux.c
@@ -687,12 +687,9 @@ static int rtw_wx_set_mode(struct net_device *dev, struct iw_request_info *a,
enum ndis_802_11_network_infra networkType;
int ret = 0;
-
-
- if (_FAIL == rtw_pwr_wakeup(padapter)) {
- ret = -EPERM;
+ ret = rtw_pwr_wakeup(padapter);
+ if (ret)
goto exit;
- }
if (!padapter->hw_init_completed) {
ret = -EPERM;
@@ -931,12 +928,9 @@ static int rtw_wx_set_wap(struct net_device *dev,
struct wlan_network *pnetwork = NULL;
enum ndis_802_11_auth_mode authmode;
-
-
- if (_FAIL == rtw_pwr_wakeup(padapter)) {
- ret = -1;
+ ret = rtw_pwr_wakeup(padapter);
+ if (ret)
goto exit;
- }
if (!padapter->bup) {
ret = -1;
@@ -1049,10 +1043,9 @@ static int rtw_wx_set_scan(struct net_device *dev, struct iw_request_info *a,
struct ndis_802_11_ssid ssid[RTW_SSID_SCAN_AMOUNT];
struct wifidirect_info *pwdinfo = &padapter->wdinfo;
- if (_FAIL == rtw_pwr_wakeup(padapter)) {
- ret = -1;
+ ret = rtw_pwr_wakeup(padapter);
+ if (ret)
goto exit;
- }
if (padapter->bDriverStopped) {
ret = -1;
@@ -1252,10 +1245,9 @@ static int rtw_wx_set_essid(struct net_device *dev,
uint ret = 0, len;
- if (_FAIL == rtw_pwr_wakeup(padapter)) {
- ret = -1;
+ ret = rtw_pwr_wakeup(padapter);
+ if (ret)
goto exit;
- }
if (!padapter->bup) {
ret = -1;
@@ -1593,7 +1585,7 @@ static int rtw_wx_set_enc(struct net_device *dev,
if (erq->length > 0) {
wep.KeyLength = erq->length <= 5 ? 5 : 13;
- wep.Length = wep.KeyLength + FIELD_OFFSET(struct ndis_802_11_wep, KeyMaterial);
+ wep.Length = wep.KeyLength + offsetof(struct ndis_802_11_wep, KeyMaterial);
} else {
wep.KeyLength = 0;
@@ -3126,18 +3118,29 @@ exit:
static void mac_reg_dump(struct adapter *padapter)
{
int i, j = 1;
+ u32 reg;
+ int res;
+
pr_info("\n ======= MAC REG =======\n");
for (i = 0x0; i < 0x300; i += 4) {
if (j % 4 == 1)
pr_info("0x%02x", i);
- pr_info(" 0x%08x ", rtw_read32(padapter, i));
+
+ res = rtw_read32(padapter, i, &reg);
+ if (!res)
+ pr_info(" 0x%08x ", reg);
+
if ((j++) % 4 == 0)
pr_info("\n");
}
for (i = 0x400; i < 0x800; i += 4) {
if (j % 4 == 1)
pr_info("0x%02x", i);
- pr_info(" 0x%08x ", rtw_read32(padapter, i));
+
+ res = rtw_read32(padapter, i, &reg);
+ if (!res)
+ pr_info(" 0x%08x ", reg);
+
if ((j++) % 4 == 0)
pr_info("\n");
}
@@ -3145,13 +3148,18 @@ static void mac_reg_dump(struct adapter *padapter)
static void bb_reg_dump(struct adapter *padapter)
{
- int i, j = 1;
+ int i, j = 1, res;
+ u32 reg;
+
pr_info("\n ======= BB REG =======\n");
for (i = 0x800; i < 0x1000; i += 4) {
if (j % 4 == 1)
pr_info("0x%02x", i);
- pr_info(" 0x%08x ", rtw_read32(padapter, i));
+ res = rtw_read32(padapter, i, &reg);
+ if (!res)
+ pr_info(" 0x%08x ", reg);
+
if ((j++) % 4 == 0)
pr_info("\n");
}
@@ -3178,6 +3186,7 @@ static void rtw_set_dynamic_functions(struct adapter *adapter, u8 dm_func)
{
struct hal_data_8188e *haldata = &adapter->haldata;
struct odm_dm_struct *odmpriv = &haldata->odmpriv;
+ int res;
switch (dm_func) {
case 0:
@@ -3193,7 +3202,9 @@ static void rtw_set_dynamic_functions(struct adapter *adapter, u8 dm_func)
if (!(odmpriv->SupportAbility & DYNAMIC_BB_DIG)) {
struct rtw_dig *digtable = &odmpriv->DM_DigTable;
- digtable->CurIGValue = rtw_read8(adapter, 0xc50);
+ res = rtw_read8(adapter, 0xc50, &digtable->CurIGValue);
+ (void)res;
+ /* FIXME: return an error to caller */
}
odmpriv->SupportAbility = DYNAMIC_ALL_FUNC_ENABLE;
break;
@@ -3202,6 +3213,14 @@ static void rtw_set_dynamic_functions(struct adapter *adapter, u8 dm_func)
}
}
+static void rtw_set_dm_func_flag(struct adapter *adapter, u32 odm_flag)
+{
+ struct hal_data_8188e *haldata = &adapter->haldata;
+ struct odm_dm_struct *odmpriv = &haldata->odmpriv;
+
+ odmpriv->SupportAbility = odm_flag;
+}
+
static int rtw_dbg_port(struct net_device *dev,
struct iw_request_info *info,
union iwreq_data *wrqu, char *extra)
@@ -3329,8 +3348,9 @@ static int rtw_dbg_port(struct net_device *dev,
u16 reg = arg;
u16 start_value = 0;
u32 write_num = extra_arg;
- int i;
+ int i, res;
struct xmit_frame *xmit_frame;
+ u8 val8;
xmit_frame = rtw_IOL_accquire_xmit_frame(padapter);
if (!xmit_frame) {
@@ -3343,7 +3363,9 @@ static int rtw_dbg_port(struct net_device *dev,
if (rtl8188e_IOL_exec_cmds_sync(padapter, xmit_frame, 5000, 0) != _SUCCESS)
ret = -EPERM;
- rtw_read8(padapter, reg);
+ /* FIXME: is this read necessary? */
+ res = rtw_read8(padapter, reg, &val8);
+ (void)res;
}
break;
@@ -3352,8 +3374,8 @@ static int rtw_dbg_port(struct net_device *dev,
u16 reg = arg;
u16 start_value = 200;
u32 write_num = extra_arg;
-
- int i;
+ u16 val16;
+ int i, res;
struct xmit_frame *xmit_frame;
xmit_frame = rtw_IOL_accquire_xmit_frame(padapter);
@@ -3367,7 +3389,9 @@ static int rtw_dbg_port(struct net_device *dev,
if (rtl8188e_IOL_exec_cmds_sync(padapter, xmit_frame, 5000, 0) != _SUCCESS)
ret = -EPERM;
- rtw_read16(padapter, reg);
+ /* FIXME: is this read necessary? */
+ res = rtw_read16(padapter, reg, &val16);
+ (void)res;
}
break;
case 0x08: /* continuous write dword test */
@@ -3390,7 +3414,8 @@ static int rtw_dbg_port(struct net_device *dev,
if (rtl8188e_IOL_exec_cmds_sync(padapter, xmit_frame, 5000, 0) != _SUCCESS)
ret = -EPERM;
- rtw_read32(padapter, reg);
+ /* FIXME: is this read necessary? */
+ ret = rtw_read32(padapter, reg, &write_num);
}
break;
}
@@ -3434,7 +3459,7 @@ static int rtw_dbg_port(struct net_device *dev,
case 0x06:
{
u32 ODMFlag = (u32)(0x0f & arg);
- SetHwReg8188EU(padapter, HW_VAR_DM_FLAG, (u8 *)(&ODMFlag));
+ rtw_set_dm_func_flag(padapter, ODMFlag);
}
break;
case 0x07:
diff --git a/drivers/staging/r8188eu/os_dep/os_intfs.c b/drivers/staging/r8188eu/os_dep/os_intfs.c
index 891c85b088ca..cac9553666e6 100644
--- a/drivers/staging/r8188eu/os_dep/os_intfs.c
+++ b/drivers/staging/r8188eu/os_dep/os_intfs.c
@@ -740,19 +740,32 @@ static void rtw_fifo_cleanup(struct adapter *adapter)
{
struct pwrctrl_priv *pwrpriv = &adapter->pwrctrlpriv;
u8 trycnt = 100;
+ int res;
+ u32 reg;
/* pause tx */
rtw_write8(adapter, REG_TXPAUSE, 0xff);
/* keep sn */
- adapter->xmitpriv.nqos_ssn = rtw_read16(adapter, REG_NQOS_SEQ);
+ /* FIXME: return an error to caller */
+ res = rtw_read16(adapter, REG_NQOS_SEQ, &adapter->xmitpriv.nqos_ssn);
+ if (res)
+ return;
if (!pwrpriv->bkeepfwalive) {
/* RX DMA stop */
+ res = rtw_read32(adapter, REG_RXPKT_NUM, &reg);
+ if (res)
+ return;
+
rtw_write32(adapter, REG_RXPKT_NUM,
- (rtw_read32(adapter, REG_RXPKT_NUM) | RW_RELEASE_EN));
+ (reg | RW_RELEASE_EN));
do {
- if (!(rtw_read32(adapter, REG_RXPKT_NUM) & RXDMA_IDLE))
+ res = rtw_read32(adapter, REG_RXPKT_NUM, &reg);
+ if (res)
+ continue;
+
+ if (!(reg & RXDMA_IDLE))
break;
} while (trycnt--);
diff --git a/drivers/staging/r8188eu/os_dep/osdep_service.c b/drivers/staging/r8188eu/os_dep/osdep_service.c
index 812acd59be79..3504a0a9ba87 100644
--- a/drivers/staging/r8188eu/os_dep/osdep_service.c
+++ b/drivers/staging/r8188eu/os_dep/osdep_service.c
@@ -42,14 +42,6 @@ Otherwise, there will be racing condition.
Caller must check if the list is empty before calling rtw_list_delete
*/
-void rtw_usleep_os(int us)
-{
- if (1 < (us / 1000))
- msleep(1);
- else
- msleep((us / 1000) + 1);
-}
-
static const struct device_type wlan_type = {
.name = "wlan",
};
diff --git a/drivers/staging/r8188eu/os_dep/usb_intf.c b/drivers/staging/r8188eu/os_dep/usb_intf.c
index 68869c5daeff..cc2b44f60c46 100644
--- a/drivers/staging/r8188eu/os_dep/usb_intf.c
+++ b/drivers/staging/r8188eu/os_dep/usb_intf.c
@@ -372,7 +372,7 @@ handle_dualmac:
free_adapter:
if (pnetdev)
rtw_free_netdev(pnetdev);
- else if (padapter)
+ else
vfree(padapter);
return NULL;
diff --git a/drivers/staging/r8188eu/os_dep/usb_ops_linux.c b/drivers/staging/r8188eu/os_dep/usb_ops_linux.c
index 0269e602b217..220e592b757c 100644
--- a/drivers/staging/r8188eu/os_dep/usb_ops_linux.c
+++ b/drivers/staging/r8188eu/os_dep/usb_ops_linux.c
@@ -7,7 +7,7 @@
#include "../include/usb_ops_linux.h"
#include "../include/rtl8188e_recv.h"
-unsigned int ffaddr2pipehdl(struct dvobj_priv *pdvobj, u32 addr)
+static unsigned int ffaddr2pipehdl(struct dvobj_priv *pdvobj, u32 addr)
{
unsigned int pipe = 0, ep_num = 0;
struct usb_device *pusbd = pdvobj->pusbdev;
diff --git a/drivers/staging/r8188eu/os_dep/xmit_linux.c b/drivers/staging/r8188eu/os_dep/xmit_linux.c
index e430c64e9068..91a1e4e3219a 100644
--- a/drivers/staging/r8188eu/os_dep/xmit_linux.c
+++ b/drivers/staging/r8188eu/os_dep/xmit_linux.c
@@ -71,7 +71,7 @@ int rtw_os_xmit_resource_alloc(struct adapter *padapter, struct xmit_buf *pxmitb
if (!pxmitbuf->pallocated_buf)
return _FAIL;
- pxmitbuf->pbuf = (u8 *)N_BYTE_ALIGMENT((size_t)(pxmitbuf->pallocated_buf), XMITBUF_ALIGN_SZ);
+ pxmitbuf->pbuf = (u8 *)ALIGN((size_t)(pxmitbuf->pallocated_buf), XMITBUF_ALIGN_SZ);
pxmitbuf->dma_transfer_addr = 0;
pxmitbuf->pxmit_urb = usb_alloc_urb(0, GFP_KERNEL);
diff --git a/drivers/staging/rtl8192e/rtllib_tx.c b/drivers/staging/rtl8192e/rtllib_tx.c
index 37715afb0210..42f81b23a144 100644
--- a/drivers/staging/rtl8192e/rtllib_tx.c
+++ b/drivers/staging/rtl8192e/rtllib_tx.c
@@ -205,30 +205,28 @@ static struct rtllib_txb *rtllib_alloc_txb(int nr_frags, int txb_size,
struct rtllib_txb *txb;
int i;
- txb = kmalloc(sizeof(struct rtllib_txb) + (sizeof(u8 *) * nr_frags),
- gfp_mask);
+ txb = kzalloc(struct_size(txb, fragments, nr_frags), gfp_mask);
if (!txb)
return NULL;
- memset(txb, 0, sizeof(struct rtllib_txb));
txb->nr_frags = nr_frags;
txb->frag_size = cpu_to_le16(txb_size);
for (i = 0; i < nr_frags; i++) {
txb->fragments[i] = dev_alloc_skb(txb_size);
- if (unlikely(!txb->fragments[i])) {
- i--;
- break;
- }
+ if (unlikely(!txb->fragments[i]))
+ goto err_free;
memset(txb->fragments[i]->cb, 0, sizeof(txb->fragments[i]->cb));
}
- if (unlikely(i != nr_frags)) {
- while (i >= 0)
- dev_kfree_skb_any(txb->fragments[i--]);
- kfree(txb);
- return NULL;
- }
+
return txb;
+
+err_free:
+ while (--i >= 0)
+ dev_kfree_skb_any(txb->fragments[i]);
+ kfree(txb);
+
+ return NULL;
}
static int rtllib_classify(struct sk_buff *skb, u8 bIsAmsdu)
diff --git a/drivers/staging/rtl8192e/rtllib_wx.c b/drivers/staging/rtl8192e/rtllib_wx.c
index cf9a240924f2..da2c41c9b92f 100644
--- a/drivers/staging/rtl8192e/rtllib_wx.c
+++ b/drivers/staging/rtl8192e/rtllib_wx.c
@@ -17,17 +17,9 @@
#include <linux/module.h>
#include <linux/etherdevice.h>
#include "rtllib.h"
-struct modes_unit {
- char *mode_string;
- int mode_size;
-};
-static struct modes_unit rtllib_modes[] = {
- {"a", 1},
- {"b", 1},
- {"g", 1},
- {"?", 1},
- {"N-24G", 5},
- {"N-5G", 4},
+
+static const char * const rtllib_modes[] = {
+ "a", "b", "g", "?", "N-24G", "N-5G"
};
#define MAX_CUSTOM_LEN 64
@@ -72,10 +64,9 @@ static inline char *rtl819x_translate_scan(struct rtllib_device *ieee,
/* Add the protocol name */
iwe.cmd = SIOCGIWNAME;
for (i = 0; i < ARRAY_SIZE(rtllib_modes); i++) {
- if (network->mode&(1<<i)) {
- sprintf(pname, rtllib_modes[i].mode_string,
- rtllib_modes[i].mode_size);
- pname += rtllib_modes[i].mode_size;
+ if (network->mode & BIT(i)) {
+ strcpy(pname, rtllib_modes[i]);
+ pname += strlen(rtllib_modes[i]);
}
}
*pname = '\0';
@@ -158,7 +149,8 @@ static inline char *rtl819x_translate_scan(struct rtllib_device *ieee,
max_rate = rate;
}
iwe.cmd = SIOCGIWRATE;
- iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0;
+ iwe.u.bitrate.disabled = 0;
+ iwe.u.bitrate.fixed = 0;
iwe.u.bitrate.value = max_rate * 500000;
start = iwe_stream_add_event_rsl(info, start, stop, &iwe, IW_EV_PARAM_LEN);
iwe.cmd = IWEVCUSTOM;
@@ -285,7 +277,7 @@ int rtllib_wx_set_encode(struct rtllib_device *ieee,
struct iw_request_info *info,
union iwreq_data *wrqu, char *keybuf)
{
- struct iw_point *erq = &(wrqu->encoding);
+ struct iw_point *erq = &wrqu->encoding;
struct net_device *dev = ieee->dev;
struct rtllib_security sec = {
.flags = 0
@@ -312,8 +304,9 @@ int rtllib_wx_set_encode(struct rtllib_device *ieee,
netdev_dbg(ieee->dev,
"Disabling encryption on key %d.\n", key);
lib80211_crypt_delayed_deinit(&ieee->crypt_info, crypt);
- } else
+ } else {
netdev_dbg(ieee->dev, "Disabling encryption.\n");
+ }
/* Check all the keys to see if any are still configured,
* and if no key index was provided, de-init them all
@@ -457,7 +450,7 @@ int rtllib_wx_get_encode(struct rtllib_device *ieee,
struct iw_request_info *info,
union iwreq_data *wrqu, char *keybuf)
{
- struct iw_point *erq = &(wrqu->encoding);
+ struct iw_point *erq = &wrqu->encoding;
int len, key;
struct lib80211_crypt_data *crypt;
@@ -608,7 +601,6 @@ int rtllib_wx_set_encode_ext(struct rtllib_device *ieee,
goto done;
}
*crypt = new_crypt;
-
}
if (ext->key_len > 0 && (*crypt)->ops->set_key &&
@@ -732,8 +724,9 @@ int rtllib_wx_set_auth(struct rtllib_device *ieee,
} else if (data->value & IW_AUTH_ALG_LEAP) {
ieee->open_wep = 1;
ieee->auth_mode = 2;
- } else
+ } else {
return -EINVAL;
+ }
break;
case IW_AUTH_WPA_ENABLED:
@@ -776,7 +769,7 @@ int rtllib_wx_set_gen_ie(struct rtllib_device *ieee, u8 *ie, size_t len)
kfree(ieee->wps_ie);
ieee->wps_ie = NULL;
if (len) {
- if (len != ie[1]+2)
+ if (len != ie[1] + 2)
return -EINVAL;
buf = kmemdup(ie, len, GFP_KERNEL);
if (!buf)
diff --git a/drivers/staging/rtl8192u/r8192U.h b/drivers/staging/rtl8192u/r8192U.h
index 14ca00a2789b..1942cb849374 100644
--- a/drivers/staging/rtl8192u/r8192U.h
+++ b/drivers/staging/rtl8192u/r8192U.h
@@ -1013,7 +1013,7 @@ typedef struct r8192_priv {
bool bis_any_nonbepkts;
bool bcurrent_turbo_EDCA;
bool bis_cur_rdlstate;
- struct timer_list fsync_timer;
+ struct delayed_work fsync_work;
bool bfsync_processing; /* 500ms Fsync timer is active or not */
u32 rate_record;
u32 rateCountDiffRecord;
diff --git a/drivers/staging/rtl8192u/r8192U_dm.c b/drivers/staging/rtl8192u/r8192U_dm.c
index 725bf5ca9e34..00fc8fd344db 100644
--- a/drivers/staging/rtl8192u/r8192U_dm.c
+++ b/drivers/staging/rtl8192u/r8192U_dm.c
@@ -2578,19 +2578,20 @@ static void dm_init_fsync(struct net_device *dev)
priv->ieee80211->fsync_seconddiff_ratethreshold = 200;
priv->ieee80211->fsync_state = Default_Fsync;
priv->framesyncMonitor = 1; /* current default 0xc38 monitor on */
- timer_setup(&priv->fsync_timer, dm_fsync_timer_callback, 0);
+ INIT_DELAYED_WORK(&priv->fsync_work, dm_fsync_work_callback);
}
static void dm_deInit_fsync(struct net_device *dev)
{
struct r8192_priv *priv = ieee80211_priv(dev);
- del_timer_sync(&priv->fsync_timer);
+ cancel_delayed_work_sync(&priv->fsync_work);
}
-void dm_fsync_timer_callback(struct timer_list *t)
+void dm_fsync_work_callback(struct work_struct *work)
{
- struct r8192_priv *priv = from_timer(priv, t, fsync_timer);
+ struct r8192_priv *priv =
+ container_of(work, struct r8192_priv, fsync_work.work);
struct net_device *dev = priv->ieee80211->dev;
u32 rate_index, rate_count = 0, rate_count_diff = 0;
bool bSwitchFromCountDiff = false;
@@ -2657,17 +2658,16 @@ void dm_fsync_timer_callback(struct timer_list *t)
}
}
if (bDoubleTimeInterval) {
- if (timer_pending(&priv->fsync_timer))
- del_timer_sync(&priv->fsync_timer);
- priv->fsync_timer.expires = jiffies +
- msecs_to_jiffies(priv->ieee80211->fsync_time_interval*priv->ieee80211->fsync_multiple_timeinterval);
- add_timer(&priv->fsync_timer);
+ cancel_delayed_work_sync(&priv->fsync_work);
+ schedule_delayed_work(&priv->fsync_work,
+ msecs_to_jiffies(priv
+ ->ieee80211->fsync_time_interval *
+ priv->ieee80211->fsync_multiple_timeinterval));
} else {
- if (timer_pending(&priv->fsync_timer))
- del_timer_sync(&priv->fsync_timer);
- priv->fsync_timer.expires = jiffies +
- msecs_to_jiffies(priv->ieee80211->fsync_time_interval);
- add_timer(&priv->fsync_timer);
+ cancel_delayed_work_sync(&priv->fsync_work);
+ schedule_delayed_work(&priv->fsync_work,
+ msecs_to_jiffies(priv
+ ->ieee80211->fsync_time_interval));
}
} else {
/* Let Register return to default value; */
@@ -2695,7 +2695,7 @@ static void dm_EndSWFsync(struct net_device *dev)
struct r8192_priv *priv = ieee80211_priv(dev);
RT_TRACE(COMP_HALDM, "%s\n", __func__);
- del_timer_sync(&(priv->fsync_timer));
+ cancel_delayed_work_sync(&priv->fsync_work);
/* Let Register return to default value; */
if (priv->bswitch_fsync) {
@@ -2736,11 +2736,9 @@ static void dm_StartSWFsync(struct net_device *dev)
if (priv->ieee80211->fsync_rate_bitmap & rateBitmap)
priv->rate_record += priv->stats.received_rate_histogram[1][rateIndex];
}
- if (timer_pending(&priv->fsync_timer))
- del_timer_sync(&priv->fsync_timer);
- priv->fsync_timer.expires = jiffies +
- msecs_to_jiffies(priv->ieee80211->fsync_time_interval);
- add_timer(&priv->fsync_timer);
+ cancel_delayed_work_sync(&priv->fsync_work);
+ schedule_delayed_work(&priv->fsync_work,
+ msecs_to_jiffies(priv->ieee80211->fsync_time_interval));
write_nic_dword(dev, rOFDM0_RxDetector2, 0x465c12cd);
}
@@ -3002,7 +3000,7 @@ static void dm_check_txrateandretrycount(struct net_device *dev)
/* for initial tx rate */
/*priv->stats.last_packet_rate = read_nic_byte(dev, INITIAL_TX_RATE_REG);*/
read_nic_byte(dev, INITIAL_TX_RATE_REG, &ieee->softmac_stats.last_packet_rate);
- /* for tx tx retry count */
+ /* for tx retry count */
/*priv->stats.txretrycount = read_nic_dword(dev, TX_RETRY_COUNT_REG);*/
read_nic_dword(dev, TX_RETRY_COUNT_REG, &ieee->softmac_stats.txretrycount);
}
diff --git a/drivers/staging/rtl8192u/r8192U_dm.h b/drivers/staging/rtl8192u/r8192U_dm.h
index 0b2a1c688597..2159018b4e38 100644
--- a/drivers/staging/rtl8192u/r8192U_dm.h
+++ b/drivers/staging/rtl8192u/r8192U_dm.h
@@ -166,7 +166,7 @@ void dm_force_tx_fw_info(struct net_device *dev,
void dm_init_edca_turbo(struct net_device *dev);
void dm_rf_operation_test_callback(unsigned long data);
void dm_rf_pathcheck_workitemcallback(struct work_struct *work);
-void dm_fsync_timer_callback(struct timer_list *t);
+void dm_fsync_work_callback(struct work_struct *work);
void dm_cck_txpower_adjust(struct net_device *dev, bool binch14);
void dm_shadow_init(struct net_device *dev);
void dm_initialize_txpower_tracking(struct net_device *dev);
diff --git a/drivers/staging/rtl8723bs/core/rtw_mlme_ext.c b/drivers/staging/rtl8723bs/core/rtw_mlme_ext.c
index 1bdbd0971f73..f878b04076d8 100644
--- a/drivers/staging/rtl8723bs/core/rtw_mlme_ext.c
+++ b/drivers/staging/rtl8723bs/core/rtw_mlme_ext.c
@@ -960,7 +960,7 @@ unsigned int OnAssocReq(struct adapter *padapter, union recv_frame *precv_frame)
return _FAIL;
frame_type = GetFrameSubType(pframe);
- if (frame_type == WIFI_ASSOCREQ)
+ if (frame_type == WIFI_ASSOCREQ)
ie_offset = _ASOCREQ_IE_OFFSET_;
else /* WIFI_REASSOCREQ */
ie_offset = _REASOCREQ_IE_OFFSET_;
diff --git a/drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c b/drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c
index cf35125b7891..cb6d287f580d 100644
--- a/drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c
+++ b/drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c
@@ -366,9 +366,8 @@ void rtw_cfg80211_ibss_indicate_connect(struct adapter *padapter)
int freq = (int)cur_network->network.configuration.ds_config;
struct ieee80211_channel *chan;
- if (pwdev->iftype != NL80211_IFTYPE_ADHOC) {
+ if (pwdev->iftype != NL80211_IFTYPE_ADHOC)
return;
- }
if (!rtw_cfg80211_check_bss(padapter)) {
struct wlan_bssid_ex *pnetwork = &(padapter->mlmeextpriv.mlmext_info.network);
@@ -544,9 +543,8 @@ static int rtw_cfg80211_ap_set_encryption(struct net_device *dev, struct ieee_pa
goto exit;
}
- if (wep_key_len > 0) {
+ if (wep_key_len > 0)
wep_key_len = wep_key_len <= 5 ? 5 : 13;
- }
if (psecuritypriv->bWepDefaultKeyIdxSet == 0) {
/* wep default key has not been set, so use this key index as default key. */
@@ -582,9 +580,8 @@ static int rtw_cfg80211_ap_set_encryption(struct net_device *dev, struct ieee_pa
memcpy(grpkey, param->u.crypt.key, (param->u.crypt.key_len > 16 ? 16 : param->u.crypt.key_len));
psecuritypriv->dot118021XGrpPrivacy = _WEP40_;
- if (param->u.crypt.key_len == 13) {
+ if (param->u.crypt.key_len == 13)
psecuritypriv->dot118021XGrpPrivacy = _WEP104_;
- }
} else if (strcmp(param->u.crypt.alg, "TKIP") == 0) {
psecuritypriv->dot118021XGrpPrivacy = _TKIP_;
@@ -626,24 +623,16 @@ static int rtw_cfg80211_ap_set_encryption(struct net_device *dev, struct ieee_pa
}
- if (psecuritypriv->dot11AuthAlgrthm == dot11AuthAlgrthm_8021X && psta) /* psk/802_1x */
- {
- if (check_fwstate(pmlmepriv, WIFI_AP_STATE))
- {
- if (param->u.crypt.set_tx == 1) /* pairwise key */
- {
+ if (psecuritypriv->dot11AuthAlgrthm == dot11AuthAlgrthm_8021X && psta) { /* psk/802_1x */
+ if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
+ if (param->u.crypt.set_tx == 1) { /* pairwise key */
memcpy(psta->dot118021x_UncstKey.skey, param->u.crypt.key, (param->u.crypt.key_len > 16 ? 16 : param->u.crypt.key_len));
- if (strcmp(param->u.crypt.alg, "WEP") == 0)
- {
+ if (strcmp(param->u.crypt.alg, "WEP") == 0) {
psta->dot118021XPrivacy = _WEP40_;
if (param->u.crypt.key_len == 13)
- {
psta->dot118021XPrivacy = _WEP104_;
- }
- }
- else if (strcmp(param->u.crypt.alg, "TKIP") == 0)
- {
+ } else if (strcmp(param->u.crypt.alg, "TKIP") == 0) {
psta->dot118021XPrivacy = _TKIP_;
/* DEBUG_ERR("set key length :param->u.crypt.key_len =%d\n", param->u.crypt.key_len); */
@@ -653,14 +642,10 @@ static int rtw_cfg80211_ap_set_encryption(struct net_device *dev, struct ieee_pa
psecuritypriv->busetkipkey = true;
- }
- else if (strcmp(param->u.crypt.alg, "CCMP") == 0)
- {
+ } else if (strcmp(param->u.crypt.alg, "CCMP") == 0) {
psta->dot118021XPrivacy = _AES_;
- }
- else
- {
+ } else {
psta->dot118021XPrivacy = _NO_PRIVACY_;
}
@@ -670,21 +655,14 @@ static int rtw_cfg80211_ap_set_encryption(struct net_device *dev, struct ieee_pa
psta->bpairwise_key_installed = true;
- }
- else/* group key??? */
- {
- if (strcmp(param->u.crypt.alg, "WEP") == 0)
- {
+ } else { /* group key??? */
+ if (strcmp(param->u.crypt.alg, "WEP") == 0) {
memcpy(grpkey, param->u.crypt.key, (param->u.crypt.key_len > 16 ? 16 : param->u.crypt.key_len));
psecuritypriv->dot118021XGrpPrivacy = _WEP40_;
if (param->u.crypt.key_len == 13)
- {
psecuritypriv->dot118021XGrpPrivacy = _WEP104_;
- }
- }
- else if (strcmp(param->u.crypt.alg, "TKIP") == 0)
- {
+ } else if (strcmp(param->u.crypt.alg, "TKIP") == 0) {
psecuritypriv->dot118021XGrpPrivacy = _TKIP_;
memcpy(grpkey, param->u.crypt.key, (param->u.crypt.key_len > 16 ? 16 : param->u.crypt.key_len));
@@ -696,15 +674,11 @@ static int rtw_cfg80211_ap_set_encryption(struct net_device *dev, struct ieee_pa
psecuritypriv->busetkipkey = true;
- }
- else if (strcmp(param->u.crypt.alg, "CCMP") == 0)
- {
+ } else if (strcmp(param->u.crypt.alg, "CCMP") == 0) {
psecuritypriv->dot118021XGrpPrivacy = _AES_;
memcpy(grpkey, param->u.crypt.key, (param->u.crypt.key_len > 16 ? 16 : param->u.crypt.key_len));
- }
- else
- {
+ } else {
psecuritypriv->dot118021XGrpPrivacy = _NO_PRIVACY_;
}
@@ -717,8 +691,7 @@ static int rtw_cfg80211_ap_set_encryption(struct net_device *dev, struct ieee_pa
rtw_ap_set_group_key(padapter, param->u.crypt.key, psecuritypriv->dot118021XGrpPrivacy, param->u.crypt.idx);
pbcmc_sta = rtw_get_bcmc_stainfo(padapter);
- if (pbcmc_sta)
- {
+ if (pbcmc_sta) {
pbcmc_sta->ieee8021x_blocked = false;
pbcmc_sta->dot118021XPrivacy = psecuritypriv->dot118021XGrpPrivacy;/* rx will use bmc_sta's dot118021XPrivacy */
}
@@ -746,20 +719,16 @@ static int rtw_cfg80211_set_encryption(struct net_device *dev, struct ieee_param
param->u.crypt.err = 0;
param->u.crypt.alg[IEEE_CRYPT_ALG_NAME_LEN - 1] = '\0';
- if (param_len < (u32) ((u8 *) param->u.crypt.key - (u8 *) param) + param->u.crypt.key_len)
- {
+ if (param_len < (u32) ((u8 *) param->u.crypt.key - (u8 *) param) + param->u.crypt.key_len) {
ret = -EINVAL;
goto exit;
}
if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
- param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff)
- {
+ param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) {
if (param->u.crypt.idx >= WEP_KEYS
- || param->u.crypt.idx >= BIP_MAX_KEYID
- )
- {
+ || param->u.crypt.idx >= BIP_MAX_KEYID) {
ret = -EINVAL;
goto exit;
}
@@ -770,19 +739,16 @@ static int rtw_cfg80211_set_encryption(struct net_device *dev, struct ieee_param
}
}
- if (strcmp(param->u.crypt.alg, "WEP") == 0)
- {
+ if (strcmp(param->u.crypt.alg, "WEP") == 0) {
wep_key_idx = param->u.crypt.idx;
wep_key_len = param->u.crypt.key_len;
- if ((wep_key_idx >= WEP_KEYS) || (wep_key_len <= 0))
- {
+ if ((wep_key_idx >= WEP_KEYS) || (wep_key_len <= 0)) {
ret = -EINVAL;
goto exit;
}
- if (psecuritypriv->bWepDefaultKeyIdxSet == 0)
- {
+ if (psecuritypriv->bWepDefaultKeyIdxSet == 0) {
/* wep default key has not been set, so use this key index as default key. */
wep_key_len = wep_key_len <= 5 ? 5 : 13;
@@ -791,8 +757,7 @@ static int rtw_cfg80211_set_encryption(struct net_device *dev, struct ieee_param
psecuritypriv->dot11PrivacyAlgrthm = _WEP40_;
psecuritypriv->dot118021XGrpPrivacy = _WEP40_;
- if (wep_key_len == 13)
- {
+ if (wep_key_len == 13) {
psecuritypriv->dot11PrivacyAlgrthm = _WEP104_;
psecuritypriv->dot118021XGrpPrivacy = _WEP104_;
}
@@ -809,13 +774,11 @@ static int rtw_cfg80211_set_encryption(struct net_device *dev, struct ieee_param
goto exit;
}
- if (padapter->securitypriv.dot11AuthAlgrthm == dot11AuthAlgrthm_8021X) /* 802_1x */
- {
+ if (padapter->securitypriv.dot11AuthAlgrthm == dot11AuthAlgrthm_8021X) { /* 802_1x */
struct sta_info *psta, *pbcmc_sta;
struct sta_priv *pstapriv = &padapter->stapriv;
- if (check_fwstate(pmlmepriv, WIFI_STATION_STATE | WIFI_MP_STATE) == true) /* sta mode */
- {
+ if (check_fwstate(pmlmepriv, WIFI_STATION_STATE | WIFI_MP_STATE) == true) { /* sta mode */
psta = rtw_get_stainfo(pstapriv, get_bssid(pmlmepriv));
if (psta) {
/* Jeff: don't disable ieee8021x_blocked while clearing key */
@@ -824,18 +787,15 @@ static int rtw_cfg80211_set_encryption(struct net_device *dev, struct ieee_param
if ((padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption2Enabled) ||
- (padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption3Enabled))
- {
+ (padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption3Enabled)) {
psta->dot118021XPrivacy = padapter->securitypriv.dot11PrivacyAlgrthm;
}
- if (param->u.crypt.set_tx == 1)/* pairwise key */
- {
+ if (param->u.crypt.set_tx == 1) { /* pairwise key */
memcpy(psta->dot118021x_UncstKey.skey, param->u.crypt.key, (param->u.crypt.key_len > 16 ? 16 : param->u.crypt.key_len));
- if (strcmp(param->u.crypt.alg, "TKIP") == 0)/* set mic key */
- {
+ if (strcmp(param->u.crypt.alg, "TKIP") == 0) { /* set mic key */
/* DEBUG_ERR(("\nset key length :param->u.crypt.key_len =%d\n", param->u.crypt.key_len)); */
memcpy(psta->dot11tkiptxmickey.skey, &(param->u.crypt.key[16]), 8);
memcpy(psta->dot11tkiprxmickey.skey, &(param->u.crypt.key[24]), 8);
@@ -845,11 +805,8 @@ static int rtw_cfg80211_set_encryption(struct net_device *dev, struct ieee_param
}
rtw_setstakey_cmd(padapter, psta, true, true);
- }
- else/* group key */
- {
- if (strcmp(param->u.crypt.alg, "TKIP") == 0 || strcmp(param->u.crypt.alg, "CCMP") == 0)
- {
+ } else { /* group key */
+ if (strcmp(param->u.crypt.alg, "TKIP") == 0 || strcmp(param->u.crypt.alg, "CCMP") == 0) {
memcpy(padapter->securitypriv.dot118021XGrpKey[param->u.crypt.idx].skey, param->u.crypt.key, (param->u.crypt.key_len > 16 ? 16 : param->u.crypt.key_len));
memcpy(padapter->securitypriv.dot118021XGrptxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[16]), 8);
memcpy(padapter->securitypriv.dot118021XGrprxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[24]), 8);
@@ -857,9 +814,7 @@ static int rtw_cfg80211_set_encryption(struct net_device *dev, struct ieee_param
padapter->securitypriv.dot118021XGrpKeyid = param->u.crypt.idx;
rtw_set_key(padapter, &padapter->securitypriv, param->u.crypt.idx, 1, true);
- }
- else if (strcmp(param->u.crypt.alg, "BIP") == 0)
- {
+ } else if (strcmp(param->u.crypt.alg, "BIP") == 0) {
/* save the IGTK key, length 16 bytes */
memcpy(padapter->securitypriv.dot11wBIPKey[param->u.crypt.idx].skey, param->u.crypt.key, (param->u.crypt.key_len > 16 ? 16 : param->u.crypt.key_len));
/*
@@ -873,25 +828,19 @@ static int rtw_cfg80211_set_encryption(struct net_device *dev, struct ieee_param
}
pbcmc_sta = rtw_get_bcmc_stainfo(padapter);
- if (!pbcmc_sta)
- {
+ if (!pbcmc_sta) {
/* DEBUG_ERR(("Set OID_802_11_ADD_KEY: bcmc stainfo is null\n")); */
- }
- else
- {
+ } else {
/* Jeff: don't disable ieee8021x_blocked while clearing key */
if (strcmp(param->u.crypt.alg, "none") != 0)
pbcmc_sta->ieee8021x_blocked = false;
if ((padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption2Enabled) ||
- (padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption3Enabled))
- {
+ (padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption3Enabled)) {
pbcmc_sta->dot118021XPrivacy = padapter->securitypriv.dot11PrivacyAlgrthm;
}
}
- }
- else if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) /* adhoc mode */
- {
+ } else if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) { /* adhoc mode */
}
}
@@ -949,39 +898,29 @@ static int cfg80211_rtw_add_key(struct wiphy *wiphy, struct net_device *ndev,
if (!mac_addr || is_broadcast_ether_addr(mac_addr))
- {
param->u.crypt.set_tx = 0; /* for wpa/wpa2 group key */
- } else {
+ else
param->u.crypt.set_tx = 1; /* for wpa/wpa2 pairwise key */
- }
param->u.crypt.idx = key_index;
if (params->seq_len && params->seq)
- {
memcpy(param->u.crypt.seq, (u8 *)params->seq, params->seq_len);
- }
- if (params->key_len && params->key)
- {
+ if (params->key_len && params->key) {
param->u.crypt.key_len = params->key_len;
memcpy(param->u.crypt.key, (u8 *)params->key, params->key_len);
}
- if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == true)
- {
+ if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == true) {
ret = rtw_cfg80211_set_encryption(ndev, param, param_len);
- }
- else if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == true)
- {
+ } else if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == true) {
if (mac_addr)
memcpy(param->sta_addr, (void *)mac_addr, ETH_ALEN);
ret = rtw_cfg80211_ap_set_encryption(ndev, param, param_len);
- }
- else if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == true
- || check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == true)
- {
+ } else if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == true
+ || check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == true) {
ret = rtw_cfg80211_set_encryption(ndev, param, param_len);
}
@@ -1007,8 +946,7 @@ static int cfg80211_rtw_del_key(struct wiphy *wiphy, struct net_device *ndev,
struct adapter *padapter = rtw_netdev_priv(ndev);
struct security_priv *psecuritypriv = &padapter->securitypriv;
- if (key_index == psecuritypriv->dot11PrivacyKeyIndex)
- {
+ if (key_index == psecuritypriv->dot11PrivacyKeyIndex) {
/* clear the flag of wep default key set. */
psecuritypriv->bWepDefaultKeyIdxSet = 0;
}
@@ -1024,16 +962,14 @@ static int cfg80211_rtw_set_default_key(struct wiphy *wiphy,
struct adapter *padapter = rtw_netdev_priv(ndev);
struct security_priv *psecuritypriv = &padapter->securitypriv;
- if ((key_index < WEP_KEYS) && ((psecuritypriv->dot11PrivacyAlgrthm == _WEP40_) || (psecuritypriv->dot11PrivacyAlgrthm == _WEP104_))) /* set wep default key */
- {
+ if ((key_index < WEP_KEYS) && ((psecuritypriv->dot11PrivacyAlgrthm == _WEP40_) || (psecuritypriv->dot11PrivacyAlgrthm == _WEP104_))) { /* set wep default key */
psecuritypriv->ndisencryptstatus = Ndis802_11Encryption1Enabled;
psecuritypriv->dot11PrivacyKeyIndex = key_index;
psecuritypriv->dot11PrivacyAlgrthm = _WEP40_;
psecuritypriv->dot118021XGrpPrivacy = _WEP40_;
- if (psecuritypriv->dot11DefKeylen[key_index] == 13)
- {
+ if (psecuritypriv->dot11DefKeylen[key_index] == 13) {
psecuritypriv->dot11PrivacyAlgrthm = _WEP104_;
psecuritypriv->dot118021XGrpPrivacy = _WEP104_;
}
@@ -1071,9 +1007,7 @@ static int cfg80211_rtw_get_station(struct wiphy *wiphy,
/* for infra./P2PClient mode */
if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)
- && check_fwstate(pmlmepriv, _FW_LINKED)
- )
- {
+ && check_fwstate(pmlmepriv, _FW_LINKED)) {
struct wlan_network *cur_network = &(pmlmepriv->cur_network);
if (memcmp((u8 *)mac, cur_network->network.mac_address, ETH_ALEN)) {
@@ -1099,9 +1033,7 @@ static int cfg80211_rtw_get_station(struct wiphy *wiphy,
if ((check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)
|| check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)
|| check_fwstate(pmlmepriv, WIFI_AP_STATE))
- && check_fwstate(pmlmepriv, _FW_LINKED)
- )
- {
+ && check_fwstate(pmlmepriv, _FW_LINKED)) {
/* TODO: should acquire station info... */
}
@@ -1121,8 +1053,7 @@ static int cfg80211_rtw_change_iface(struct wiphy *wiphy,
struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
int ret = 0;
- if (adapter_to_dvobj(padapter)->processing_dev_remove == true)
- {
+ if (adapter_to_dvobj(padapter)->processing_dev_remove == true) {
ret = -EPERM;
goto exit;
}
@@ -1141,8 +1072,7 @@ static int cfg80211_rtw_change_iface(struct wiphy *wiphy,
old_type = rtw_wdev->iftype;
- if (old_type != type)
- {
+ if (old_type != type) {
pmlmeext->action_public_rxseq = 0xffff;
pmlmeext->action_public_dialog_token = 0xff;
}
@@ -1164,8 +1094,7 @@ static int cfg80211_rtw_change_iface(struct wiphy *wiphy,
rtw_wdev->iftype = type;
- if (rtw_set_802_11_infrastructure_mode(padapter, networkType) == false)
- {
+ if (rtw_set_802_11_infrastructure_mode(padapter, networkType) == false) {
rtw_wdev->iftype = old_type;
ret = -EPERM;
goto exit;
@@ -1230,9 +1159,7 @@ void rtw_cfg80211_surveydone_event_callback(struct adapter *padapter)
/* report network only if the current channel set contains the channel to which this network belongs */
if (rtw_ch_set_search_ch(padapter->mlmeextpriv.channel_set, pnetwork->network.configuration.ds_config) >= 0
- && true == rtw_validate_ssid(&(pnetwork->network.ssid))
- )
- {
+ && true == rtw_validate_ssid(&(pnetwork->network.ssid))) {
/* ev =translate_scan(padapter, a, pnetwork, ev, stop); */
rtw_cfg80211_inform_bss(padapter, pnetwork);
}
@@ -1249,13 +1176,10 @@ static int rtw_cfg80211_set_probe_req_wpsp2pie(struct adapter *padapter, char *b
u8 *wps_ie;
struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
- if (len > 0)
- {
+ if (len > 0) {
wps_ie = rtw_get_wps_ie(buf, len, NULL, &wps_ielen);
- if (wps_ie)
- {
- if (pmlmepriv->wps_probe_req_ie)
- {
+ if (wps_ie) {
+ if (pmlmepriv->wps_probe_req_ie) {
pmlmepriv->wps_probe_req_ie_len = 0;
kfree(pmlmepriv->wps_probe_req_ie);
pmlmepriv->wps_probe_req_ie = NULL;
@@ -1307,10 +1231,8 @@ static int cfg80211_rtw_scan(struct wiphy *wiphy
pwdev_priv->scan_request = request;
spin_unlock_bh(&pwdev_priv->scan_req_lock);
- if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == true)
- {
- if (check_fwstate(pmlmepriv, WIFI_UNDER_WPS|_FW_UNDER_SURVEY|_FW_UNDER_LINKING) == true)
- {
+ if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == true) {
+ if (check_fwstate(pmlmepriv, WIFI_UNDER_WPS|_FW_UNDER_SURVEY|_FW_UNDER_LINKING) == true) {
need_indicate_scan_done = true;
goto check_need_indicate_scan_done;
}
@@ -1333,15 +1255,13 @@ static int cfg80211_rtw_scan(struct wiphy *wiphy
goto check_need_indicate_scan_done;
}
- if (pmlmepriv->LinkDetectInfo.bBusyTraffic == true)
- {
- static unsigned long lastscantime = 0;
+ if (pmlmepriv->LinkDetectInfo.bBusyTraffic == true) {
+ static unsigned long lastscantime;
unsigned long passtime;
passtime = jiffies_to_msecs(jiffies - lastscantime);
lastscantime = jiffies;
- if (passtime > 12000)
- {
+ if (passtime > 12000) {
need_indicate_scan_done = true;
goto check_need_indicate_scan_done;
}
@@ -1380,9 +1300,7 @@ static int cfg80211_rtw_scan(struct wiphy *wiphy
} else if (request->n_channels <= 4) {
for (j = request->n_channels - 1; j >= 0; j--)
for (i = 0; i < survey_times; i++)
- {
memcpy(&ch[j*survey_times+i], &ch[j], sizeof(struct rtw_ieee80211_channel));
- }
_status = rtw_sitesurvey_cmd(padapter, ssid, RTW_SSID_SCAN_AMOUNT, ch, survey_times * request->n_channels);
} else {
_status = rtw_sitesurvey_cmd(padapter, ssid, RTW_SSID_SCAN_AMOUNT, NULL, 0);
@@ -1391,14 +1309,11 @@ static int cfg80211_rtw_scan(struct wiphy *wiphy
if (_status == false)
- {
ret = -1;
- }
check_need_indicate_scan_done:
kfree(ssid);
- if (need_indicate_scan_done)
- {
+ if (need_indicate_scan_done) {
rtw_cfg80211_surveydone_event_callback(padapter);
rtw_cfg80211_indicate_scan_done(padapter, false);
}
@@ -1424,9 +1339,7 @@ static int rtw_cfg80211_set_wpa_version(struct security_priv *psecuritypriv, u32
if (wpa_version & (NL80211_WPA_VERSION_1 | NL80211_WPA_VERSION_2))
- {
psecuritypriv->ndisauthtype = Ndis802_11AuthModeWPAPSK;
- }
return 0;
@@ -1585,8 +1498,7 @@ static int rtw_cfg80211_set_wpa_ie(struct adapter *padapter, u8 *pie, size_t iel
if (pairwise_cipher == 0)
pairwise_cipher = WPA_CIPHER_NONE;
- switch (group_cipher)
- {
+ switch (group_cipher) {
case WPA_CIPHER_NONE:
padapter->securitypriv.dot118021XGrpPrivacy = _NO_PRIVACY_;
padapter->securitypriv.ndisencryptstatus = Ndis802_11EncryptionDisabled;
@@ -1609,8 +1521,7 @@ static int rtw_cfg80211_set_wpa_ie(struct adapter *padapter, u8 *pie, size_t iel
break;
}
- switch (pairwise_cipher)
- {
+ switch (pairwise_cipher) {
case WPA_CIPHER_NONE:
padapter->securitypriv.dot11PrivacyAlgrthm = _NO_PRIVACY_;
padapter->securitypriv.ndisencryptstatus = Ndis802_11EncryptionDisabled;
@@ -1731,8 +1642,7 @@ static int cfg80211_rtw_leave_ibss(struct wiphy *wiphy, struct net_device *ndev)
rtw_wdev->iftype = NL80211_IFTYPE_STATION;
- if (rtw_set_802_11_infrastructure_mode(padapter, Ndis802_11Infrastructure) == false)
- {
+ if (rtw_set_802_11_infrastructure_mode(padapter, Ndis802_11Infrastructure) == false) {
rtw_wdev->iftype = old_type;
ret = -EPERM;
goto leave_ibss;
@@ -1792,9 +1702,8 @@ static int cfg80211_rtw_connect(struct wiphy *wiphy, struct net_device *ndev,
ret = -EBUSY;
goto exit;
}
- if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == true) {
+ if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == true)
rtw_scan_abort(padapter);
- }
psecuritypriv->ndisencryptstatus = Ndis802_11EncryptionDisabled;
psecuritypriv->dot11PrivacyAlgrthm = _NO_PRIVACY_;
@@ -2288,9 +2197,8 @@ static int rtw_cfg80211_add_monitor_if(struct adapter *padapter, char *name, str
mon_ndev->ieee80211_ptr = mon_wdev;
ret = cfg80211_register_netdevice(mon_ndev);
- if (ret) {
+ if (ret)
goto out;
- }
*ndev = pwdev_priv->pmon_ndev = mon_ndev;
memcpy(pwdev_priv->ifname_mon, name, IFNAMSIZ+1);
@@ -2403,11 +2311,10 @@ static int rtw_add_beacon(struct adapter *adapter, const u8 *head, size_t head_l
rtw_ies_remove_ie(pbuf, &len, _BEACON_IE_OFFSET_, WLAN_EID_VENDOR_SPECIFIC, P2P_OUI, 4);
rtw_ies_remove_ie(pbuf, &len, _BEACON_IE_OFFSET_, WLAN_EID_VENDOR_SPECIFIC, WFD_OUI, 4);
- if (rtw_check_beacon_data(adapter, pbuf, len) == _SUCCESS) {
+ if (rtw_check_beacon_data(adapter, pbuf, len) == _SUCCESS)
ret = 0;
- } else {
+ else
ret = -EINVAL;
- }
kfree(pbuf);
diff --git a/drivers/staging/rts5208/spi.c b/drivers/staging/rts5208/spi.c
index f1e9e80044ed..e88fe1a998f8 100644
--- a/drivers/staging/rts5208/spi.c
+++ b/drivers/staging/rts5208/spi.c
@@ -460,10 +460,8 @@ int spi_set_parameter(struct scsi_cmnd *srb, struct rtsx_chip *chip)
spi->clk_div = ((u16)(srb->cmnd[4]) << 8) | srb->cmnd[5];
spi->write_en = srb->cmnd[6];
- dev_dbg(rtsx_dev(chip), "%s: ", __func__);
- dev_dbg(rtsx_dev(chip), "spi_clock = %d, ", spi->spi_clock);
- dev_dbg(rtsx_dev(chip), "clk_div = %d, ", spi->clk_div);
- dev_dbg(rtsx_dev(chip), "write_en = %d\n", spi->write_en);
+ dev_dbg(rtsx_dev(chip), "spi_clock = %d, clk_div = %d, write_en = %d\n",
+ spi->spi_clock, spi->clk_div, spi->write_en);
return STATUS_SUCCESS;
}
diff --git a/drivers/staging/sm750fb/ddk750_dvi.c b/drivers/staging/sm750fb/ddk750_dvi.c
index 029d9acec47d..e0c7ff3352bf 100644
--- a/drivers/staging/sm750fb/ddk750_dvi.c
+++ b/drivers/staging/sm750fb/ddk750_dvi.c
@@ -15,7 +15,7 @@ static struct dvi_ctrl_device dcft_supported_dvi_controller[] = {
#ifdef DVI_CTRL_SII164
{
.init = sii164InitChip,
- .get_vendor_id = sii164GetVendorID,
+ .get_vendor_id = sii164_get_vendor_id,
.get_device_id = sii164GetDeviceID,
#ifdef SII164_FULL_FUNCTIONS
.reset_chip = sii164ResetChip,
diff --git a/drivers/staging/sm750fb/ddk750_power.h b/drivers/staging/sm750fb/ddk750_power.h
index 7002567a47d2..63c9e8b6ffb3 100644
--- a/drivers/staging/sm750fb/ddk750_power.h
+++ b/drivers/staging/sm750fb/ddk750_power.h
@@ -15,7 +15,7 @@ enum dpms {
}
void ddk750_set_dpms(enum dpms state);
-void sm750_set_power_mode(unsigned int powerMode);
+void sm750_set_power_mode(unsigned int mode);
void sm750_set_current_gate(unsigned int gate);
/*
diff --git a/drivers/staging/sm750fb/ddk750_sii164.c b/drivers/staging/sm750fb/ddk750_sii164.c
index 73e0e9f41ec5..3da1796cd7aa 100644
--- a/drivers/staging/sm750fb/ddk750_sii164.c
+++ b/drivers/staging/sm750fb/ddk750_sii164.c
@@ -29,13 +29,13 @@ static char *gDviCtrlChipName = "Silicon Image SiI 164";
#endif
/*
- * sii164GetVendorID
+ * sii164_get_vendor_id
* This function gets the vendor ID of the DVI controller chip.
*
* Output:
* Vendor ID
*/
-unsigned short sii164GetVendorID(void)
+unsigned short sii164_get_vendor_id(void)
{
unsigned short vendorID;
@@ -140,7 +140,7 @@ long sii164InitChip(unsigned char edge_select,
#endif
/* Check if SII164 Chip exists */
- if ((sii164GetVendorID() == SII164_VENDOR_ID) &&
+ if ((sii164_get_vendor_id() == SII164_VENDOR_ID) &&
(sii164GetDeviceID() == SII164_DEVICE_ID)) {
/*
* Initialize SII164 controller chip.
diff --git a/drivers/staging/sm750fb/ddk750_sii164.h b/drivers/staging/sm750fb/ddk750_sii164.h
index d940cb729066..ca330f6a43e2 100644
--- a/drivers/staging/sm750fb/ddk750_sii164.h
+++ b/drivers/staging/sm750fb/ddk750_sii164.h
@@ -27,7 +27,7 @@ long sii164InitChip(unsigned char edgeSelect,
unsigned char pllFilterEnable,
unsigned char pllFilterValue);
-unsigned short sii164GetVendorID(void);
+unsigned short sii164_get_vendor_id(void);
unsigned short sii164GetDeviceID(void);
#ifdef SII164_FULL_FUNCTIONS
diff --git a/drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c b/drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c
index e429b33b4d39..f4c2c9506d86 100644
--- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c
+++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c
@@ -25,12 +25,14 @@ MODULE_PARM_DESC(force_bulk, "Force use of vchiq bulk for audio");
static void bcm2835_audio_lock(struct bcm2835_audio_instance *instance)
{
mutex_lock(&instance->vchi_mutex);
- vchiq_use_service(instance->service_handle);
+ vchiq_use_service(instance->alsa_stream->chip->vchi_ctx->instance,
+ instance->service_handle);
}
static void bcm2835_audio_unlock(struct bcm2835_audio_instance *instance)
{
- vchiq_release_service(instance->service_handle);
+ vchiq_release_service(instance->alsa_stream->chip->vchi_ctx->instance,
+ instance->service_handle);
mutex_unlock(&instance->vchi_mutex);
}
@@ -44,8 +46,8 @@ static int bcm2835_audio_send_msg_locked(struct bcm2835_audio_instance *instance
init_completion(&instance->msg_avail_comp);
}
- status = vchiq_queue_kernel_message(instance->service_handle,
- m, sizeof(*m));
+ status = vchiq_queue_kernel_message(instance->alsa_stream->chip->vchi_ctx->instance,
+ instance->service_handle, m, sizeof(*m));
if (status) {
dev_err(instance->dev,
"vchi message queue failed: %d, msg=%d\n",
@@ -89,11 +91,13 @@ static int bcm2835_audio_send_simple(struct bcm2835_audio_instance *instance,
return bcm2835_audio_send_msg(instance, &m, wait);
}
-static enum vchiq_status audio_vchi_callback(enum vchiq_reason reason,
+static enum vchiq_status audio_vchi_callback(struct vchiq_instance *vchiq_instance,
+ enum vchiq_reason reason,
struct vchiq_header *header,
unsigned int handle, void *userdata)
{
- struct bcm2835_audio_instance *instance = vchiq_get_service_userdata(handle);
+ struct bcm2835_audio_instance *instance = vchiq_get_service_userdata(vchiq_instance,
+ handle);
struct vc_audio_msg *m;
if (reason != VCHIQ_MESSAGE_AVAILABLE)
@@ -114,7 +118,7 @@ static enum vchiq_status audio_vchi_callback(enum vchiq_reason reason,
dev_err(instance->dev, "unexpected callback type=%d\n", m->type);
}
- vchiq_release_message(handle, header);
+ vchiq_release_message(vchiq_instance, instance->service_handle, header);
return VCHIQ_SUCCESS;
}
@@ -143,7 +147,8 @@ vc_vchi_audio_init(struct vchiq_instance *vchiq_instance,
}
/* Finished with the service for now */
- vchiq_release_service(instance->service_handle);
+ vchiq_release_service(instance->alsa_stream->chip->vchi_ctx->instance,
+ instance->service_handle);
return 0;
}
@@ -153,10 +158,12 @@ static void vc_vchi_audio_deinit(struct bcm2835_audio_instance *instance)
int status;
mutex_lock(&instance->vchi_mutex);
- vchiq_use_service(instance->service_handle);
+ vchiq_use_service(instance->alsa_stream->chip->vchi_ctx->instance,
+ instance->service_handle);
/* Close all VCHI service connections */
- status = vchiq_close_service(instance->service_handle);
+ status = vchiq_close_service(instance->alsa_stream->chip->vchi_ctx->instance,
+ instance->service_handle);
if (status) {
dev_err(instance->dev,
"failed to close VCHI service connection (status=%d)\n",
@@ -226,7 +233,7 @@ int bcm2835_audio_open(struct bcm2835_alsa_stream *alsa_stream)
goto deinit;
bcm2835_audio_lock(instance);
- vchiq_get_peer_version(instance->service_handle,
+ vchiq_get_peer_version(vchi_ctx->instance, instance->service_handle,
&instance->peer_version);
bcm2835_audio_unlock(instance);
if (instance->peer_version < 2 || force_bulk)
@@ -322,6 +329,8 @@ int bcm2835_audio_write(struct bcm2835_alsa_stream *alsa_stream,
unsigned int size, void *src)
{
struct bcm2835_audio_instance *instance = alsa_stream->instance;
+ struct bcm2835_vchi_ctx *vchi_ctx = alsa_stream->chip->vchi_ctx;
+ struct vchiq_instance *vchiq_instance = vchi_ctx->instance;
struct vc_audio_msg m = {
.type = VC_AUDIO_MSG_TYPE_WRITE,
.write.count = size,
@@ -343,15 +352,14 @@ int bcm2835_audio_write(struct bcm2835_alsa_stream *alsa_stream,
count = size;
if (!instance->max_packet) {
/* Send the message to the videocore */
- status = vchiq_bulk_transmit(instance->service_handle, src,
- count, NULL,
- VCHIQ_BULK_MODE_BLOCKING);
+ status = vchiq_bulk_transmit(vchiq_instance, instance->service_handle, src, count,
+ NULL, VCHIQ_BULK_MODE_BLOCKING);
} else {
while (count > 0) {
int bytes = min(instance->max_packet, count);
- status = vchiq_queue_kernel_message(instance->service_handle,
- src, bytes);
+ status = vchiq_queue_kernel_message(vchiq_instance,
+ instance->service_handle, src, bytes);
src += bytes;
count -= bytes;
}
diff --git a/drivers/staging/vc04_services/include/linux/raspberrypi/vchiq.h b/drivers/staging/vc04_services/include/linux/raspberrypi/vchiq.h
index c93f2f3e87bb..db1441c0cc66 100644
--- a/drivers/staging/vc04_services/include/linux/raspberrypi/vchiq.h
+++ b/drivers/staging/vc04_services/include/linux/raspberrypi/vchiq.h
@@ -53,9 +53,12 @@ struct vchiq_element {
unsigned int size;
};
+struct vchiq_instance;
+
struct vchiq_service_base {
int fourcc;
- enum vchiq_status (*callback)(enum vchiq_reason reason,
+ enum vchiq_status (*callback)(struct vchiq_instance *instance,
+ enum vchiq_reason reason,
struct vchiq_header *header,
unsigned int handle,
void *bulk_userdata);
@@ -71,7 +74,8 @@ struct vchiq_completion_data_kernel {
struct vchiq_service_params_kernel {
int fourcc;
- enum vchiq_status (*callback)(enum vchiq_reason reason,
+ enum vchiq_status (*callback)(struct vchiq_instance *instance,
+ enum vchiq_reason reason,
struct vchiq_header *header,
unsigned int handle,
void *bulk_userdata);
@@ -88,23 +92,27 @@ extern enum vchiq_status vchiq_connect(struct vchiq_instance *instance);
extern enum vchiq_status vchiq_open_service(struct vchiq_instance *instance,
const struct vchiq_service_params_kernel *params,
unsigned int *pservice);
-extern enum vchiq_status vchiq_close_service(unsigned int service);
-extern enum vchiq_status vchiq_use_service(unsigned int service);
-extern enum vchiq_status vchiq_release_service(unsigned int service);
-extern void vchiq_msg_queue_push(unsigned int handle, struct vchiq_header *header);
-extern void vchiq_release_message(unsigned int service,
- struct vchiq_header *header);
-extern int vchiq_queue_kernel_message(unsigned int handle, void *data,
- unsigned int size);
-extern enum vchiq_status vchiq_bulk_transmit(unsigned int service,
- const void *data, unsigned int size, void *userdata,
- enum vchiq_bulk_mode mode);
-extern enum vchiq_status vchiq_bulk_receive(unsigned int service,
- void *data, unsigned int size, void *userdata,
- enum vchiq_bulk_mode mode);
-extern void *vchiq_get_service_userdata(unsigned int service);
-extern enum vchiq_status vchiq_get_peer_version(unsigned int handle,
- short *peer_version);
-extern struct vchiq_header *vchiq_msg_hold(unsigned int handle);
+extern enum vchiq_status vchiq_close_service(struct vchiq_instance *instance,
+ unsigned int service);
+extern enum vchiq_status vchiq_use_service(struct vchiq_instance *instance, unsigned int service);
+extern enum vchiq_status vchiq_release_service(struct vchiq_instance *instance,
+ unsigned int service);
+extern void vchiq_msg_queue_push(struct vchiq_instance *instance, unsigned int handle,
+ struct vchiq_header *header);
+extern void vchiq_release_message(struct vchiq_instance *instance, unsigned int service,
+ struct vchiq_header *header);
+extern int vchiq_queue_kernel_message(struct vchiq_instance *instance, unsigned int handle,
+ void *data, unsigned int size);
+extern enum vchiq_status vchiq_bulk_transmit(struct vchiq_instance *instance, unsigned int service,
+ const void *data, unsigned int size, void *userdata,
+ enum vchiq_bulk_mode mode);
+extern enum vchiq_status vchiq_bulk_receive(struct vchiq_instance *instance, unsigned int service,
+ void *data, unsigned int size, void *userdata,
+ enum vchiq_bulk_mode mode);
+extern void *vchiq_get_service_userdata(struct vchiq_instance *instance, unsigned int service);
+extern enum vchiq_status vchiq_get_peer_version(struct vchiq_instance *instance,
+ unsigned int handle,
+ short *peer_version);
+extern struct vchiq_header *vchiq_msg_hold(struct vchiq_instance *instance, unsigned int handle);
#endif /* VCHIQ_H */
diff --git a/drivers/staging/vc04_services/interface/TESTING b/drivers/staging/vc04_services/interface/TESTING
new file mode 100644
index 000000000000..a6d63efcbcb9
--- /dev/null
+++ b/drivers/staging/vc04_services/interface/TESTING
@@ -0,0 +1,82 @@
+This document contains some hints to test the function of the VCHIQ driver
+without having additional hardware to the Raspberry Pi.
+
+* Requirements & limitations
+
+Testing the VCHIQ driver requires a Raspberry Pi with one of the following SoC:
+ - BCM2835 ( e.g. Raspberry Pi Zero W )
+ - BCM2836 ( e.g. Raspberry Pi 2 )
+ - BCM2837 ( e.g. Raspberry Pi 3 B+ )
+
+The BCM2711 used in the Raspberry Pi 4 is currently not supported in the
+mainline kernel.
+
+There are no specific requirements to the VideoCore firmware to get VCHIQ
+working.
+
+The test scenarios described in this document based on the tool vchiq_test.
+Its source code is available here: https://github.com/raspberrypi/userland
+
+* Configuration
+
+Here are the most common kernel configurations:
+
+ 1. BCM2835 target SoC (ARM 32 bit)
+
+ Just use bcm2835_defconfig which already has VCHIQ enabled.
+
+ 2. BCM2836/7 target SoC (ARM 32 bit)
+
+ Use the multi_v7_defconfig as a base and then enable all VCHIQ options.
+
+ 3. BCM2837 target SoC (ARM 64 bit)
+
+ Use the defconfig as a base and then enable all VCHIQ options.
+
+* Scenarios
+
+ * Initial test
+
+ Check the driver is probed and /dev/vchiq is created
+
+ * Functional test
+
+ Command: vchiq_test -f 10
+
+ Expected output:
+ Functional test - iters:10
+ ======== iteration 1 ========
+ Testing bulk transfer for alignment.
+ Testing bulk transfer at PAGE_SIZE.
+ ...
+
+ * Ping test
+
+ Command: vchiq_test -p 1
+
+ Expected output:
+ Ping test - service:echo, iters:1, version 3
+ vchi ping (size 0) -> 57.000000us
+ vchi ping (size 0, 0 async, 0 oneway) -> 122.000000us
+ vchi bulk (size 0, 0 async, 0 oneway) -> 546.000000us
+ vchi bulk (size 0, 0 oneway) -> 230.000000us
+ vchi ping (size 0) -> 49.000000us
+ vchi ping (size 0, 0 async, 0 oneway) -> 70.000000us
+ vchi bulk (size 0, 0 async, 0 oneway) -> 296.000000us
+ vchi bulk (size 0, 0 oneway) -> 266.000000us
+ vchi ping (size 0, 1 async, 0 oneway) -> 65.000000us
+ vchi bulk (size 0, 0 oneway) -> 456.000000us
+ vchi ping (size 0, 2 async, 0 oneway) -> 74.000000us
+ vchi bulk (size 0, 0 oneway) -> 640.000000us
+ vchi ping (size 0, 10 async, 0 oneway) -> 125.000000us
+ vchi bulk (size 0, 0 oneway) -> 2309.000000us
+ vchi ping (size 0, 0 async, 1 oneway) -> 70.000000us
+ vchi ping (size 0, 0 async, 2 oneway) -> 76.000000us
+ vchi ping (size 0, 0 async, 10 oneway) -> 105.000000us
+ vchi ping (size 0, 10 async, 10 oneway) -> 165.000000us
+ vchi ping (size 0, 100 async, 0 oneway) -> nanus
+ vchi bulk (size 0, 0 oneway) -> nanus
+ vchi ping (size 0, 0 async, 100 oneway) -> nanus
+ vchi ping (size 0, 100 async, 100 oneway) -> infus
+ vchi ping (size 0, 200 async, 0 oneway) -> infus
+ ...
diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c
index 0596ac61e286..dc33490ba7fb 100644
--- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c
+++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c
@@ -148,12 +148,11 @@ static unsigned int g_fragments_size;
static char *g_fragments_base;
static char *g_free_fragments;
static struct semaphore g_free_fragments_sema;
-static struct device *g_dev;
static DEFINE_SEMAPHORE(g_free_fragments_mutex);
static enum vchiq_status
-vchiq_blocking_bulk_transfer(unsigned int handle, void *data,
+vchiq_blocking_bulk_transfer(struct vchiq_instance *instance, unsigned int handle, void *data,
unsigned int size, enum vchiq_bulk_dir dir);
static irqreturn_t
@@ -175,17 +174,17 @@ vchiq_doorbell_irq(int irq, void *dev_id)
}
static void
-cleanup_pagelistinfo(struct vchiq_pagelist_info *pagelistinfo)
+cleanup_pagelistinfo(struct vchiq_instance *instance, struct vchiq_pagelist_info *pagelistinfo)
{
if (pagelistinfo->scatterlist_mapped) {
- dma_unmap_sg(g_dev, pagelistinfo->scatterlist,
+ dma_unmap_sg(instance->state->dev, pagelistinfo->scatterlist,
pagelistinfo->num_pages, pagelistinfo->dma_dir);
}
if (pagelistinfo->pages_need_release)
unpin_user_pages(pagelistinfo->pages, pagelistinfo->num_pages);
- dma_free_coherent(g_dev, pagelistinfo->pagelist_buffer_size,
+ dma_free_coherent(instance->state->dev, pagelistinfo->pagelist_buffer_size,
pagelistinfo->pagelist, pagelistinfo->dma_addr);
}
@@ -212,7 +211,7 @@ is_adjacent_block(u32 *addrs, u32 addr, unsigned int k)
*/
static struct vchiq_pagelist_info *
-create_pagelist(char *buf, char __user *ubuf,
+create_pagelist(struct vchiq_instance *instance, char *buf, char __user *ubuf,
size_t count, unsigned short type)
{
struct pagelist *pagelist;
@@ -250,7 +249,7 @@ create_pagelist(char *buf, char __user *ubuf,
/* Allocate enough storage to hold the page pointers and the page
* list
*/
- pagelist = dma_alloc_coherent(g_dev, pagelist_size, &dma_addr,
+ pagelist = dma_alloc_coherent(instance->state->dev, pagelist_size, &dma_addr,
GFP_KERNEL);
vchiq_log_trace(vchiq_arm_log_level, "%s - %pK", __func__, pagelist);
@@ -292,7 +291,7 @@ create_pagelist(char *buf, char __user *ubuf,
size_t bytes = PAGE_SIZE - off;
if (!pg) {
- cleanup_pagelistinfo(pagelistinfo);
+ cleanup_pagelistinfo(instance, pagelistinfo);
return NULL;
}
@@ -315,7 +314,7 @@ create_pagelist(char *buf, char __user *ubuf,
/* This is probably due to the process being killed */
if (actual_pages > 0)
unpin_user_pages(pages, actual_pages);
- cleanup_pagelistinfo(pagelistinfo);
+ cleanup_pagelistinfo(instance, pagelistinfo);
return NULL;
}
/* release user pages */
@@ -338,13 +337,13 @@ create_pagelist(char *buf, char __user *ubuf,
count -= len;
}
- dma_buffers = dma_map_sg(g_dev,
+ dma_buffers = dma_map_sg(instance->state->dev,
scatterlist,
num_pages,
pagelistinfo->dma_dir);
if (dma_buffers == 0) {
- cleanup_pagelistinfo(pagelistinfo);
+ cleanup_pagelistinfo(instance, pagelistinfo);
return NULL;
}
@@ -378,7 +377,7 @@ create_pagelist(char *buf, char __user *ubuf,
char *fragments;
if (down_interruptible(&g_free_fragments_sema)) {
- cleanup_pagelistinfo(pagelistinfo);
+ cleanup_pagelistinfo(instance, pagelistinfo);
return NULL;
}
@@ -397,7 +396,7 @@ create_pagelist(char *buf, char __user *ubuf,
}
static void
-free_pagelist(struct vchiq_pagelist_info *pagelistinfo,
+free_pagelist(struct vchiq_instance *instance, struct vchiq_pagelist_info *pagelistinfo,
int actual)
{
struct pagelist *pagelist = pagelistinfo->pagelist;
@@ -411,7 +410,7 @@ free_pagelist(struct vchiq_pagelist_info *pagelistinfo,
* NOTE: dma_unmap_sg must be called before the
* cpu can touch any of the data/pages.
*/
- dma_unmap_sg(g_dev, pagelistinfo->scatterlist,
+ dma_unmap_sg(instance->state->dev, pagelistinfo->scatterlist,
pagelistinfo->num_pages, pagelistinfo->dma_dir);
pagelistinfo->scatterlist_mapped = 0;
@@ -460,7 +459,7 @@ free_pagelist(struct vchiq_pagelist_info *pagelistinfo,
set_page_dirty(pages[i]);
}
- cleanup_pagelistinfo(pagelistinfo);
+ cleanup_pagelistinfo(instance, pagelistinfo);
}
int vchiq_platform_init(struct platform_device *pdev, struct vchiq_state *state)
@@ -519,7 +518,7 @@ int vchiq_platform_init(struct platform_device *pdev, struct vchiq_state *state)
*(char **)&g_fragments_base[i * g_fragments_size] = NULL;
sema_init(&g_free_fragments_sema, MAX_FRAGMENTS);
- err = vchiq_init_state(state, vchiq_slot_zero);
+ err = vchiq_init_state(state, vchiq_slot_zero, dev);
if (err)
return err;
@@ -547,7 +546,6 @@ int vchiq_platform_init(struct platform_device *pdev, struct vchiq_state *state)
return err ? : -ENXIO;
}
- g_dev = dev;
vchiq_log_info(vchiq_arm_log_level, "vchiq_init - done (slots %pK, phys %pad)",
vchiq_slot_zero, &slot_phys);
@@ -604,6 +602,10 @@ static struct vchiq_arm_state *vchiq_platform_get_arm_state(struct vchiq_state *
void
remote_event_signal(struct remote_event *event)
{
+ /*
+ * Ensure that all writes to shared data structures have completed
+ * before signalling the peer.
+ */
wmb();
event->fired = 1;
@@ -615,12 +617,12 @@ remote_event_signal(struct remote_event *event)
}
int
-vchiq_prepare_bulk_data(struct vchiq_bulk *bulk, void *offset,
+vchiq_prepare_bulk_data(struct vchiq_instance *instance, struct vchiq_bulk *bulk, void *offset,
void __user *uoffset, int size, int dir)
{
struct vchiq_pagelist_info *pagelistinfo;
- pagelistinfo = create_pagelist(offset, uoffset, size,
+ pagelistinfo = create_pagelist(instance, offset, uoffset, size,
(dir == VCHIQ_BULK_RECEIVE)
? PAGELIST_READ
: PAGELIST_WRITE);
@@ -640,10 +642,10 @@ vchiq_prepare_bulk_data(struct vchiq_bulk *bulk, void *offset,
}
void
-vchiq_complete_bulk(struct vchiq_bulk *bulk)
+vchiq_complete_bulk(struct vchiq_instance *instance, struct vchiq_bulk *bulk)
{
if (bulk && bulk->remote_data && bulk->actual)
- free_pagelist((struct vchiq_pagelist_info *)bulk->remote_data,
+ free_pagelist(instance, (struct vchiq_pagelist_info *)bulk->remote_data,
bulk->actual);
}
@@ -821,7 +823,7 @@ vchiq_open_service(struct vchiq_instance *instance,
*phandle = service->handle;
status = vchiq_open_service_internal(service, current->pid);
if (status != VCHIQ_SUCCESS) {
- vchiq_remove_service(service->handle);
+ vchiq_remove_service(instance, service->handle);
*phandle = VCHIQ_SERVICE_HANDLE_INVALID;
}
}
@@ -834,8 +836,8 @@ failed:
EXPORT_SYMBOL(vchiq_open_service);
enum vchiq_status
-vchiq_bulk_transmit(unsigned int handle, const void *data, unsigned int size,
- void *userdata, enum vchiq_bulk_mode mode)
+vchiq_bulk_transmit(struct vchiq_instance *instance, unsigned int handle, const void *data,
+ unsigned int size, void *userdata, enum vchiq_bulk_mode mode)
{
enum vchiq_status status;
@@ -843,13 +845,13 @@ vchiq_bulk_transmit(unsigned int handle, const void *data, unsigned int size,
switch (mode) {
case VCHIQ_BULK_MODE_NOCALLBACK:
case VCHIQ_BULK_MODE_CALLBACK:
- status = vchiq_bulk_transfer(handle,
+ status = vchiq_bulk_transfer(instance, handle,
(void *)data, NULL,
size, userdata, mode,
VCHIQ_BULK_TRANSMIT);
break;
case VCHIQ_BULK_MODE_BLOCKING:
- status = vchiq_blocking_bulk_transfer(handle, (void *)data, size,
+ status = vchiq_blocking_bulk_transfer(instance, handle, (void *)data, size,
VCHIQ_BULK_TRANSMIT);
break;
default:
@@ -871,8 +873,8 @@ vchiq_bulk_transmit(unsigned int handle, const void *data, unsigned int size,
}
EXPORT_SYMBOL(vchiq_bulk_transmit);
-enum vchiq_status vchiq_bulk_receive(unsigned int handle, void *data,
- unsigned int size, void *userdata,
+enum vchiq_status vchiq_bulk_receive(struct vchiq_instance *instance, unsigned int handle,
+ void *data, unsigned int size, void *userdata,
enum vchiq_bulk_mode mode)
{
enum vchiq_status status;
@@ -881,12 +883,12 @@ enum vchiq_status vchiq_bulk_receive(unsigned int handle, void *data,
switch (mode) {
case VCHIQ_BULK_MODE_NOCALLBACK:
case VCHIQ_BULK_MODE_CALLBACK:
- status = vchiq_bulk_transfer(handle, data, NULL,
+ status = vchiq_bulk_transfer(instance, handle, data, NULL,
size, userdata,
mode, VCHIQ_BULK_RECEIVE);
break;
case VCHIQ_BULK_MODE_BLOCKING:
- status = vchiq_blocking_bulk_transfer(handle, (void *)data, size,
+ status = vchiq_blocking_bulk_transfer(instance, handle, (void *)data, size,
VCHIQ_BULK_RECEIVE);
break;
default:
@@ -909,20 +911,17 @@ enum vchiq_status vchiq_bulk_receive(unsigned int handle, void *data,
EXPORT_SYMBOL(vchiq_bulk_receive);
static enum vchiq_status
-vchiq_blocking_bulk_transfer(unsigned int handle, void *data, unsigned int size,
- enum vchiq_bulk_dir dir)
+vchiq_blocking_bulk_transfer(struct vchiq_instance *instance, unsigned int handle, void *data,
+ unsigned int size, enum vchiq_bulk_dir dir)
{
- struct vchiq_instance *instance;
struct vchiq_service *service;
enum vchiq_status status;
struct bulk_waiter_node *waiter = NULL, *iter;
- service = find_service_by_handle(handle);
+ service = find_service_by_handle(instance, handle);
if (!service)
return VCHIQ_ERROR;
- instance = service->instance;
-
vchiq_service_put(service);
mutex_lock(&instance->bulk_waiter_list_mutex);
@@ -959,7 +958,7 @@ vchiq_blocking_bulk_transfer(unsigned int handle, void *data, unsigned int size,
}
}
- status = vchiq_bulk_transfer(handle, data, NULL, size,
+ status = vchiq_bulk_transfer(instance, handle, data, NULL, size,
&waiter->bulk_waiter,
VCHIQ_BULK_MODE_BLOCKING, dir);
if ((status != VCHIQ_RETRY) || fatal_signal_pending(current) || !waiter->bulk_waiter.bulk) {
@@ -1046,8 +1045,8 @@ add_completion(struct vchiq_instance *instance, enum vchiq_reason reason,
}
enum vchiq_status
-service_callback(enum vchiq_reason reason, struct vchiq_header *header,
- unsigned int handle, void *bulk_userdata)
+service_callback(struct vchiq_instance *instance, enum vchiq_reason reason,
+ struct vchiq_header *header, unsigned int handle, void *bulk_userdata)
{
/*
* How do we ensure the callback goes to the right client?
@@ -1057,7 +1056,6 @@ service_callback(enum vchiq_reason reason, struct vchiq_header *header,
*/
struct user_service *user_service;
struct vchiq_service *service;
- struct vchiq_instance *instance;
bool skip_completion = false;
DEBUG_INITIALISE(g_state.local);
@@ -1065,14 +1063,13 @@ service_callback(enum vchiq_reason reason, struct vchiq_header *header,
DEBUG_TRACE(SERVICE_CALLBACK_LINE);
rcu_read_lock();
- service = handle_to_service(handle);
+ service = handle_to_service(instance, handle);
if (WARN_ON(!service)) {
rcu_read_unlock();
return VCHIQ_SUCCESS;
}
user_service = (struct user_service *)service->base.userdata;
- instance = user_service->instance;
if (!instance || instance->closing) {
rcu_read_unlock();
@@ -1318,7 +1315,8 @@ vchiq_get_state(void)
*/
static enum vchiq_status
-vchiq_keepalive_vchiq_callback(enum vchiq_reason reason,
+vchiq_keepalive_vchiq_callback(struct vchiq_instance *instance,
+ enum vchiq_reason reason,
struct vchiq_header *header,
unsigned int service_user, void *bulk_user)
{
@@ -1387,14 +1385,14 @@ vchiq_keepalive_thread_func(void *v)
*/
while (uc--) {
atomic_inc(&arm_state->ka_use_ack_count);
- status = vchiq_use_service(ka_handle);
+ status = vchiq_use_service(instance, ka_handle);
if (status != VCHIQ_SUCCESS) {
vchiq_log_error(vchiq_susp_log_level,
"%s vchiq_use_service error %d", __func__, status);
}
}
while (rc--) {
- status = vchiq_release_service(ka_handle);
+ status = vchiq_release_service(instance, ka_handle);
if (status != VCHIQ_SUCCESS) {
vchiq_log_error(vchiq_susp_log_level,
"%s vchiq_release_service error %d", __func__,
@@ -1590,10 +1588,10 @@ vchiq_instance_set_trace(struct vchiq_instance *instance, int trace)
}
enum vchiq_status
-vchiq_use_service(unsigned int handle)
+vchiq_use_service(struct vchiq_instance *instance, unsigned int handle)
{
enum vchiq_status ret = VCHIQ_ERROR;
- struct vchiq_service *service = find_service_by_handle(handle);
+ struct vchiq_service *service = find_service_by_handle(instance, handle);
if (service) {
ret = vchiq_use_internal(service->state, service, USE_TYPE_SERVICE);
@@ -1604,10 +1602,10 @@ vchiq_use_service(unsigned int handle)
EXPORT_SYMBOL(vchiq_use_service);
enum vchiq_status
-vchiq_release_service(unsigned int handle)
+vchiq_release_service(struct vchiq_instance *instance, unsigned int handle)
{
enum vchiq_status ret = VCHIQ_ERROR;
- struct vchiq_service *service = find_service_by_handle(handle);
+ struct vchiq_service *service = find_service_by_handle(instance, handle);
if (service) {
ret = vchiq_release_internal(service->state, service);
diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.h b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.h
index 2aa46b119a46..2851ef6b9cd0 100644
--- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.h
+++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.h
@@ -86,10 +86,10 @@ extern struct vchiq_state *
vchiq_get_state(void);
enum vchiq_status
-vchiq_use_service(unsigned int handle);
+vchiq_use_service(struct vchiq_instance *instance, unsigned int handle);
extern enum vchiq_status
-vchiq_release_service(unsigned int handle);
+vchiq_release_service(struct vchiq_instance *instance, unsigned int handle);
extern enum vchiq_status
vchiq_check_service(struct vchiq_service *service);
@@ -138,8 +138,8 @@ static inline int vchiq_register_chrdev(struct device *parent) { return 0; }
#endif /* IS_ENABLED(CONFIG_VCHIQ_CDEV) */
extern enum vchiq_status
-service_callback(enum vchiq_reason reason, struct vchiq_header *header,
- unsigned int handle, void *bulk_userdata);
+service_callback(struct vchiq_instance *vchiq_instance, enum vchiq_reason reason,
+ struct vchiq_header *header, unsigned int handle, void *bulk_userdata);
extern void
free_bulk_waiter(struct vchiq_instance *instance);
diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.c b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.c
index 8f99272dbd6f..45ed30bfdbf5 100644
--- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.c
+++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.c
@@ -13,6 +13,7 @@
#include <linux/rcupdate.h>
#include <linux/sched/signal.h>
+#include "vchiq_arm.h"
#include "vchiq_core.h"
#define VCHIQ_SLOT_HANDLER_STACK 8192
@@ -161,7 +162,6 @@ int vchiq_sync_log_level = VCHIQ_LOG_DEFAULT;
DEFINE_SPINLOCK(bulk_waiter_spinlock);
static DEFINE_SPINLOCK(quota_spinlock);
-struct vchiq_state *vchiq_states[VCHIQ_MAX_STATES];
static unsigned int handle_seq;
static const char *const srvstate_names[] = {
@@ -234,13 +234,19 @@ set_service_state(struct vchiq_service *service, int newstate)
service->srvstate = newstate;
}
+struct vchiq_service *handle_to_service(struct vchiq_instance *instance, unsigned int handle)
+{
+ int idx = handle & (VCHIQ_MAX_SERVICES - 1);
+
+ return rcu_dereference(instance->state->services[idx]);
+}
struct vchiq_service *
-find_service_by_handle(unsigned int handle)
+find_service_by_handle(struct vchiq_instance *instance, unsigned int handle)
{
struct vchiq_service *service;
rcu_read_lock();
- service = handle_to_service(handle);
+ service = handle_to_service(instance, handle);
if (service && service->srvstate != VCHIQ_SRVSTATE_FREE &&
service->handle == handle &&
kref_get_unless_zero(&service->ref_count)) {
@@ -281,7 +287,7 @@ find_service_for_instance(struct vchiq_instance *instance, unsigned int handle)
struct vchiq_service *service;
rcu_read_lock();
- service = handle_to_service(handle);
+ service = handle_to_service(instance, handle);
if (service && service->srvstate != VCHIQ_SRVSTATE_FREE &&
service->handle == handle &&
service->instance == instance &&
@@ -302,7 +308,7 @@ find_closed_service_for_instance(struct vchiq_instance *instance, unsigned int h
struct vchiq_service *service;
rcu_read_lock();
- service = handle_to_service(handle);
+ service = handle_to_service(instance, handle);
if (service &&
(service->srvstate == VCHIQ_SRVSTATE_FREE ||
service->srvstate == VCHIQ_SRVSTATE_CLOSED) &&
@@ -398,26 +404,26 @@ vchiq_service_put(struct vchiq_service *service)
}
int
-vchiq_get_client_id(unsigned int handle)
+vchiq_get_client_id(struct vchiq_instance *instance, unsigned int handle)
{
struct vchiq_service *service;
int id;
rcu_read_lock();
- service = handle_to_service(handle);
+ service = handle_to_service(instance, handle);
id = service ? service->client_id : 0;
rcu_read_unlock();
return id;
}
void *
-vchiq_get_service_userdata(unsigned int handle)
+vchiq_get_service_userdata(struct vchiq_instance *instance, unsigned int handle)
{
void *userdata;
struct vchiq_service *service;
rcu_read_lock();
- service = handle_to_service(handle);
+ service = handle_to_service(instance, handle);
userdata = service ? service->base.userdata : NULL;
rcu_read_unlock();
return userdata;
@@ -466,7 +472,8 @@ make_service_callback(struct vchiq_service *service, enum vchiq_reason reason,
vchiq_log_trace(vchiq_core_log_level, "%d: callback:%d (%s, %pK, %pK)",
service->state->id, service->localport, reason_names[reason],
header, bulk_userdata);
- status = service->base.callback(reason, header, service->handle, bulk_userdata);
+ status = service->base.callback(service->instance, reason, header, service->handle,
+ bulk_userdata);
if (status == VCHIQ_ERROR) {
vchiq_log_warning(vchiq_core_log_level,
"%d: ignoring ERROR from callback to service %x",
@@ -475,7 +482,7 @@ make_service_callback(struct vchiq_service *service, enum vchiq_reason reason,
}
if (reason != VCHIQ_MESSAGE_AVAILABLE)
- vchiq_release_message(service->handle, header);
+ vchiq_release_message(service->instance, service->handle, header);
return status;
}
@@ -521,6 +528,7 @@ remote_event_wait(wait_queue_head_t *wq, struct remote_event *event)
return 0;
}
event->armed = 0;
+ /* Ensure that the peer sees that we are not waiting (armed == 0). */
wmb();
}
@@ -643,6 +651,7 @@ request_poll(struct vchiq_state *state, struct vchiq_service *service,
skip_service:
state->poll_needed = 1;
+ /* Ensure the slot handler thread sees the poll_needed flag. */
wmb();
/* ... and ensure the slot handler runs. */
@@ -1149,6 +1158,7 @@ queue_message_sync(struct vchiq_state *state, struct vchiq_service *service,
remote_event_wait(&state->sync_release_event, &local->sync_release);
+ /* Ensure that reads don't overtake the remote_event_wait. */
rmb();
header = (struct vchiq_header *)SLOT_DATA_FROM_INDEX(state,
@@ -1441,7 +1451,7 @@ abort_outstanding_bulks(struct vchiq_service *service,
}
if (queue->process != queue->local_insert) {
- vchiq_complete_bulk(bulk);
+ vchiq_complete_bulk(service->instance, bulk);
vchiq_log_info(SRVTRACE_LEVEL(service),
"%s %c%c%c%c d:%d ABORTED - tx len:%d, rx len:%d",
@@ -1769,7 +1779,7 @@ parse_message(struct vchiq_state *state, struct vchiq_header *header)
DEBUG_TRACE(PARSE_LINE);
WARN_ON(queue->process == queue->local_insert);
- vchiq_complete_bulk(bulk);
+ vchiq_complete_bulk(service->instance, bulk);
queue->process++;
mutex_unlock(&service->bulk_mutex);
DEBUG_TRACE(PARSE_LINE);
@@ -1952,6 +1962,7 @@ slot_handler_func(void *v)
DEBUG_TRACE(SLOT_HANDLER_LINE);
remote_event_wait(&state->trigger_event, &local->trigger);
+ /* Ensure that reads don't overtake the remote_event_wait. */
rmb();
DEBUG_TRACE(SLOT_HANDLER_LINE);
@@ -2014,6 +2025,7 @@ sync_func(void *v)
remote_event_wait(&state->sync_trigger_event, &local->sync_trigger);
+ /* Ensure that reads don't overtake the remote_event_wait. */
rmb();
msgid = header->msgid;
@@ -2142,18 +2154,13 @@ vchiq_init_slots(void *mem_base, int mem_size)
}
int
-vchiq_init_state(struct vchiq_state *state, struct vchiq_slot_zero *slot_zero)
+vchiq_init_state(struct vchiq_state *state, struct vchiq_slot_zero *slot_zero, struct device *dev)
{
struct vchiq_shared_state *local;
struct vchiq_shared_state *remote;
char threadname[16];
int i, ret;
- if (vchiq_states[0]) {
- pr_err("%s: VCHIQ state already initialized\n", __func__);
- return -EINVAL;
- }
-
local = &slot_zero->slave;
remote = &slot_zero->master;
@@ -2169,6 +2176,8 @@ vchiq_init_state(struct vchiq_state *state, struct vchiq_slot_zero *slot_zero)
memset(state, 0, sizeof(struct vchiq_state));
+ state->dev = dev;
+
/*
* initialize shared state pointers
*/
@@ -2272,8 +2281,6 @@ vchiq_init_state(struct vchiq_state *state, struct vchiq_slot_zero *slot_zero)
wake_up_process(state->recycle_thread);
wake_up_process(state->sync_thread);
- vchiq_states[0] = state;
-
/* Indicate readiness to the other side */
local->initialised = 1;
@@ -2287,9 +2294,10 @@ fail_free_handler_thread:
return ret;
}
-void vchiq_msg_queue_push(unsigned int handle, struct vchiq_header *header)
+void vchiq_msg_queue_push(struct vchiq_instance *instance, unsigned int handle,
+ struct vchiq_header *header)
{
- struct vchiq_service *service = find_service_by_handle(handle);
+ struct vchiq_service *service = find_service_by_handle(instance, handle);
int pos;
if (!service)
@@ -2309,9 +2317,9 @@ void vchiq_msg_queue_push(unsigned int handle, struct vchiq_header *header)
}
EXPORT_SYMBOL(vchiq_msg_queue_push);
-struct vchiq_header *vchiq_msg_hold(unsigned int handle)
+struct vchiq_header *vchiq_msg_hold(struct vchiq_instance *instance, unsigned int handle)
{
- struct vchiq_service *service = find_service_by_handle(handle);
+ struct vchiq_service *service = find_service_by_handle(instance, handle);
struct vchiq_header *header;
int pos;
@@ -2866,16 +2874,16 @@ vchiq_shutdown_internal(struct vchiq_state *state, struct vchiq_instance *instan
/* Find all services registered to this client and remove them. */
i = 0;
while ((service = next_service_by_instance(state, instance, &i)) != NULL) {
- (void)vchiq_remove_service(service->handle);
+ (void)vchiq_remove_service(instance, service->handle);
vchiq_service_put(service);
}
}
enum vchiq_status
-vchiq_close_service(unsigned int handle)
+vchiq_close_service(struct vchiq_instance *instance, unsigned int handle)
{
/* Unregister the service */
- struct vchiq_service *service = find_service_by_handle(handle);
+ struct vchiq_service *service = find_service_by_handle(instance, handle);
enum vchiq_status status = VCHIQ_SUCCESS;
if (!service)
@@ -2930,10 +2938,10 @@ vchiq_close_service(unsigned int handle)
EXPORT_SYMBOL(vchiq_close_service);
enum vchiq_status
-vchiq_remove_service(unsigned int handle)
+vchiq_remove_service(struct vchiq_instance *instance, unsigned int handle)
{
/* Unregister the service */
- struct vchiq_service *service = find_service_by_handle(handle);
+ struct vchiq_service *service = find_service_by_handle(instance, handle);
enum vchiq_status status = VCHIQ_SUCCESS;
if (!service)
@@ -2996,11 +3004,11 @@ vchiq_remove_service(unsigned int handle)
* When called in blocking mode, the userdata field points to a bulk_waiter
* structure.
*/
-enum vchiq_status vchiq_bulk_transfer(unsigned int handle, void *offset, void __user *uoffset,
- int size, void *userdata, enum vchiq_bulk_mode mode,
- enum vchiq_bulk_dir dir)
+enum vchiq_status vchiq_bulk_transfer(struct vchiq_instance *instance, unsigned int handle,
+ void *offset, void __user *uoffset, int size, void *userdata,
+ enum vchiq_bulk_mode mode, enum vchiq_bulk_dir dir)
{
- struct vchiq_service *service = find_service_by_handle(handle);
+ struct vchiq_service *service = find_service_by_handle(instance, handle);
struct vchiq_bulk_queue *queue;
struct vchiq_bulk *bulk;
struct vchiq_state *state;
@@ -3075,9 +3083,13 @@ enum vchiq_status vchiq_bulk_transfer(unsigned int handle, void *offset, void __
bulk->size = size;
bulk->actual = VCHIQ_BULK_ACTUAL_ABORTED;
- if (vchiq_prepare_bulk_data(bulk, offset, uoffset, size, dir))
+ if (vchiq_prepare_bulk_data(instance, bulk, offset, uoffset, size, dir))
goto unlock_error_exit;
+ /*
+ * Ensure that the bulk data record is visible to the peer
+ * before proceeding.
+ */
wmb();
vchiq_log_info(vchiq_core_log_level, "%d: bt (%d->%d) %cx %x@%pad %pK",
@@ -3139,7 +3151,7 @@ waiting:
unlock_both_error_exit:
mutex_unlock(&state->slot_mutex);
cancel_bulk_error_exit:
- vchiq_complete_bulk(bulk);
+ vchiq_complete_bulk(service->instance, bulk);
unlock_error_exit:
mutex_unlock(&service->bulk_mutex);
@@ -3150,13 +3162,13 @@ error_exit:
}
enum vchiq_status
-vchiq_queue_message(unsigned int handle,
+vchiq_queue_message(struct vchiq_instance *instance, unsigned int handle,
ssize_t (*copy_callback)(void *context, void *dest,
size_t offset, size_t maxsize),
void *context,
size_t size)
{
- struct vchiq_service *service = find_service_by_handle(handle);
+ struct vchiq_service *service = find_service_by_handle(instance, handle);
enum vchiq_status status = VCHIQ_ERROR;
int data_id;
@@ -3199,12 +3211,13 @@ error_exit:
return status;
}
-int vchiq_queue_kernel_message(unsigned int handle, void *data, unsigned int size)
+int vchiq_queue_kernel_message(struct vchiq_instance *instance, unsigned int handle, void *data,
+ unsigned int size)
{
enum vchiq_status status;
while (1) {
- status = vchiq_queue_message(handle, memcpy_copy_callback,
+ status = vchiq_queue_message(instance, handle, memcpy_copy_callback,
data, size);
/*
@@ -3223,10 +3236,10 @@ int vchiq_queue_kernel_message(unsigned int handle, void *data, unsigned int siz
EXPORT_SYMBOL(vchiq_queue_kernel_message);
void
-vchiq_release_message(unsigned int handle,
+vchiq_release_message(struct vchiq_instance *instance, unsigned int handle,
struct vchiq_header *header)
{
- struct vchiq_service *service = find_service_by_handle(handle);
+ struct vchiq_service *service = find_service_by_handle(instance, handle);
struct vchiq_shared_state *remote;
struct vchiq_state *state;
int slot_index;
@@ -3265,10 +3278,10 @@ release_message_sync(struct vchiq_state *state, struct vchiq_header *header)
}
enum vchiq_status
-vchiq_get_peer_version(unsigned int handle, short *peer_version)
+vchiq_get_peer_version(struct vchiq_instance *instance, unsigned int handle, short *peer_version)
{
enum vchiq_status status = VCHIQ_ERROR;
- struct vchiq_service *service = find_service_by_handle(handle);
+ struct vchiq_service *service = find_service_by_handle(instance, handle);
if (!service)
goto exit;
@@ -3300,9 +3313,10 @@ void vchiq_get_config(struct vchiq_config *config)
}
int
-vchiq_set_service_option(unsigned int handle, enum vchiq_service_option option, int value)
+vchiq_set_service_option(struct vchiq_instance *instance, unsigned int handle,
+ enum vchiq_service_option option, int value)
{
- struct vchiq_service *service = find_service_by_handle(handle);
+ struct vchiq_service *service = find_service_by_handle(instance, handle);
struct vchiq_service_quota *quota;
int ret = -EINVAL;
diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.h b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.h
index 1ddc661642a9..8b4a38f5b3f2 100644
--- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.h
+++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.h
@@ -314,6 +314,7 @@ struct vchiq_slot_zero {
};
struct vchiq_state {
+ struct device *dev;
int id;
int initialised;
enum vchiq_connstate conn_state;
@@ -448,8 +449,6 @@ extern int vchiq_core_log_level;
extern int vchiq_core_msg_log_level;
extern int vchiq_sync_log_level;
-extern struct vchiq_state *vchiq_states[VCHIQ_MAX_STATES];
-
extern const char *
get_conn_state_name(enum vchiq_connstate conn_state);
@@ -457,7 +456,7 @@ extern struct vchiq_slot_zero *
vchiq_init_slots(void *mem_base, int mem_size);
extern int
-vchiq_init_state(struct vchiq_state *state, struct vchiq_slot_zero *slot_zero);
+vchiq_init_state(struct vchiq_state *state, struct vchiq_slot_zero *slot_zero, struct device *dev);
extern enum vchiq_status
vchiq_connect_internal(struct vchiq_state *state, struct vchiq_instance *instance);
@@ -487,8 +486,8 @@ extern void
remote_event_pollall(struct vchiq_state *state);
extern enum vchiq_status
-vchiq_bulk_transfer(unsigned int handle, void *offset, void __user *uoffset,
- int size, void *userdata, enum vchiq_bulk_mode mode,
+vchiq_bulk_transfer(struct vchiq_instance *instance, unsigned int handle, void *offset,
+ void __user *uoffset, int size, void *userdata, enum vchiq_bulk_mode mode,
enum vchiq_bulk_dir dir);
extern int
@@ -507,20 +506,10 @@ extern void
request_poll(struct vchiq_state *state, struct vchiq_service *service,
int poll_type);
-static inline struct vchiq_service *
-handle_to_service(unsigned int handle)
-{
- int idx = handle & (VCHIQ_MAX_SERVICES - 1);
- struct vchiq_state *state = vchiq_states[(handle / VCHIQ_MAX_SERVICES) &
- (VCHIQ_MAX_STATES - 1)];
-
- if (!state)
- return NULL;
- return rcu_dereference(state->services[idx]);
-}
+struct vchiq_service *handle_to_service(struct vchiq_instance *instance, unsigned int handle);
extern struct vchiq_service *
-find_service_by_handle(unsigned int handle);
+find_service_by_handle(struct vchiq_instance *instance, unsigned int handle);
extern struct vchiq_service *
find_service_by_port(struct vchiq_state *state, unsigned int localport);
@@ -548,16 +537,16 @@ extern void
vchiq_service_put(struct vchiq_service *service);
extern enum vchiq_status
-vchiq_queue_message(unsigned int handle,
+vchiq_queue_message(struct vchiq_instance *instance, unsigned int handle,
ssize_t (*copy_callback)(void *context, void *dest,
size_t offset, size_t maxsize),
void *context,
size_t size);
-int vchiq_prepare_bulk_data(struct vchiq_bulk *bulk, void *offset, void __user *uoffset,
- int size, int dir);
+int vchiq_prepare_bulk_data(struct vchiq_instance *instance, struct vchiq_bulk *bulk, void *offset,
+ void __user *uoffset, int size, int dir);
-void vchiq_complete_bulk(struct vchiq_bulk *bulk);
+void vchiq_complete_bulk(struct vchiq_instance *instance, struct vchiq_bulk *bulk);
void remote_event_signal(struct remote_event *event);
@@ -595,12 +584,13 @@ void vchiq_set_conn_state(struct vchiq_state *state, enum vchiq_connstate newsta
void vchiq_log_dump_mem(const char *label, u32 addr, const void *void_mem, size_t num_bytes);
-enum vchiq_status vchiq_remove_service(unsigned int service);
+enum vchiq_status vchiq_remove_service(struct vchiq_instance *instance, unsigned int service);
-int vchiq_get_client_id(unsigned int service);
+int vchiq_get_client_id(struct vchiq_instance *instance, unsigned int service);
void vchiq_get_config(struct vchiq_config *config);
-int vchiq_set_service_option(unsigned int service, enum vchiq_service_option option, int value);
+int vchiq_set_service_option(struct vchiq_instance *instance, unsigned int service,
+ enum vchiq_service_option option, int value);
#endif
diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_dev.c b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_dev.c
index 66bbfec332ba..7e297494437e 100644
--- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_dev.c
+++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_dev.c
@@ -108,8 +108,8 @@ static ssize_t vchiq_ioc_copy_element_data(void *context, void *dest,
}
static int
-vchiq_ioc_queue_message(unsigned int handle, struct vchiq_element *elements,
- unsigned long count)
+vchiq_ioc_queue_message(struct vchiq_instance *instance, unsigned int handle,
+ struct vchiq_element *elements, unsigned long count)
{
struct vchiq_io_copy_callback_context context;
enum vchiq_status status = VCHIQ_SUCCESS;
@@ -127,7 +127,7 @@ vchiq_ioc_queue_message(unsigned int handle, struct vchiq_element *elements,
total_size += elements[i].size;
}
- status = vchiq_queue_message(handle, vchiq_ioc_copy_element_data,
+ status = vchiq_queue_message(instance, handle, vchiq_ioc_copy_element_data,
&context, total_size);
if (status == VCHIQ_ERROR)
@@ -191,7 +191,7 @@ static int vchiq_ioc_create_service(struct vchiq_instance *instance,
if (args->is_open) {
status = vchiq_open_service_internal(service, instance->pid);
if (status != VCHIQ_SUCCESS) {
- vchiq_remove_service(service->handle);
+ vchiq_remove_service(instance, service->handle);
return (status == VCHIQ_RETRY) ?
-EINTR : -EIO;
}
@@ -266,7 +266,7 @@ static int vchiq_ioc_dequeue_message(struct vchiq_instance *instance,
/* Copy to user space if msgbuf is not NULL */
if (!args->buf || (copy_to_user(args->buf, header->data, header->size) == 0)) {
ret = header->size;
- vchiq_release_message(service->handle, header);
+ vchiq_release_message(instance, service->handle, header);
} else {
ret = -EFAULT;
}
@@ -330,7 +330,7 @@ static int vchiq_irq_queue_bulk_tx_rx(struct vchiq_instance *instance,
userdata = args->userdata;
}
- status = vchiq_bulk_transfer(args->handle, NULL, args->data, args->size,
+ status = vchiq_bulk_transfer(instance, args->handle, NULL, args->data, args->size,
userdata, args->mode, dir);
if (!waiter) {
@@ -529,7 +529,7 @@ static int vchiq_ioc_await_completion(struct vchiq_instance *instance,
}
/* Now it has been copied, the message can be released. */
- vchiq_release_message(service->handle, header);
+ vchiq_release_message(instance, service->handle, header);
/* The completion must point to the msgbuf. */
user_completion.header = msgbuf;
@@ -596,7 +596,7 @@ vchiq_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
i = 0;
while ((service = next_service_by_instance(instance->state,
instance, &i))) {
- status = vchiq_remove_service(service->handle);
+ status = vchiq_remove_service(instance, service->handle);
vchiq_service_put(service);
if (status != VCHIQ_SUCCESS)
break;
@@ -649,7 +649,7 @@ vchiq_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
break;
if (put_user(args.handle, &argp->handle)) {
- vchiq_remove_service(args.handle);
+ vchiq_remove_service(instance, args.handle);
ret = -EFAULT;
}
} break;
@@ -673,8 +673,8 @@ vchiq_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
*/
if (!user_service->close_pending) {
status = (cmd == VCHIQ_IOC_CLOSE_SERVICE) ?
- vchiq_close_service(service->handle) :
- vchiq_remove_service(service->handle);
+ vchiq_close_service(instance, service->handle) :
+ vchiq_remove_service(instance, service->handle);
if (status != VCHIQ_SUCCESS)
break;
}
@@ -731,7 +731,7 @@ vchiq_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
if (copy_from_user(elements, args.elements,
args.count * sizeof(struct vchiq_element)) == 0)
- ret = vchiq_ioc_queue_message(args.handle, elements,
+ ret = vchiq_ioc_queue_message(instance, args.handle, elements,
args.count);
else
ret = -EFAULT;
@@ -788,7 +788,7 @@ vchiq_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
case VCHIQ_IOC_GET_CLIENT_ID: {
unsigned int handle = (unsigned int)arg;
- ret = vchiq_get_client_id(handle);
+ ret = vchiq_get_client_id(instance, handle);
} break;
case VCHIQ_IOC_GET_CONFIG: {
@@ -827,7 +827,7 @@ vchiq_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
break;
}
- ret = vchiq_set_service_option(args.handle, args.option,
+ ret = vchiq_set_service_option(instance, args.handle, args.option,
args.value);
} break;
@@ -908,6 +908,7 @@ vchiq_compat_ioctl_create_service(struct file *file, unsigned int cmd,
{
struct vchiq_create_service args;
struct vchiq_create_service32 args32;
+ struct vchiq_instance *instance = file->private_data;
long ret;
if (copy_from_user(&args32, ptrargs32, sizeof(args32)))
@@ -926,12 +927,12 @@ vchiq_compat_ioctl_create_service(struct file *file, unsigned int cmd,
.handle = args32.handle,
};
- ret = vchiq_ioc_create_service(file->private_data, &args);
+ ret = vchiq_ioc_create_service(instance, &args);
if (ret < 0)
return ret;
if (put_user(args.handle, &ptrargs32->handle)) {
- vchiq_remove_service(args.handle);
+ vchiq_remove_service(instance, args.handle);
return -EFAULT;
}
@@ -960,6 +961,7 @@ vchiq_compat_ioctl_queue_message(struct file *file,
struct vchiq_queue_message args;
struct vchiq_queue_message32 args32;
struct vchiq_service *service;
+ struct vchiq_instance *instance = file->private_data;
int ret;
if (copy_from_user(&args32, arg, sizeof(args32)))
@@ -974,7 +976,7 @@ vchiq_compat_ioctl_queue_message(struct file *file,
if (args32.count > MAX_ELEMENTS)
return -EINVAL;
- service = find_service_for_instance(file->private_data, args.handle);
+ service = find_service_for_instance(instance, args.handle);
if (!service)
return -EINVAL;
@@ -994,7 +996,7 @@ vchiq_compat_ioctl_queue_message(struct file *file,
compat_ptr(element32[count].data);
elements[count].size = element32[count].size;
}
- ret = vchiq_ioc_queue_message(args.handle, elements,
+ ret = vchiq_ioc_queue_message(instance, args.handle, elements,
args.count);
} else {
ret = -EINVAL;
@@ -1261,7 +1263,7 @@ static int vchiq_release(struct inode *inode, struct file *file)
spin_unlock(&msg_queue_spinlock);
if (header)
- vchiq_release_message(service->handle, header);
+ vchiq_release_message(instance, service->handle, header);
spin_lock(&msg_queue_spinlock);
}
diff --git a/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c b/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c
index 845b20e4d05a..cb921c94996a 100644
--- a/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c
+++ b/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c
@@ -292,8 +292,8 @@ static void buffer_to_host_work_cb(struct work_struct *work)
/* Dummy receive to ensure the buffers remain in order */
len = 8;
/* queue the bulk submission */
- vchiq_use_service(instance->service_handle);
- ret = vchiq_bulk_receive(instance->service_handle,
+ vchiq_use_service(instance->vchiq_instance, instance->service_handle);
+ ret = vchiq_bulk_receive(instance->vchiq_instance, instance->service_handle,
msg_context->u.bulk.buffer->buffer,
/* Actual receive needs to be a multiple
* of 4 bytes
@@ -302,7 +302,7 @@ static void buffer_to_host_work_cb(struct work_struct *work)
msg_context,
VCHIQ_BULK_MODE_CALLBACK);
- vchiq_release_service(instance->service_handle);
+ vchiq_release_service(instance->vchiq_instance, instance->service_handle);
if (ret != 0)
pr_err("%s: ctx: %p, vchiq_bulk_receive failed %d\n",
@@ -436,15 +436,15 @@ buffer_from_host(struct vchiq_mmal_instance *instance,
/* no payload in message */
m.u.buffer_from_host.payload_in_message = 0;
- vchiq_use_service(instance->service_handle);
+ vchiq_use_service(instance->vchiq_instance, instance->service_handle);
- ret = vchiq_queue_kernel_message(instance->service_handle, &m,
+ ret = vchiq_queue_kernel_message(instance->vchiq_instance, instance->service_handle, &m,
sizeof(struct mmal_msg_header) +
sizeof(m.u.buffer_from_host));
if (ret)
atomic_dec(&port->buffers_with_vpu);
- vchiq_release_service(instance->service_handle);
+ vchiq_release_service(instance->vchiq_instance, instance->service_handle);
return ret;
}
@@ -548,11 +548,12 @@ static void bulk_abort_cb(struct vchiq_mmal_instance *instance,
}
/* incoming event service callback */
-static enum vchiq_status service_callback(enum vchiq_reason reason,
+static enum vchiq_status service_callback(struct vchiq_instance *vchiq_instance,
+ enum vchiq_reason reason,
struct vchiq_header *header,
unsigned int handle, void *bulk_ctx)
{
- struct vchiq_mmal_instance *instance = vchiq_get_service_userdata(handle);
+ struct vchiq_mmal_instance *instance = vchiq_get_service_userdata(vchiq_instance, handle);
u32 msg_len;
struct mmal_msg *msg;
struct mmal_msg_context *msg_context;
@@ -572,25 +573,25 @@ static enum vchiq_status service_callback(enum vchiq_reason reason,
/* handling is different for buffer messages */
switch (msg->h.type) {
case MMAL_MSG_TYPE_BUFFER_FROM_HOST:
- vchiq_release_message(handle, header);
+ vchiq_release_message(vchiq_instance, handle, header);
break;
case MMAL_MSG_TYPE_EVENT_TO_HOST:
event_to_host_cb(instance, msg, msg_len);
- vchiq_release_message(handle, header);
+ vchiq_release_message(vchiq_instance, handle, header);
break;
case MMAL_MSG_TYPE_BUFFER_TO_HOST:
buffer_to_host_cb(instance, msg, msg_len);
- vchiq_release_message(handle, header);
+ vchiq_release_message(vchiq_instance, handle, header);
break;
default:
/* messages dependent on header context to complete */
if (!msg->h.context) {
pr_err("received message context was null!\n");
- vchiq_release_message(handle, header);
+ vchiq_release_message(vchiq_instance, handle, header);
break;
}
@@ -599,7 +600,7 @@ static enum vchiq_status service_callback(enum vchiq_reason reason,
if (!msg_context) {
pr_err("received invalid message context %u!\n",
msg->h.context);
- vchiq_release_message(handle, header);
+ vchiq_release_message(vchiq_instance, handle, header);
break;
}
@@ -678,13 +679,13 @@ static int send_synchronous_mmal_msg(struct vchiq_mmal_instance *instance,
DBG_DUMP_MSG(msg, (sizeof(struct mmal_msg_header) + payload_len),
">>> sync message");
- vchiq_use_service(instance->service_handle);
+ vchiq_use_service(instance->vchiq_instance, instance->service_handle);
- ret = vchiq_queue_kernel_message(instance->service_handle, msg,
+ ret = vchiq_queue_kernel_message(instance->vchiq_instance, instance->service_handle, msg,
sizeof(struct mmal_msg_header) +
payload_len);
- vchiq_release_service(instance->service_handle);
+ vchiq_release_service(instance->vchiq_instance, instance->service_handle);
if (ret) {
pr_err("error %d queuing message\n", ret);
@@ -824,7 +825,7 @@ static int port_info_set(struct vchiq_mmal_instance *instance,
port->component->handle, port->handle);
release_msg:
- vchiq_release_message(instance->service_handle, rmsg_handle);
+ vchiq_release_message(instance->vchiq_instance, instance->service_handle, rmsg_handle);
return ret;
}
@@ -919,7 +920,7 @@ release_msg:
pr_debug("%s:result:%d component:0x%x port:%d\n",
__func__, ret, port->component->handle, port->handle);
- vchiq_release_message(instance->service_handle, rmsg_handle);
+ vchiq_release_message(instance->vchiq_instance, instance->service_handle, rmsg_handle);
return ret;
}
@@ -967,7 +968,7 @@ static int create_component(struct vchiq_mmal_instance *instance,
component->inputs, component->outputs, component->clocks);
release_msg:
- vchiq_release_message(instance->service_handle, rmsg_handle);
+ vchiq_release_message(instance->vchiq_instance, instance->service_handle, rmsg_handle);
return ret;
}
@@ -1000,7 +1001,7 @@ static int destroy_component(struct vchiq_mmal_instance *instance,
release_msg:
- vchiq_release_message(instance->service_handle, rmsg_handle);
+ vchiq_release_message(instance->vchiq_instance, instance->service_handle, rmsg_handle);
return ret;
}
@@ -1032,7 +1033,7 @@ static int enable_component(struct vchiq_mmal_instance *instance,
ret = -rmsg->u.component_enable_reply.status;
release_msg:
- vchiq_release_message(instance->service_handle, rmsg_handle);
+ vchiq_release_message(instance->vchiq_instance, instance->service_handle, rmsg_handle);
return ret;
}
@@ -1065,7 +1066,7 @@ static int disable_component(struct vchiq_mmal_instance *instance,
release_msg:
- vchiq_release_message(instance->service_handle, rmsg_handle);
+ vchiq_release_message(instance->vchiq_instance, instance->service_handle, rmsg_handle);
return ret;
}
@@ -1097,7 +1098,7 @@ static int get_version(struct vchiq_mmal_instance *instance,
*minor_out = rmsg->u.version.minor;
release_msg:
- vchiq_release_message(instance->service_handle, rmsg_handle);
+ vchiq_release_message(instance->vchiq_instance, instance->service_handle, rmsg_handle);
return ret;
}
@@ -1139,7 +1140,7 @@ static int port_action_port(struct vchiq_mmal_instance *instance,
port_action_type_names[action_type], action_type);
release_msg:
- vchiq_release_message(instance->service_handle, rmsg_handle);
+ vchiq_release_message(instance->vchiq_instance, instance->service_handle, rmsg_handle);
return ret;
}
@@ -1187,7 +1188,7 @@ static int port_action_handle(struct vchiq_mmal_instance *instance,
action_type, connect_component_handle, connect_port_handle);
release_msg:
- vchiq_release_message(instance->service_handle, rmsg_handle);
+ vchiq_release_message(instance->vchiq_instance, instance->service_handle, rmsg_handle);
return ret;
}
@@ -1228,7 +1229,7 @@ static int port_parameter_set(struct vchiq_mmal_instance *instance,
ret, port->component->handle, port->handle, parameter_id);
release_msg:
- vchiq_release_message(instance->service_handle, rmsg_handle);
+ vchiq_release_message(instance->vchiq_instance, instance->service_handle, rmsg_handle);
return ret;
}
@@ -1287,7 +1288,7 @@ static int port_parameter_get(struct vchiq_mmal_instance *instance,
ret, port->component->handle, port->handle, parameter_id);
release_msg:
- vchiq_release_message(instance->service_handle, rmsg_handle);
+ vchiq_release_message(instance->vchiq_instance, instance->service_handle, rmsg_handle);
return ret;
}
@@ -1832,9 +1833,9 @@ int vchiq_mmal_finalise(struct vchiq_mmal_instance *instance)
if (mutex_lock_interruptible(&instance->vchiq_mutex))
return -EINTR;
- vchiq_use_service(instance->service_handle);
+ vchiq_use_service(instance->vchiq_instance, instance->service_handle);
- status = vchiq_close_service(instance->service_handle);
+ status = vchiq_close_service(instance->vchiq_instance, instance->service_handle);
if (status != 0)
pr_err("mmal-vchiq: VCHIQ close failed\n");
@@ -1922,14 +1923,14 @@ int vchiq_mmal_init(struct vchiq_mmal_instance **out_instance)
goto err_close_services;
}
- vchiq_release_service(instance->service_handle);
+ vchiq_release_service(instance->vchiq_instance, instance->service_handle);
*out_instance = instance;
return 0;
err_close_services:
- vchiq_close_service(instance->service_handle);
+ vchiq_close_service(instance->vchiq_instance, instance->service_handle);
destroy_workqueue(instance->bulk_wq);
err_free:
kfree(instance);
diff --git a/drivers/staging/vme_user/Kconfig b/drivers/staging/vme_user/Kconfig
index e8b4461bf27f..c8eabf8f40f1 100644
--- a/drivers/staging/vme_user/Kconfig
+++ b/drivers/staging/vme_user/Kconfig
@@ -1,4 +1,29 @@
# SPDX-License-Identifier: GPL-2.0
+menuconfig VME_BUS
+ bool "VME bridge support"
+ depends on STAGING && PCI
+ help
+ If you say Y here you get support for the VME bridge Framework.
+
+if VME_BUS
+
+comment "VME Bridge Drivers"
+
+config VME_TSI148
+ tristate "Tempe"
+ depends on HAS_DMA
+ help
+ If you say Y here you get support for the Tundra TSI148 VME bridge
+ chip.
+
+config VME_FAKE
+ tristate "Fake"
+ help
+ If you say Y here you get support for the fake VME bridge. This
+ provides a virtualised VME Bus for devices with no VME bridge. This
+ is mainly useful for VME development (in the absence of VME
+ hardware).
+
comment "VME Device Drivers"
config VME_USER
@@ -11,3 +36,5 @@ config VME_USER
To compile this driver as a module, choose M here. The module will
be called vme_user. If unsure, say N.
+
+endif
diff --git a/drivers/staging/vme_user/Makefile b/drivers/staging/vme_user/Makefile
index 5380115139b0..8dcc6938ce5c 100644
--- a/drivers/staging/vme_user/Makefile
+++ b/drivers/staging/vme_user/Makefile
@@ -3,4 +3,7 @@
# Makefile for the VME device drivers.
#
+obj-$(CONFIG_VME_BUS) += vme.o
obj-$(CONFIG_VME_USER) += vme_user.o
+obj-$(CONFIG_VME_TSI148) += vme_tsi148.o
+obj-$(CONFIG_VME_FAKE) += vme_fake.o
diff --git a/drivers/staging/vme_user/vme.c b/drivers/staging/vme_user/vme.c
new file mode 100644
index 000000000000..b5555683a069
--- /dev/null
+++ b/drivers/staging/vme_user/vme.c
@@ -0,0 +1,2015 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * VME Bridge Framework
+ *
+ * Author: Martyn Welch <martyn.welch@ge.com>
+ * Copyright 2008 GE Intelligent Platforms Embedded Systems, Inc.
+ *
+ * Based on work by Tom Armistead and Ajit Prem
+ * Copyright 2004 Motorola Inc.
+ */
+
+#include <linux/init.h>
+#include <linux/export.h>
+#include <linux/mm.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/pci.h>
+#include <linux/poll.h>
+#include <linux/highmem.h>
+#include <linux/interrupt.h>
+#include <linux/pagemap.h>
+#include <linux/device.h>
+#include <linux/dma-mapping.h>
+#include <linux/syscalls.h>
+#include <linux/mutex.h>
+#include <linux/spinlock.h>
+#include <linux/slab.h>
+
+#include "vme.h"
+#include "vme_bridge.h"
+
+/* Bitmask and list of registered buses both protected by common mutex */
+static unsigned int vme_bus_numbers;
+static LIST_HEAD(vme_bus_list);
+static DEFINE_MUTEX(vme_buses_lock);
+
+static int __init vme_init(void);
+
+static struct vme_dev *dev_to_vme_dev(struct device *dev)
+{
+ return container_of(dev, struct vme_dev, dev);
+}
+
+/*
+ * Find the bridge that the resource is associated with.
+ */
+static struct vme_bridge *find_bridge(struct vme_resource *resource)
+{
+ /* Get list to search */
+ switch (resource->type) {
+ case VME_MASTER:
+ return list_entry(resource->entry, struct vme_master_resource,
+ list)->parent;
+ case VME_SLAVE:
+ return list_entry(resource->entry, struct vme_slave_resource,
+ list)->parent;
+ case VME_DMA:
+ return list_entry(resource->entry, struct vme_dma_resource,
+ list)->parent;
+ case VME_LM:
+ return list_entry(resource->entry, struct vme_lm_resource,
+ list)->parent;
+ default:
+ printk(KERN_ERR "Unknown resource type\n");
+ return NULL;
+ }
+}
+
+/**
+ * vme_alloc_consistent - Allocate contiguous memory.
+ * @resource: Pointer to VME resource.
+ * @size: Size of allocation required.
+ * @dma: Pointer to variable to store physical address of allocation.
+ *
+ * Allocate a contiguous block of memory for use by the driver. This is used to
+ * create the buffers for the slave windows.
+ *
+ * Return: Virtual address of allocation on success, NULL on failure.
+ */
+void *vme_alloc_consistent(struct vme_resource *resource, size_t size,
+ dma_addr_t *dma)
+{
+ struct vme_bridge *bridge;
+
+ if (!resource) {
+ printk(KERN_ERR "No resource\n");
+ return NULL;
+ }
+
+ bridge = find_bridge(resource);
+ if (!bridge) {
+ printk(KERN_ERR "Can't find bridge\n");
+ return NULL;
+ }
+
+ if (!bridge->parent) {
+ printk(KERN_ERR "Dev entry NULL for bridge %s\n", bridge->name);
+ return NULL;
+ }
+
+ if (!bridge->alloc_consistent) {
+ printk(KERN_ERR "alloc_consistent not supported by bridge %s\n",
+ bridge->name);
+ return NULL;
+ }
+
+ return bridge->alloc_consistent(bridge->parent, size, dma);
+}
+EXPORT_SYMBOL(vme_alloc_consistent);
+
+/**
+ * vme_free_consistent - Free previously allocated memory.
+ * @resource: Pointer to VME resource.
+ * @size: Size of allocation to free.
+ * @vaddr: Virtual address of allocation.
+ * @dma: Physical address of allocation.
+ *
+ * Free previously allocated block of contiguous memory.
+ */
+void vme_free_consistent(struct vme_resource *resource, size_t size,
+ void *vaddr, dma_addr_t dma)
+{
+ struct vme_bridge *bridge;
+
+ if (!resource) {
+ printk(KERN_ERR "No resource\n");
+ return;
+ }
+
+ bridge = find_bridge(resource);
+ if (!bridge) {
+ printk(KERN_ERR "Can't find bridge\n");
+ return;
+ }
+
+ if (!bridge->parent) {
+ printk(KERN_ERR "Dev entry NULL for bridge %s\n", bridge->name);
+ return;
+ }
+
+ if (!bridge->free_consistent) {
+ printk(KERN_ERR "free_consistent not supported by bridge %s\n",
+ bridge->name);
+ return;
+ }
+
+ bridge->free_consistent(bridge->parent, size, vaddr, dma);
+}
+EXPORT_SYMBOL(vme_free_consistent);
+
+/**
+ * vme_get_size - Helper function returning size of a VME window
+ * @resource: Pointer to VME slave or master resource.
+ *
+ * Determine the size of the VME window provided. This is a helper
+ * function, wrappering the call to vme_master_get or vme_slave_get
+ * depending on the type of window resource handed to it.
+ *
+ * Return: Size of the window on success, zero on failure.
+ */
+size_t vme_get_size(struct vme_resource *resource)
+{
+ int enabled, retval;
+ unsigned long long base, size;
+ dma_addr_t buf_base;
+ u32 aspace, cycle, dwidth;
+
+ switch (resource->type) {
+ case VME_MASTER:
+ retval = vme_master_get(resource, &enabled, &base, &size,
+ &aspace, &cycle, &dwidth);
+ if (retval)
+ return 0;
+
+ return size;
+ case VME_SLAVE:
+ retval = vme_slave_get(resource, &enabled, &base, &size,
+ &buf_base, &aspace, &cycle);
+ if (retval)
+ return 0;
+
+ return size;
+ case VME_DMA:
+ return 0;
+ default:
+ printk(KERN_ERR "Unknown resource type\n");
+ return 0;
+ }
+}
+EXPORT_SYMBOL(vme_get_size);
+
+int vme_check_window(u32 aspace, unsigned long long vme_base,
+ unsigned long long size)
+{
+ int retval = 0;
+
+ if (vme_base + size < size)
+ return -EINVAL;
+
+ switch (aspace) {
+ case VME_A16:
+ if (vme_base + size > VME_A16_MAX)
+ retval = -EFAULT;
+ break;
+ case VME_A24:
+ if (vme_base + size > VME_A24_MAX)
+ retval = -EFAULT;
+ break;
+ case VME_A32:
+ if (vme_base + size > VME_A32_MAX)
+ retval = -EFAULT;
+ break;
+ case VME_A64:
+ /* The VME_A64_MAX limit is actually U64_MAX + 1 */
+ break;
+ case VME_CRCSR:
+ if (vme_base + size > VME_CRCSR_MAX)
+ retval = -EFAULT;
+ break;
+ case VME_USER1:
+ case VME_USER2:
+ case VME_USER3:
+ case VME_USER4:
+ /* User Defined */
+ break;
+ default:
+ printk(KERN_ERR "Invalid address space\n");
+ retval = -EINVAL;
+ break;
+ }
+
+ return retval;
+}
+EXPORT_SYMBOL(vme_check_window);
+
+static u32 vme_get_aspace(int am)
+{
+ switch (am) {
+ case 0x29:
+ case 0x2D:
+ return VME_A16;
+ case 0x38:
+ case 0x39:
+ case 0x3A:
+ case 0x3B:
+ case 0x3C:
+ case 0x3D:
+ case 0x3E:
+ case 0x3F:
+ return VME_A24;
+ case 0x8:
+ case 0x9:
+ case 0xA:
+ case 0xB:
+ case 0xC:
+ case 0xD:
+ case 0xE:
+ case 0xF:
+ return VME_A32;
+ case 0x0:
+ case 0x1:
+ case 0x3:
+ return VME_A64;
+ }
+
+ return 0;
+}
+
+/**
+ * vme_slave_request - Request a VME slave window resource.
+ * @vdev: Pointer to VME device struct vme_dev assigned to driver instance.
+ * @address: Required VME address space.
+ * @cycle: Required VME data transfer cycle type.
+ *
+ * Request use of a VME window resource capable of being set for the requested
+ * address space and data transfer cycle.
+ *
+ * Return: Pointer to VME resource on success, NULL on failure.
+ */
+struct vme_resource *vme_slave_request(struct vme_dev *vdev, u32 address,
+ u32 cycle)
+{
+ struct vme_bridge *bridge;
+ struct list_head *slave_pos = NULL;
+ struct vme_slave_resource *allocated_image = NULL;
+ struct vme_slave_resource *slave_image = NULL;
+ struct vme_resource *resource = NULL;
+
+ bridge = vdev->bridge;
+ if (!bridge) {
+ printk(KERN_ERR "Can't find VME bus\n");
+ goto err_bus;
+ }
+
+ /* Loop through slave resources */
+ list_for_each(slave_pos, &bridge->slave_resources) {
+ slave_image = list_entry(slave_pos,
+ struct vme_slave_resource, list);
+
+ if (!slave_image) {
+ printk(KERN_ERR "Registered NULL Slave resource\n");
+ continue;
+ }
+
+ /* Find an unlocked and compatible image */
+ mutex_lock(&slave_image->mtx);
+ if (((slave_image->address_attr & address) == address) &&
+ ((slave_image->cycle_attr & cycle) == cycle) &&
+ (slave_image->locked == 0)) {
+
+ slave_image->locked = 1;
+ mutex_unlock(&slave_image->mtx);
+ allocated_image = slave_image;
+ break;
+ }
+ mutex_unlock(&slave_image->mtx);
+ }
+
+ /* No free image */
+ if (!allocated_image)
+ goto err_image;
+
+ resource = kmalloc(sizeof(*resource), GFP_KERNEL);
+ if (!resource)
+ goto err_alloc;
+
+ resource->type = VME_SLAVE;
+ resource->entry = &allocated_image->list;
+
+ return resource;
+
+err_alloc:
+ /* Unlock image */
+ mutex_lock(&slave_image->mtx);
+ slave_image->locked = 0;
+ mutex_unlock(&slave_image->mtx);
+err_image:
+err_bus:
+ return NULL;
+}
+EXPORT_SYMBOL(vme_slave_request);
+
+/**
+ * vme_slave_set - Set VME slave window configuration.
+ * @resource: Pointer to VME slave resource.
+ * @enabled: State to which the window should be configured.
+ * @vme_base: Base address for the window.
+ * @size: Size of the VME window.
+ * @buf_base: Based address of buffer used to provide VME slave window storage.
+ * @aspace: VME address space for the VME window.
+ * @cycle: VME data transfer cycle type for the VME window.
+ *
+ * Set configuration for provided VME slave window.
+ *
+ * Return: Zero on success, -EINVAL if operation is not supported on this
+ * device, if an invalid resource has been provided or invalid
+ * attributes are provided. Hardware specific errors may also be
+ * returned.
+ */
+int vme_slave_set(struct vme_resource *resource, int enabled,
+ unsigned long long vme_base, unsigned long long size,
+ dma_addr_t buf_base, u32 aspace, u32 cycle)
+{
+ struct vme_bridge *bridge = find_bridge(resource);
+ struct vme_slave_resource *image;
+ int retval;
+
+ if (resource->type != VME_SLAVE) {
+ printk(KERN_ERR "Not a slave resource\n");
+ return -EINVAL;
+ }
+
+ image = list_entry(resource->entry, struct vme_slave_resource, list);
+
+ if (!bridge->slave_set) {
+ printk(KERN_ERR "Function not supported\n");
+ return -ENOSYS;
+ }
+
+ if (!(((image->address_attr & aspace) == aspace) &&
+ ((image->cycle_attr & cycle) == cycle))) {
+ printk(KERN_ERR "Invalid attributes\n");
+ return -EINVAL;
+ }
+
+ retval = vme_check_window(aspace, vme_base, size);
+ if (retval)
+ return retval;
+
+ return bridge->slave_set(image, enabled, vme_base, size, buf_base,
+ aspace, cycle);
+}
+EXPORT_SYMBOL(vme_slave_set);
+
+/**
+ * vme_slave_get - Retrieve VME slave window configuration.
+ * @resource: Pointer to VME slave resource.
+ * @enabled: Pointer to variable for storing state.
+ * @vme_base: Pointer to variable for storing window base address.
+ * @size: Pointer to variable for storing window size.
+ * @buf_base: Pointer to variable for storing slave buffer base address.
+ * @aspace: Pointer to variable for storing VME address space.
+ * @cycle: Pointer to variable for storing VME data transfer cycle type.
+ *
+ * Return configuration for provided VME slave window.
+ *
+ * Return: Zero on success, -EINVAL if operation is not supported on this
+ * device or if an invalid resource has been provided.
+ */
+int vme_slave_get(struct vme_resource *resource, int *enabled,
+ unsigned long long *vme_base, unsigned long long *size,
+ dma_addr_t *buf_base, u32 *aspace, u32 *cycle)
+{
+ struct vme_bridge *bridge = find_bridge(resource);
+ struct vme_slave_resource *image;
+
+ if (resource->type != VME_SLAVE) {
+ printk(KERN_ERR "Not a slave resource\n");
+ return -EINVAL;
+ }
+
+ image = list_entry(resource->entry, struct vme_slave_resource, list);
+
+ if (!bridge->slave_get) {
+ printk(KERN_ERR "vme_slave_get not supported\n");
+ return -EINVAL;
+ }
+
+ return bridge->slave_get(image, enabled, vme_base, size, buf_base,
+ aspace, cycle);
+}
+EXPORT_SYMBOL(vme_slave_get);
+
+/**
+ * vme_slave_free - Free VME slave window
+ * @resource: Pointer to VME slave resource.
+ *
+ * Free the provided slave resource so that it may be reallocated.
+ */
+void vme_slave_free(struct vme_resource *resource)
+{
+ struct vme_slave_resource *slave_image;
+
+ if (resource->type != VME_SLAVE) {
+ printk(KERN_ERR "Not a slave resource\n");
+ return;
+ }
+
+ slave_image = list_entry(resource->entry, struct vme_slave_resource,
+ list);
+ if (!slave_image) {
+ printk(KERN_ERR "Can't find slave resource\n");
+ return;
+ }
+
+ /* Unlock image */
+ mutex_lock(&slave_image->mtx);
+ if (slave_image->locked == 0)
+ printk(KERN_ERR "Image is already free\n");
+
+ slave_image->locked = 0;
+ mutex_unlock(&slave_image->mtx);
+
+ /* Free up resource memory */
+ kfree(resource);
+}
+EXPORT_SYMBOL(vme_slave_free);
+
+/**
+ * vme_master_request - Request a VME master window resource.
+ * @vdev: Pointer to VME device struct vme_dev assigned to driver instance.
+ * @address: Required VME address space.
+ * @cycle: Required VME data transfer cycle type.
+ * @dwidth: Required VME data transfer width.
+ *
+ * Request use of a VME window resource capable of being set for the requested
+ * address space, data transfer cycle and width.
+ *
+ * Return: Pointer to VME resource on success, NULL on failure.
+ */
+struct vme_resource *vme_master_request(struct vme_dev *vdev, u32 address,
+ u32 cycle, u32 dwidth)
+{
+ struct vme_bridge *bridge;
+ struct list_head *master_pos = NULL;
+ struct vme_master_resource *allocated_image = NULL;
+ struct vme_master_resource *master_image = NULL;
+ struct vme_resource *resource = NULL;
+
+ bridge = vdev->bridge;
+ if (!bridge) {
+ printk(KERN_ERR "Can't find VME bus\n");
+ goto err_bus;
+ }
+
+ /* Loop through master resources */
+ list_for_each(master_pos, &bridge->master_resources) {
+ master_image = list_entry(master_pos,
+ struct vme_master_resource, list);
+
+ if (!master_image) {
+ printk(KERN_WARNING "Registered NULL master resource\n");
+ continue;
+ }
+
+ /* Find an unlocked and compatible image */
+ spin_lock(&master_image->lock);
+ if (((master_image->address_attr & address) == address) &&
+ ((master_image->cycle_attr & cycle) == cycle) &&
+ ((master_image->width_attr & dwidth) == dwidth) &&
+ (master_image->locked == 0)) {
+
+ master_image->locked = 1;
+ spin_unlock(&master_image->lock);
+ allocated_image = master_image;
+ break;
+ }
+ spin_unlock(&master_image->lock);
+ }
+
+ /* Check to see if we found a resource */
+ if (!allocated_image) {
+ printk(KERN_ERR "Can't find a suitable resource\n");
+ goto err_image;
+ }
+
+ resource = kmalloc(sizeof(*resource), GFP_KERNEL);
+ if (!resource)
+ goto err_alloc;
+
+ resource->type = VME_MASTER;
+ resource->entry = &allocated_image->list;
+
+ return resource;
+
+err_alloc:
+ /* Unlock image */
+ spin_lock(&master_image->lock);
+ master_image->locked = 0;
+ spin_unlock(&master_image->lock);
+err_image:
+err_bus:
+ return NULL;
+}
+EXPORT_SYMBOL(vme_master_request);
+
+/**
+ * vme_master_set - Set VME master window configuration.
+ * @resource: Pointer to VME master resource.
+ * @enabled: State to which the window should be configured.
+ * @vme_base: Base address for the window.
+ * @size: Size of the VME window.
+ * @aspace: VME address space for the VME window.
+ * @cycle: VME data transfer cycle type for the VME window.
+ * @dwidth: VME data transfer width for the VME window.
+ *
+ * Set configuration for provided VME master window.
+ *
+ * Return: Zero on success, -EINVAL if operation is not supported on this
+ * device, if an invalid resource has been provided or invalid
+ * attributes are provided. Hardware specific errors may also be
+ * returned.
+ */
+int vme_master_set(struct vme_resource *resource, int enabled,
+ unsigned long long vme_base, unsigned long long size, u32 aspace,
+ u32 cycle, u32 dwidth)
+{
+ struct vme_bridge *bridge = find_bridge(resource);
+ struct vme_master_resource *image;
+ int retval;
+
+ if (resource->type != VME_MASTER) {
+ printk(KERN_ERR "Not a master resource\n");
+ return -EINVAL;
+ }
+
+ image = list_entry(resource->entry, struct vme_master_resource, list);
+
+ if (!bridge->master_set) {
+ printk(KERN_WARNING "vme_master_set not supported\n");
+ return -EINVAL;
+ }
+
+ if (!(((image->address_attr & aspace) == aspace) &&
+ ((image->cycle_attr & cycle) == cycle) &&
+ ((image->width_attr & dwidth) == dwidth))) {
+ printk(KERN_WARNING "Invalid attributes\n");
+ return -EINVAL;
+ }
+
+ retval = vme_check_window(aspace, vme_base, size);
+ if (retval)
+ return retval;
+
+ return bridge->master_set(image, enabled, vme_base, size, aspace,
+ cycle, dwidth);
+}
+EXPORT_SYMBOL(vme_master_set);
+
+/**
+ * vme_master_get - Retrieve VME master window configuration.
+ * @resource: Pointer to VME master resource.
+ * @enabled: Pointer to variable for storing state.
+ * @vme_base: Pointer to variable for storing window base address.
+ * @size: Pointer to variable for storing window size.
+ * @aspace: Pointer to variable for storing VME address space.
+ * @cycle: Pointer to variable for storing VME data transfer cycle type.
+ * @dwidth: Pointer to variable for storing VME data transfer width.
+ *
+ * Return configuration for provided VME master window.
+ *
+ * Return: Zero on success, -EINVAL if operation is not supported on this
+ * device or if an invalid resource has been provided.
+ */
+int vme_master_get(struct vme_resource *resource, int *enabled,
+ unsigned long long *vme_base, unsigned long long *size, u32 *aspace,
+ u32 *cycle, u32 *dwidth)
+{
+ struct vme_bridge *bridge = find_bridge(resource);
+ struct vme_master_resource *image;
+
+ if (resource->type != VME_MASTER) {
+ printk(KERN_ERR "Not a master resource\n");
+ return -EINVAL;
+ }
+
+ image = list_entry(resource->entry, struct vme_master_resource, list);
+
+ if (!bridge->master_get) {
+ printk(KERN_WARNING "%s not supported\n", __func__);
+ return -EINVAL;
+ }
+
+ return bridge->master_get(image, enabled, vme_base, size, aspace,
+ cycle, dwidth);
+}
+EXPORT_SYMBOL(vme_master_get);
+
+/**
+ * vme_master_read - Read data from VME space into a buffer.
+ * @resource: Pointer to VME master resource.
+ * @buf: Pointer to buffer where data should be transferred.
+ * @count: Number of bytes to transfer.
+ * @offset: Offset into VME master window at which to start transfer.
+ *
+ * Perform read of count bytes of data from location on VME bus which maps into
+ * the VME master window at offset to buf.
+ *
+ * Return: Number of bytes read, -EINVAL if resource is not a VME master
+ * resource or read operation is not supported. -EFAULT returned if
+ * invalid offset is provided. Hardware specific errors may also be
+ * returned.
+ */
+ssize_t vme_master_read(struct vme_resource *resource, void *buf, size_t count,
+ loff_t offset)
+{
+ struct vme_bridge *bridge = find_bridge(resource);
+ struct vme_master_resource *image;
+ size_t length;
+
+ if (!bridge->master_read) {
+ printk(KERN_WARNING "Reading from resource not supported\n");
+ return -EINVAL;
+ }
+
+ if (resource->type != VME_MASTER) {
+ printk(KERN_ERR "Not a master resource\n");
+ return -EINVAL;
+ }
+
+ image = list_entry(resource->entry, struct vme_master_resource, list);
+
+ length = vme_get_size(resource);
+
+ if (offset > length) {
+ printk(KERN_WARNING "Invalid Offset\n");
+ return -EFAULT;
+ }
+
+ if ((offset + count) > length)
+ count = length - offset;
+
+ return bridge->master_read(image, buf, count, offset);
+
+}
+EXPORT_SYMBOL(vme_master_read);
+
+/**
+ * vme_master_write - Write data out to VME space from a buffer.
+ * @resource: Pointer to VME master resource.
+ * @buf: Pointer to buffer holding data to transfer.
+ * @count: Number of bytes to transfer.
+ * @offset: Offset into VME master window at which to start transfer.
+ *
+ * Perform write of count bytes of data from buf to location on VME bus which
+ * maps into the VME master window at offset.
+ *
+ * Return: Number of bytes written, -EINVAL if resource is not a VME master
+ * resource or write operation is not supported. -EFAULT returned if
+ * invalid offset is provided. Hardware specific errors may also be
+ * returned.
+ */
+ssize_t vme_master_write(struct vme_resource *resource, void *buf,
+ size_t count, loff_t offset)
+{
+ struct vme_bridge *bridge = find_bridge(resource);
+ struct vme_master_resource *image;
+ size_t length;
+
+ if (!bridge->master_write) {
+ printk(KERN_WARNING "Writing to resource not supported\n");
+ return -EINVAL;
+ }
+
+ if (resource->type != VME_MASTER) {
+ printk(KERN_ERR "Not a master resource\n");
+ return -EINVAL;
+ }
+
+ image = list_entry(resource->entry, struct vme_master_resource, list);
+
+ length = vme_get_size(resource);
+
+ if (offset > length) {
+ printk(KERN_WARNING "Invalid Offset\n");
+ return -EFAULT;
+ }
+
+ if ((offset + count) > length)
+ count = length - offset;
+
+ return bridge->master_write(image, buf, count, offset);
+}
+EXPORT_SYMBOL(vme_master_write);
+
+/**
+ * vme_master_rmw - Perform read-modify-write cycle.
+ * @resource: Pointer to VME master resource.
+ * @mask: Bits to be compared and swapped in operation.
+ * @compare: Bits to be compared with data read from offset.
+ * @swap: Bits to be swapped in data read from offset.
+ * @offset: Offset into VME master window at which to perform operation.
+ *
+ * Perform read-modify-write cycle on provided location:
+ * - Location on VME bus is read.
+ * - Bits selected by mask are compared with compare.
+ * - Where a selected bit matches that in compare and are selected in swap,
+ * the bit is swapped.
+ * - Result written back to location on VME bus.
+ *
+ * Return: Bytes written on success, -EINVAL if resource is not a VME master
+ * resource or RMW operation is not supported. Hardware specific
+ * errors may also be returned.
+ */
+unsigned int vme_master_rmw(struct vme_resource *resource, unsigned int mask,
+ unsigned int compare, unsigned int swap, loff_t offset)
+{
+ struct vme_bridge *bridge = find_bridge(resource);
+ struct vme_master_resource *image;
+
+ if (!bridge->master_rmw) {
+ printk(KERN_WARNING "Writing to resource not supported\n");
+ return -EINVAL;
+ }
+
+ if (resource->type != VME_MASTER) {
+ printk(KERN_ERR "Not a master resource\n");
+ return -EINVAL;
+ }
+
+ image = list_entry(resource->entry, struct vme_master_resource, list);
+
+ return bridge->master_rmw(image, mask, compare, swap, offset);
+}
+EXPORT_SYMBOL(vme_master_rmw);
+
+/**
+ * vme_master_mmap - Mmap region of VME master window.
+ * @resource: Pointer to VME master resource.
+ * @vma: Pointer to definition of user mapping.
+ *
+ * Memory map a region of the VME master window into user space.
+ *
+ * Return: Zero on success, -EINVAL if resource is not a VME master
+ * resource or -EFAULT if map exceeds window size. Other generic mmap
+ * errors may also be returned.
+ */
+int vme_master_mmap(struct vme_resource *resource, struct vm_area_struct *vma)
+{
+ struct vme_master_resource *image;
+ phys_addr_t phys_addr;
+ unsigned long vma_size;
+
+ if (resource->type != VME_MASTER) {
+ pr_err("Not a master resource\n");
+ return -EINVAL;
+ }
+
+ image = list_entry(resource->entry, struct vme_master_resource, list);
+ phys_addr = image->bus_resource.start + (vma->vm_pgoff << PAGE_SHIFT);
+ vma_size = vma->vm_end - vma->vm_start;
+
+ if (phys_addr + vma_size > image->bus_resource.end + 1) {
+ pr_err("Map size cannot exceed the window size\n");
+ return -EFAULT;
+ }
+
+ vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+
+ return vm_iomap_memory(vma, phys_addr, vma->vm_end - vma->vm_start);
+}
+EXPORT_SYMBOL(vme_master_mmap);
+
+/**
+ * vme_master_free - Free VME master window
+ * @resource: Pointer to VME master resource.
+ *
+ * Free the provided master resource so that it may be reallocated.
+ */
+void vme_master_free(struct vme_resource *resource)
+{
+ struct vme_master_resource *master_image;
+
+ if (resource->type != VME_MASTER) {
+ printk(KERN_ERR "Not a master resource\n");
+ return;
+ }
+
+ master_image = list_entry(resource->entry, struct vme_master_resource,
+ list);
+ if (!master_image) {
+ printk(KERN_ERR "Can't find master resource\n");
+ return;
+ }
+
+ /* Unlock image */
+ spin_lock(&master_image->lock);
+ if (master_image->locked == 0)
+ printk(KERN_ERR "Image is already free\n");
+
+ master_image->locked = 0;
+ spin_unlock(&master_image->lock);
+
+ /* Free up resource memory */
+ kfree(resource);
+}
+EXPORT_SYMBOL(vme_master_free);
+
+/**
+ * vme_dma_request - Request a DMA controller.
+ * @vdev: Pointer to VME device struct vme_dev assigned to driver instance.
+ * @route: Required src/destination combination.
+ *
+ * Request a VME DMA controller with capability to perform transfers bewteen
+ * requested source/destination combination.
+ *
+ * Return: Pointer to VME DMA resource on success, NULL on failure.
+ */
+struct vme_resource *vme_dma_request(struct vme_dev *vdev, u32 route)
+{
+ struct vme_bridge *bridge;
+ struct list_head *dma_pos = NULL;
+ struct vme_dma_resource *allocated_ctrlr = NULL;
+ struct vme_dma_resource *dma_ctrlr = NULL;
+ struct vme_resource *resource = NULL;
+
+ /* XXX Not checking resource attributes */
+ printk(KERN_ERR "No VME resource Attribute tests done\n");
+
+ bridge = vdev->bridge;
+ if (!bridge) {
+ printk(KERN_ERR "Can't find VME bus\n");
+ goto err_bus;
+ }
+
+ /* Loop through DMA resources */
+ list_for_each(dma_pos, &bridge->dma_resources) {
+ dma_ctrlr = list_entry(dma_pos,
+ struct vme_dma_resource, list);
+ if (!dma_ctrlr) {
+ printk(KERN_ERR "Registered NULL DMA resource\n");
+ continue;
+ }
+
+ /* Find an unlocked and compatible controller */
+ mutex_lock(&dma_ctrlr->mtx);
+ if (((dma_ctrlr->route_attr & route) == route) &&
+ (dma_ctrlr->locked == 0)) {
+
+ dma_ctrlr->locked = 1;
+ mutex_unlock(&dma_ctrlr->mtx);
+ allocated_ctrlr = dma_ctrlr;
+ break;
+ }
+ mutex_unlock(&dma_ctrlr->mtx);
+ }
+
+ /* Check to see if we found a resource */
+ if (!allocated_ctrlr)
+ goto err_ctrlr;
+
+ resource = kmalloc(sizeof(*resource), GFP_KERNEL);
+ if (!resource)
+ goto err_alloc;
+
+ resource->type = VME_DMA;
+ resource->entry = &allocated_ctrlr->list;
+
+ return resource;
+
+err_alloc:
+ /* Unlock image */
+ mutex_lock(&dma_ctrlr->mtx);
+ dma_ctrlr->locked = 0;
+ mutex_unlock(&dma_ctrlr->mtx);
+err_ctrlr:
+err_bus:
+ return NULL;
+}
+EXPORT_SYMBOL(vme_dma_request);
+
+/**
+ * vme_new_dma_list - Create new VME DMA list.
+ * @resource: Pointer to VME DMA resource.
+ *
+ * Create a new VME DMA list. It is the responsibility of the user to free
+ * the list once it is no longer required with vme_dma_list_free().
+ *
+ * Return: Pointer to new VME DMA list, NULL on allocation failure or invalid
+ * VME DMA resource.
+ */
+struct vme_dma_list *vme_new_dma_list(struct vme_resource *resource)
+{
+ struct vme_dma_list *dma_list;
+
+ if (resource->type != VME_DMA) {
+ printk(KERN_ERR "Not a DMA resource\n");
+ return NULL;
+ }
+
+ dma_list = kmalloc(sizeof(*dma_list), GFP_KERNEL);
+ if (!dma_list)
+ return NULL;
+
+ INIT_LIST_HEAD(&dma_list->entries);
+ dma_list->parent = list_entry(resource->entry,
+ struct vme_dma_resource,
+ list);
+ mutex_init(&dma_list->mtx);
+
+ return dma_list;
+}
+EXPORT_SYMBOL(vme_new_dma_list);
+
+/**
+ * vme_dma_pattern_attribute - Create "Pattern" type VME DMA list attribute.
+ * @pattern: Value to use used as pattern
+ * @type: Type of pattern to be written.
+ *
+ * Create VME DMA list attribute for pattern generation. It is the
+ * responsibility of the user to free used attributes using
+ * vme_dma_free_attribute().
+ *
+ * Return: Pointer to VME DMA attribute, NULL on failure.
+ */
+struct vme_dma_attr *vme_dma_pattern_attribute(u32 pattern, u32 type)
+{
+ struct vme_dma_attr *attributes;
+ struct vme_dma_pattern *pattern_attr;
+
+ attributes = kmalloc(sizeof(*attributes), GFP_KERNEL);
+ if (!attributes)
+ goto err_attr;
+
+ pattern_attr = kmalloc(sizeof(*pattern_attr), GFP_KERNEL);
+ if (!pattern_attr)
+ goto err_pat;
+
+ attributes->type = VME_DMA_PATTERN;
+ attributes->private = (void *)pattern_attr;
+
+ pattern_attr->pattern = pattern;
+ pattern_attr->type = type;
+
+ return attributes;
+
+err_pat:
+ kfree(attributes);
+err_attr:
+ return NULL;
+}
+EXPORT_SYMBOL(vme_dma_pattern_attribute);
+
+/**
+ * vme_dma_pci_attribute - Create "PCI" type VME DMA list attribute.
+ * @address: PCI base address for DMA transfer.
+ *
+ * Create VME DMA list attribute pointing to a location on PCI for DMA
+ * transfers. It is the responsibility of the user to free used attributes
+ * using vme_dma_free_attribute().
+ *
+ * Return: Pointer to VME DMA attribute, NULL on failure.
+ */
+struct vme_dma_attr *vme_dma_pci_attribute(dma_addr_t address)
+{
+ struct vme_dma_attr *attributes;
+ struct vme_dma_pci *pci_attr;
+
+ /* XXX Run some sanity checks here */
+
+ attributes = kmalloc(sizeof(*attributes), GFP_KERNEL);
+ if (!attributes)
+ goto err_attr;
+
+ pci_attr = kmalloc(sizeof(*pci_attr), GFP_KERNEL);
+ if (!pci_attr)
+ goto err_pci;
+
+ attributes->type = VME_DMA_PCI;
+ attributes->private = (void *)pci_attr;
+
+ pci_attr->address = address;
+
+ return attributes;
+
+err_pci:
+ kfree(attributes);
+err_attr:
+ return NULL;
+}
+EXPORT_SYMBOL(vme_dma_pci_attribute);
+
+/**
+ * vme_dma_vme_attribute - Create "VME" type VME DMA list attribute.
+ * @address: VME base address for DMA transfer.
+ * @aspace: VME address space to use for DMA transfer.
+ * @cycle: VME bus cycle to use for DMA transfer.
+ * @dwidth: VME data width to use for DMA transfer.
+ *
+ * Create VME DMA list attribute pointing to a location on the VME bus for DMA
+ * transfers. It is the responsibility of the user to free used attributes
+ * using vme_dma_free_attribute().
+ *
+ * Return: Pointer to VME DMA attribute, NULL on failure.
+ */
+struct vme_dma_attr *vme_dma_vme_attribute(unsigned long long address,
+ u32 aspace, u32 cycle, u32 dwidth)
+{
+ struct vme_dma_attr *attributes;
+ struct vme_dma_vme *vme_attr;
+
+ attributes = kmalloc(sizeof(*attributes), GFP_KERNEL);
+ if (!attributes)
+ goto err_attr;
+
+ vme_attr = kmalloc(sizeof(*vme_attr), GFP_KERNEL);
+ if (!vme_attr)
+ goto err_vme;
+
+ attributes->type = VME_DMA_VME;
+ attributes->private = (void *)vme_attr;
+
+ vme_attr->address = address;
+ vme_attr->aspace = aspace;
+ vme_attr->cycle = cycle;
+ vme_attr->dwidth = dwidth;
+
+ return attributes;
+
+err_vme:
+ kfree(attributes);
+err_attr:
+ return NULL;
+}
+EXPORT_SYMBOL(vme_dma_vme_attribute);
+
+/**
+ * vme_dma_free_attribute - Free DMA list attribute.
+ * @attributes: Pointer to DMA list attribute.
+ *
+ * Free VME DMA list attribute. VME DMA list attributes can be safely freed
+ * once vme_dma_list_add() has returned.
+ */
+void vme_dma_free_attribute(struct vme_dma_attr *attributes)
+{
+ kfree(attributes->private);
+ kfree(attributes);
+}
+EXPORT_SYMBOL(vme_dma_free_attribute);
+
+/**
+ * vme_dma_list_add - Add enty to a VME DMA list.
+ * @list: Pointer to VME list.
+ * @src: Pointer to DMA list attribute to use as source.
+ * @dest: Pointer to DMA list attribute to use as destination.
+ * @count: Number of bytes to transfer.
+ *
+ * Add an entry to the provided VME DMA list. Entry requires pointers to source
+ * and destination DMA attributes and a count.
+ *
+ * Please note, the attributes supported as source and destinations for
+ * transfers are hardware dependent.
+ *
+ * Return: Zero on success, -EINVAL if operation is not supported on this
+ * device or if the link list has already been submitted for execution.
+ * Hardware specific errors also possible.
+ */
+int vme_dma_list_add(struct vme_dma_list *list, struct vme_dma_attr *src,
+ struct vme_dma_attr *dest, size_t count)
+{
+ struct vme_bridge *bridge = list->parent->parent;
+ int retval;
+
+ if (!bridge->dma_list_add) {
+ printk(KERN_WARNING "Link List DMA generation not supported\n");
+ return -EINVAL;
+ }
+
+ if (!mutex_trylock(&list->mtx)) {
+ printk(KERN_ERR "Link List already submitted\n");
+ return -EINVAL;
+ }
+
+ retval = bridge->dma_list_add(list, src, dest, count);
+
+ mutex_unlock(&list->mtx);
+
+ return retval;
+}
+EXPORT_SYMBOL(vme_dma_list_add);
+
+/**
+ * vme_dma_list_exec - Queue a VME DMA list for execution.
+ * @list: Pointer to VME list.
+ *
+ * Queue the provided VME DMA list for execution. The call will return once the
+ * list has been executed.
+ *
+ * Return: Zero on success, -EINVAL if operation is not supported on this
+ * device. Hardware specific errors also possible.
+ */
+int vme_dma_list_exec(struct vme_dma_list *list)
+{
+ struct vme_bridge *bridge = list->parent->parent;
+ int retval;
+
+ if (!bridge->dma_list_exec) {
+ printk(KERN_ERR "Link List DMA execution not supported\n");
+ return -EINVAL;
+ }
+
+ mutex_lock(&list->mtx);
+
+ retval = bridge->dma_list_exec(list);
+
+ mutex_unlock(&list->mtx);
+
+ return retval;
+}
+EXPORT_SYMBOL(vme_dma_list_exec);
+
+/**
+ * vme_dma_list_free - Free a VME DMA list.
+ * @list: Pointer to VME list.
+ *
+ * Free the provided DMA list and all its entries.
+ *
+ * Return: Zero on success, -EINVAL on invalid VME resource, -EBUSY if resource
+ * is still in use. Hardware specific errors also possible.
+ */
+int vme_dma_list_free(struct vme_dma_list *list)
+{
+ struct vme_bridge *bridge = list->parent->parent;
+ int retval;
+
+ if (!bridge->dma_list_empty) {
+ printk(KERN_WARNING "Emptying of Link Lists not supported\n");
+ return -EINVAL;
+ }
+
+ if (!mutex_trylock(&list->mtx)) {
+ printk(KERN_ERR "Link List in use\n");
+ return -EBUSY;
+ }
+
+ /*
+ * Empty out all of the entries from the DMA list. We need to go to the
+ * low level driver as DMA entries are driver specific.
+ */
+ retval = bridge->dma_list_empty(list);
+ if (retval) {
+ printk(KERN_ERR "Unable to empty link-list entries\n");
+ mutex_unlock(&list->mtx);
+ return retval;
+ }
+ mutex_unlock(&list->mtx);
+ kfree(list);
+
+ return retval;
+}
+EXPORT_SYMBOL(vme_dma_list_free);
+
+/**
+ * vme_dma_free - Free a VME DMA resource.
+ * @resource: Pointer to VME DMA resource.
+ *
+ * Free the provided DMA resource so that it may be reallocated.
+ *
+ * Return: Zero on success, -EINVAL on invalid VME resource, -EBUSY if resource
+ * is still active.
+ */
+int vme_dma_free(struct vme_resource *resource)
+{
+ struct vme_dma_resource *ctrlr;
+
+ if (resource->type != VME_DMA) {
+ printk(KERN_ERR "Not a DMA resource\n");
+ return -EINVAL;
+ }
+
+ ctrlr = list_entry(resource->entry, struct vme_dma_resource, list);
+
+ if (!mutex_trylock(&ctrlr->mtx)) {
+ printk(KERN_ERR "Resource busy, can't free\n");
+ return -EBUSY;
+ }
+
+ if (!(list_empty(&ctrlr->pending) && list_empty(&ctrlr->running))) {
+ printk(KERN_WARNING "Resource still processing transfers\n");
+ mutex_unlock(&ctrlr->mtx);
+ return -EBUSY;
+ }
+
+ ctrlr->locked = 0;
+
+ mutex_unlock(&ctrlr->mtx);
+
+ kfree(resource);
+
+ return 0;
+}
+EXPORT_SYMBOL(vme_dma_free);
+
+void vme_bus_error_handler(struct vme_bridge *bridge,
+ unsigned long long address, int am)
+{
+ struct list_head *handler_pos = NULL;
+ struct vme_error_handler *handler;
+ int handler_triggered = 0;
+ u32 aspace = vme_get_aspace(am);
+
+ list_for_each(handler_pos, &bridge->vme_error_handlers) {
+ handler = list_entry(handler_pos, struct vme_error_handler,
+ list);
+ if ((aspace == handler->aspace) &&
+ (address >= handler->start) &&
+ (address < handler->end)) {
+ if (!handler->num_errors)
+ handler->first_error = address;
+ if (handler->num_errors != UINT_MAX)
+ handler->num_errors++;
+ handler_triggered = 1;
+ }
+ }
+
+ if (!handler_triggered)
+ dev_err(bridge->parent,
+ "Unhandled VME access error at address 0x%llx\n",
+ address);
+}
+EXPORT_SYMBOL(vme_bus_error_handler);
+
+struct vme_error_handler *vme_register_error_handler(
+ struct vme_bridge *bridge, u32 aspace,
+ unsigned long long address, size_t len)
+{
+ struct vme_error_handler *handler;
+
+ handler = kmalloc(sizeof(*handler), GFP_ATOMIC);
+ if (!handler)
+ return NULL;
+
+ handler->aspace = aspace;
+ handler->start = address;
+ handler->end = address + len;
+ handler->num_errors = 0;
+ handler->first_error = 0;
+ list_add_tail(&handler->list, &bridge->vme_error_handlers);
+
+ return handler;
+}
+EXPORT_SYMBOL(vme_register_error_handler);
+
+void vme_unregister_error_handler(struct vme_error_handler *handler)
+{
+ list_del(&handler->list);
+ kfree(handler);
+}
+EXPORT_SYMBOL(vme_unregister_error_handler);
+
+void vme_irq_handler(struct vme_bridge *bridge, int level, int statid)
+{
+ void (*call)(int, int, void *);
+ void *priv_data;
+
+ call = bridge->irq[level - 1].callback[statid].func;
+ priv_data = bridge->irq[level - 1].callback[statid].priv_data;
+ if (call)
+ call(level, statid, priv_data);
+ else
+ printk(KERN_WARNING "Spurious VME interrupt, level:%x, vector:%x\n",
+ level, statid);
+}
+EXPORT_SYMBOL(vme_irq_handler);
+
+/**
+ * vme_irq_request - Request a specific VME interrupt.
+ * @vdev: Pointer to VME device struct vme_dev assigned to driver instance.
+ * @level: Interrupt priority being requested.
+ * @statid: Interrupt vector being requested.
+ * @callback: Pointer to callback function called when VME interrupt/vector
+ * received.
+ * @priv_data: Generic pointer that will be passed to the callback function.
+ *
+ * Request callback to be attached as a handler for VME interrupts with provided
+ * level and statid.
+ *
+ * Return: Zero on success, -EINVAL on invalid vme device, level or if the
+ * function is not supported, -EBUSY if the level/statid combination is
+ * already in use. Hardware specific errors also possible.
+ */
+int vme_irq_request(struct vme_dev *vdev, int level, int statid,
+ void (*callback)(int, int, void *),
+ void *priv_data)
+{
+ struct vme_bridge *bridge;
+
+ bridge = vdev->bridge;
+ if (!bridge) {
+ printk(KERN_ERR "Can't find VME bus\n");
+ return -EINVAL;
+ }
+
+ if ((level < 1) || (level > 7)) {
+ printk(KERN_ERR "Invalid interrupt level\n");
+ return -EINVAL;
+ }
+
+ if (!bridge->irq_set) {
+ printk(KERN_ERR "Configuring interrupts not supported\n");
+ return -EINVAL;
+ }
+
+ mutex_lock(&bridge->irq_mtx);
+
+ if (bridge->irq[level - 1].callback[statid].func) {
+ mutex_unlock(&bridge->irq_mtx);
+ printk(KERN_WARNING "VME Interrupt already taken\n");
+ return -EBUSY;
+ }
+
+ bridge->irq[level - 1].count++;
+ bridge->irq[level - 1].callback[statid].priv_data = priv_data;
+ bridge->irq[level - 1].callback[statid].func = callback;
+
+ /* Enable IRQ level */
+ bridge->irq_set(bridge, level, 1, 1);
+
+ mutex_unlock(&bridge->irq_mtx);
+
+ return 0;
+}
+EXPORT_SYMBOL(vme_irq_request);
+
+/**
+ * vme_irq_free - Free a VME interrupt.
+ * @vdev: Pointer to VME device struct vme_dev assigned to driver instance.
+ * @level: Interrupt priority of interrupt being freed.
+ * @statid: Interrupt vector of interrupt being freed.
+ *
+ * Remove previously attached callback from VME interrupt priority/vector.
+ */
+void vme_irq_free(struct vme_dev *vdev, int level, int statid)
+{
+ struct vme_bridge *bridge;
+
+ bridge = vdev->bridge;
+ if (!bridge) {
+ printk(KERN_ERR "Can't find VME bus\n");
+ return;
+ }
+
+ if ((level < 1) || (level > 7)) {
+ printk(KERN_ERR "Invalid interrupt level\n");
+ return;
+ }
+
+ if (!bridge->irq_set) {
+ printk(KERN_ERR "Configuring interrupts not supported\n");
+ return;
+ }
+
+ mutex_lock(&bridge->irq_mtx);
+
+ bridge->irq[level - 1].count--;
+
+ /* Disable IRQ level if no more interrupts attached at this level*/
+ if (bridge->irq[level - 1].count == 0)
+ bridge->irq_set(bridge, level, 0, 1);
+
+ bridge->irq[level - 1].callback[statid].func = NULL;
+ bridge->irq[level - 1].callback[statid].priv_data = NULL;
+
+ mutex_unlock(&bridge->irq_mtx);
+}
+EXPORT_SYMBOL(vme_irq_free);
+
+/**
+ * vme_irq_generate - Generate VME interrupt.
+ * @vdev: Pointer to VME device struct vme_dev assigned to driver instance.
+ * @level: Interrupt priority at which to assert the interrupt.
+ * @statid: Interrupt vector to associate with the interrupt.
+ *
+ * Generate a VME interrupt of the provided level and with the provided
+ * statid.
+ *
+ * Return: Zero on success, -EINVAL on invalid vme device, level or if the
+ * function is not supported. Hardware specific errors also possible.
+ */
+int vme_irq_generate(struct vme_dev *vdev, int level, int statid)
+{
+ struct vme_bridge *bridge;
+
+ bridge = vdev->bridge;
+ if (!bridge) {
+ printk(KERN_ERR "Can't find VME bus\n");
+ return -EINVAL;
+ }
+
+ if ((level < 1) || (level > 7)) {
+ printk(KERN_WARNING "Invalid interrupt level\n");
+ return -EINVAL;
+ }
+
+ if (!bridge->irq_generate) {
+ printk(KERN_WARNING "Interrupt generation not supported\n");
+ return -EINVAL;
+ }
+
+ return bridge->irq_generate(bridge, level, statid);
+}
+EXPORT_SYMBOL(vme_irq_generate);
+
+/**
+ * vme_lm_request - Request a VME location monitor
+ * @vdev: Pointer to VME device struct vme_dev assigned to driver instance.
+ *
+ * Allocate a location monitor resource to the driver. A location monitor
+ * allows the driver to monitor accesses to a contiguous number of
+ * addresses on the VME bus.
+ *
+ * Return: Pointer to a VME resource on success or NULL on failure.
+ */
+struct vme_resource *vme_lm_request(struct vme_dev *vdev)
+{
+ struct vme_bridge *bridge;
+ struct list_head *lm_pos = NULL;
+ struct vme_lm_resource *allocated_lm = NULL;
+ struct vme_lm_resource *lm = NULL;
+ struct vme_resource *resource = NULL;
+
+ bridge = vdev->bridge;
+ if (!bridge) {
+ printk(KERN_ERR "Can't find VME bus\n");
+ goto err_bus;
+ }
+
+ /* Loop through LM resources */
+ list_for_each(lm_pos, &bridge->lm_resources) {
+ lm = list_entry(lm_pos,
+ struct vme_lm_resource, list);
+ if (!lm) {
+ printk(KERN_ERR "Registered NULL Location Monitor resource\n");
+ continue;
+ }
+
+ /* Find an unlocked controller */
+ mutex_lock(&lm->mtx);
+ if (lm->locked == 0) {
+ lm->locked = 1;
+ mutex_unlock(&lm->mtx);
+ allocated_lm = lm;
+ break;
+ }
+ mutex_unlock(&lm->mtx);
+ }
+
+ /* Check to see if we found a resource */
+ if (!allocated_lm)
+ goto err_lm;
+
+ resource = kmalloc(sizeof(*resource), GFP_KERNEL);
+ if (!resource)
+ goto err_alloc;
+
+ resource->type = VME_LM;
+ resource->entry = &allocated_lm->list;
+
+ return resource;
+
+err_alloc:
+ /* Unlock image */
+ mutex_lock(&lm->mtx);
+ lm->locked = 0;
+ mutex_unlock(&lm->mtx);
+err_lm:
+err_bus:
+ return NULL;
+}
+EXPORT_SYMBOL(vme_lm_request);
+
+/**
+ * vme_lm_count - Determine number of VME Addresses monitored
+ * @resource: Pointer to VME location monitor resource.
+ *
+ * The number of contiguous addresses monitored is hardware dependent.
+ * Return the number of contiguous addresses monitored by the
+ * location monitor.
+ *
+ * Return: Count of addresses monitored or -EINVAL when provided with an
+ * invalid location monitor resource.
+ */
+int vme_lm_count(struct vme_resource *resource)
+{
+ struct vme_lm_resource *lm;
+
+ if (resource->type != VME_LM) {
+ printk(KERN_ERR "Not a Location Monitor resource\n");
+ return -EINVAL;
+ }
+
+ lm = list_entry(resource->entry, struct vme_lm_resource, list);
+
+ return lm->monitors;
+}
+EXPORT_SYMBOL(vme_lm_count);
+
+/**
+ * vme_lm_set - Configure location monitor
+ * @resource: Pointer to VME location monitor resource.
+ * @lm_base: Base address to monitor.
+ * @aspace: VME address space to monitor.
+ * @cycle: VME bus cycle type to monitor.
+ *
+ * Set the base address, address space and cycle type of accesses to be
+ * monitored by the location monitor.
+ *
+ * Return: Zero on success, -EINVAL when provided with an invalid location
+ * monitor resource or function is not supported. Hardware specific
+ * errors may also be returned.
+ */
+int vme_lm_set(struct vme_resource *resource, unsigned long long lm_base,
+ u32 aspace, u32 cycle)
+{
+ struct vme_bridge *bridge = find_bridge(resource);
+ struct vme_lm_resource *lm;
+
+ if (resource->type != VME_LM) {
+ printk(KERN_ERR "Not a Location Monitor resource\n");
+ return -EINVAL;
+ }
+
+ lm = list_entry(resource->entry, struct vme_lm_resource, list);
+
+ if (!bridge->lm_set) {
+ printk(KERN_ERR "vme_lm_set not supported\n");
+ return -EINVAL;
+ }
+
+ return bridge->lm_set(lm, lm_base, aspace, cycle);
+}
+EXPORT_SYMBOL(vme_lm_set);
+
+/**
+ * vme_lm_get - Retrieve location monitor settings
+ * @resource: Pointer to VME location monitor resource.
+ * @lm_base: Pointer used to output the base address monitored.
+ * @aspace: Pointer used to output the address space monitored.
+ * @cycle: Pointer used to output the VME bus cycle type monitored.
+ *
+ * Retrieve the base address, address space and cycle type of accesses to
+ * be monitored by the location monitor.
+ *
+ * Return: Zero on success, -EINVAL when provided with an invalid location
+ * monitor resource or function is not supported. Hardware specific
+ * errors may also be returned.
+ */
+int vme_lm_get(struct vme_resource *resource, unsigned long long *lm_base,
+ u32 *aspace, u32 *cycle)
+{
+ struct vme_bridge *bridge = find_bridge(resource);
+ struct vme_lm_resource *lm;
+
+ if (resource->type != VME_LM) {
+ printk(KERN_ERR "Not a Location Monitor resource\n");
+ return -EINVAL;
+ }
+
+ lm = list_entry(resource->entry, struct vme_lm_resource, list);
+
+ if (!bridge->lm_get) {
+ printk(KERN_ERR "vme_lm_get not supported\n");
+ return -EINVAL;
+ }
+
+ return bridge->lm_get(lm, lm_base, aspace, cycle);
+}
+EXPORT_SYMBOL(vme_lm_get);
+
+/**
+ * vme_lm_attach - Provide callback for location monitor address
+ * @resource: Pointer to VME location monitor resource.
+ * @monitor: Offset to which callback should be attached.
+ * @callback: Pointer to callback function called when triggered.
+ * @data: Generic pointer that will be passed to the callback function.
+ *
+ * Attach a callback to the specificed offset into the location monitors
+ * monitored addresses. A generic pointer is provided to allow data to be
+ * passed to the callback when called.
+ *
+ * Return: Zero on success, -EINVAL when provided with an invalid location
+ * monitor resource or function is not supported. Hardware specific
+ * errors may also be returned.
+ */
+int vme_lm_attach(struct vme_resource *resource, int monitor,
+ void (*callback)(void *), void *data)
+{
+ struct vme_bridge *bridge = find_bridge(resource);
+ struct vme_lm_resource *lm;
+
+ if (resource->type != VME_LM) {
+ printk(KERN_ERR "Not a Location Monitor resource\n");
+ return -EINVAL;
+ }
+
+ lm = list_entry(resource->entry, struct vme_lm_resource, list);
+
+ if (!bridge->lm_attach) {
+ printk(KERN_ERR "vme_lm_attach not supported\n");
+ return -EINVAL;
+ }
+
+ return bridge->lm_attach(lm, monitor, callback, data);
+}
+EXPORT_SYMBOL(vme_lm_attach);
+
+/**
+ * vme_lm_detach - Remove callback for location monitor address
+ * @resource: Pointer to VME location monitor resource.
+ * @monitor: Offset to which callback should be removed.
+ *
+ * Remove the callback associated with the specificed offset into the
+ * location monitors monitored addresses.
+ *
+ * Return: Zero on success, -EINVAL when provided with an invalid location
+ * monitor resource or function is not supported. Hardware specific
+ * errors may also be returned.
+ */
+int vme_lm_detach(struct vme_resource *resource, int monitor)
+{
+ struct vme_bridge *bridge = find_bridge(resource);
+ struct vme_lm_resource *lm;
+
+ if (resource->type != VME_LM) {
+ printk(KERN_ERR "Not a Location Monitor resource\n");
+ return -EINVAL;
+ }
+
+ lm = list_entry(resource->entry, struct vme_lm_resource, list);
+
+ if (!bridge->lm_detach) {
+ printk(KERN_ERR "vme_lm_detach not supported\n");
+ return -EINVAL;
+ }
+
+ return bridge->lm_detach(lm, monitor);
+}
+EXPORT_SYMBOL(vme_lm_detach);
+
+/**
+ * vme_lm_free - Free allocated VME location monitor
+ * @resource: Pointer to VME location monitor resource.
+ *
+ * Free allocation of a VME location monitor.
+ *
+ * WARNING: This function currently expects that any callbacks that have
+ * been attached to the location monitor have been removed.
+ *
+ * Return: Zero on success, -EINVAL when provided with an invalid location
+ * monitor resource.
+ */
+void vme_lm_free(struct vme_resource *resource)
+{
+ struct vme_lm_resource *lm;
+
+ if (resource->type != VME_LM) {
+ printk(KERN_ERR "Not a Location Monitor resource\n");
+ return;
+ }
+
+ lm = list_entry(resource->entry, struct vme_lm_resource, list);
+
+ mutex_lock(&lm->mtx);
+
+ /* XXX
+ * Check to see that there aren't any callbacks still attached, if
+ * there are we should probably be detaching them!
+ */
+
+ lm->locked = 0;
+
+ mutex_unlock(&lm->mtx);
+
+ kfree(resource);
+}
+EXPORT_SYMBOL(vme_lm_free);
+
+/**
+ * vme_slot_num - Retrieve slot ID
+ * @vdev: Pointer to VME device struct vme_dev assigned to driver instance.
+ *
+ * Retrieve the slot ID associated with the provided VME device.
+ *
+ * Return: The slot ID on success, -EINVAL if VME bridge cannot be determined
+ * or the function is not supported. Hardware specific errors may also
+ * be returned.
+ */
+int vme_slot_num(struct vme_dev *vdev)
+{
+ struct vme_bridge *bridge;
+
+ bridge = vdev->bridge;
+ if (!bridge) {
+ printk(KERN_ERR "Can't find VME bus\n");
+ return -EINVAL;
+ }
+
+ if (!bridge->slot_get) {
+ printk(KERN_WARNING "vme_slot_num not supported\n");
+ return -EINVAL;
+ }
+
+ return bridge->slot_get(bridge);
+}
+EXPORT_SYMBOL(vme_slot_num);
+
+/**
+ * vme_bus_num - Retrieve bus number
+ * @vdev: Pointer to VME device struct vme_dev assigned to driver instance.
+ *
+ * Retrieve the bus enumeration associated with the provided VME device.
+ *
+ * Return: The bus number on success, -EINVAL if VME bridge cannot be
+ * determined.
+ */
+int vme_bus_num(struct vme_dev *vdev)
+{
+ struct vme_bridge *bridge;
+
+ bridge = vdev->bridge;
+ if (!bridge) {
+ pr_err("Can't find VME bus\n");
+ return -EINVAL;
+ }
+
+ return bridge->num;
+}
+EXPORT_SYMBOL(vme_bus_num);
+
+/* - Bridge Registration --------------------------------------------------- */
+
+static void vme_dev_release(struct device *dev)
+{
+ kfree(dev_to_vme_dev(dev));
+}
+
+/* Common bridge initialization */
+struct vme_bridge *vme_init_bridge(struct vme_bridge *bridge)
+{
+ INIT_LIST_HEAD(&bridge->vme_error_handlers);
+ INIT_LIST_HEAD(&bridge->master_resources);
+ INIT_LIST_HEAD(&bridge->slave_resources);
+ INIT_LIST_HEAD(&bridge->dma_resources);
+ INIT_LIST_HEAD(&bridge->lm_resources);
+ mutex_init(&bridge->irq_mtx);
+
+ return bridge;
+}
+EXPORT_SYMBOL(vme_init_bridge);
+
+int vme_register_bridge(struct vme_bridge *bridge)
+{
+ int i;
+ int ret = -1;
+
+ mutex_lock(&vme_buses_lock);
+ for (i = 0; i < sizeof(vme_bus_numbers) * 8; i++) {
+ if ((vme_bus_numbers & (1 << i)) == 0) {
+ vme_bus_numbers |= (1 << i);
+ bridge->num = i;
+ INIT_LIST_HEAD(&bridge->devices);
+ list_add_tail(&bridge->bus_list, &vme_bus_list);
+ ret = 0;
+ break;
+ }
+ }
+ mutex_unlock(&vme_buses_lock);
+
+ return ret;
+}
+EXPORT_SYMBOL(vme_register_bridge);
+
+void vme_unregister_bridge(struct vme_bridge *bridge)
+{
+ struct vme_dev *vdev;
+ struct vme_dev *tmp;
+
+ mutex_lock(&vme_buses_lock);
+ vme_bus_numbers &= ~(1 << bridge->num);
+ list_for_each_entry_safe(vdev, tmp, &bridge->devices, bridge_list) {
+ list_del(&vdev->drv_list);
+ list_del(&vdev->bridge_list);
+ device_unregister(&vdev->dev);
+ }
+ list_del(&bridge->bus_list);
+ mutex_unlock(&vme_buses_lock);
+}
+EXPORT_SYMBOL(vme_unregister_bridge);
+
+/* - Driver Registration --------------------------------------------------- */
+
+static int __vme_register_driver_bus(struct vme_driver *drv,
+ struct vme_bridge *bridge, unsigned int ndevs)
+{
+ int err;
+ unsigned int i;
+ struct vme_dev *vdev;
+ struct vme_dev *tmp;
+
+ for (i = 0; i < ndevs; i++) {
+ vdev = kzalloc(sizeof(*vdev), GFP_KERNEL);
+ if (!vdev) {
+ err = -ENOMEM;
+ goto err_devalloc;
+ }
+ vdev->num = i;
+ vdev->bridge = bridge;
+ vdev->dev.platform_data = drv;
+ vdev->dev.release = vme_dev_release;
+ vdev->dev.parent = bridge->parent;
+ vdev->dev.bus = &vme_bus_type;
+ dev_set_name(&vdev->dev, "%s.%u-%u", drv->name, bridge->num,
+ vdev->num);
+
+ err = device_register(&vdev->dev);
+ if (err)
+ goto err_reg;
+
+ if (vdev->dev.platform_data) {
+ list_add_tail(&vdev->drv_list, &drv->devices);
+ list_add_tail(&vdev->bridge_list, &bridge->devices);
+ } else
+ device_unregister(&vdev->dev);
+ }
+ return 0;
+
+err_reg:
+ put_device(&vdev->dev);
+err_devalloc:
+ list_for_each_entry_safe(vdev, tmp, &drv->devices, drv_list) {
+ list_del(&vdev->drv_list);
+ list_del(&vdev->bridge_list);
+ device_unregister(&vdev->dev);
+ }
+ return err;
+}
+
+static int __vme_register_driver(struct vme_driver *drv, unsigned int ndevs)
+{
+ struct vme_bridge *bridge;
+ int err = 0;
+
+ mutex_lock(&vme_buses_lock);
+ list_for_each_entry(bridge, &vme_bus_list, bus_list) {
+ /*
+ * This cannot cause trouble as we already have vme_buses_lock
+ * and if the bridge is removed, it will have to go through
+ * vme_unregister_bridge() to do it (which calls remove() on
+ * the bridge which in turn tries to acquire vme_buses_lock and
+ * will have to wait).
+ */
+ err = __vme_register_driver_bus(drv, bridge, ndevs);
+ if (err)
+ break;
+ }
+ mutex_unlock(&vme_buses_lock);
+ return err;
+}
+
+/**
+ * vme_register_driver - Register a VME driver
+ * @drv: Pointer to VME driver structure to register.
+ * @ndevs: Maximum number of devices to allow to be enumerated.
+ *
+ * Register a VME device driver with the VME subsystem.
+ *
+ * Return: Zero on success, error value on registration failure.
+ */
+int vme_register_driver(struct vme_driver *drv, unsigned int ndevs)
+{
+ int err;
+
+ drv->driver.name = drv->name;
+ drv->driver.bus = &vme_bus_type;
+ INIT_LIST_HEAD(&drv->devices);
+
+ err = driver_register(&drv->driver);
+ if (err)
+ return err;
+
+ err = __vme_register_driver(drv, ndevs);
+ if (err)
+ driver_unregister(&drv->driver);
+
+ return err;
+}
+EXPORT_SYMBOL(vme_register_driver);
+
+/**
+ * vme_unregister_driver - Unregister a VME driver
+ * @drv: Pointer to VME driver structure to unregister.
+ *
+ * Unregister a VME device driver from the VME subsystem.
+ */
+void vme_unregister_driver(struct vme_driver *drv)
+{
+ struct vme_dev *dev, *dev_tmp;
+
+ mutex_lock(&vme_buses_lock);
+ list_for_each_entry_safe(dev, dev_tmp, &drv->devices, drv_list) {
+ list_del(&dev->drv_list);
+ list_del(&dev->bridge_list);
+ device_unregister(&dev->dev);
+ }
+ mutex_unlock(&vme_buses_lock);
+
+ driver_unregister(&drv->driver);
+}
+EXPORT_SYMBOL(vme_unregister_driver);
+
+/* - Bus Registration ------------------------------------------------------ */
+
+static int vme_bus_match(struct device *dev, struct device_driver *drv)
+{
+ struct vme_driver *vme_drv;
+
+ vme_drv = container_of(drv, struct vme_driver, driver);
+
+ if (dev->platform_data == vme_drv) {
+ struct vme_dev *vdev = dev_to_vme_dev(dev);
+
+ if (vme_drv->match && vme_drv->match(vdev))
+ return 1;
+
+ dev->platform_data = NULL;
+ }
+ return 0;
+}
+
+static int vme_bus_probe(struct device *dev)
+{
+ struct vme_driver *driver;
+ struct vme_dev *vdev = dev_to_vme_dev(dev);
+
+ driver = dev->platform_data;
+ if (driver->probe)
+ return driver->probe(vdev);
+
+ return -ENODEV;
+}
+
+static void vme_bus_remove(struct device *dev)
+{
+ struct vme_driver *driver;
+ struct vme_dev *vdev = dev_to_vme_dev(dev);
+
+ driver = dev->platform_data;
+ if (driver->remove)
+ driver->remove(vdev);
+}
+
+struct bus_type vme_bus_type = {
+ .name = "vme",
+ .match = vme_bus_match,
+ .probe = vme_bus_probe,
+ .remove = vme_bus_remove,
+};
+EXPORT_SYMBOL(vme_bus_type);
+
+static int __init vme_init(void)
+{
+ return bus_register(&vme_bus_type);
+}
+subsys_initcall(vme_init);
diff --git a/drivers/staging/vme_user/vme.h b/drivers/staging/vme_user/vme.h
new file mode 100644
index 000000000000..b204a9b4be1b
--- /dev/null
+++ b/drivers/staging/vme_user/vme.h
@@ -0,0 +1,190 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _VME_H_
+#define _VME_H_
+
+/* Resource Type */
+enum vme_resource_type {
+ VME_MASTER,
+ VME_SLAVE,
+ VME_DMA,
+ VME_LM
+};
+
+/* VME Address Spaces */
+#define VME_A16 0x1
+#define VME_A24 0x2
+#define VME_A32 0x4
+#define VME_A64 0x8
+#define VME_CRCSR 0x10
+#define VME_USER1 0x20
+#define VME_USER2 0x40
+#define VME_USER3 0x80
+#define VME_USER4 0x100
+
+#define VME_A16_MAX 0x10000ULL
+#define VME_A24_MAX 0x1000000ULL
+#define VME_A32_MAX 0x100000000ULL
+#define VME_A64_MAX 0x10000000000000000ULL
+#define VME_CRCSR_MAX 0x1000000ULL
+
+
+/* VME Cycle Types */
+#define VME_SCT 0x1
+#define VME_BLT 0x2
+#define VME_MBLT 0x4
+#define VME_2eVME 0x8
+#define VME_2eSST 0x10
+#define VME_2eSSTB 0x20
+
+#define VME_2eSST160 0x100
+#define VME_2eSST267 0x200
+#define VME_2eSST320 0x400
+
+#define VME_SUPER 0x1000
+#define VME_USER 0x2000
+#define VME_PROG 0x4000
+#define VME_DATA 0x8000
+
+/* VME Data Widths */
+#define VME_D8 0x1
+#define VME_D16 0x2
+#define VME_D32 0x4
+#define VME_D64 0x8
+
+/* Arbitration Scheduling Modes */
+#define VME_R_ROBIN_MODE 0x1
+#define VME_PRIORITY_MODE 0x2
+
+#define VME_DMA_PATTERN (1<<0)
+#define VME_DMA_PCI (1<<1)
+#define VME_DMA_VME (1<<2)
+
+#define VME_DMA_PATTERN_BYTE (1<<0)
+#define VME_DMA_PATTERN_WORD (1<<1)
+#define VME_DMA_PATTERN_INCREMENT (1<<2)
+
+#define VME_DMA_VME_TO_MEM (1<<0)
+#define VME_DMA_MEM_TO_VME (1<<1)
+#define VME_DMA_VME_TO_VME (1<<2)
+#define VME_DMA_MEM_TO_MEM (1<<3)
+#define VME_DMA_PATTERN_TO_VME (1<<4)
+#define VME_DMA_PATTERN_TO_MEM (1<<5)
+
+struct vme_dma_attr {
+ u32 type;
+ void *private;
+};
+
+struct vme_resource {
+ enum vme_resource_type type;
+ struct list_head *entry;
+};
+
+extern struct bus_type vme_bus_type;
+
+/* Number of VME interrupt vectors */
+#define VME_NUM_STATUSID 256
+
+/* VME_MAX_BRIDGES comes from the type of vme_bus_numbers */
+#define VME_MAX_BRIDGES (sizeof(unsigned int)*8)
+#define VME_MAX_SLOTS 32
+
+#define VME_SLOT_CURRENT -1
+#define VME_SLOT_ALL -2
+
+/**
+ * struct vme_dev - Structure representing a VME device
+ * @num: The device number
+ * @bridge: Pointer to the bridge device this device is on
+ * @dev: Internal device structure
+ * @drv_list: List of devices (per driver)
+ * @bridge_list: List of devices (per bridge)
+ */
+struct vme_dev {
+ int num;
+ struct vme_bridge *bridge;
+ struct device dev;
+ struct list_head drv_list;
+ struct list_head bridge_list;
+};
+
+/**
+ * struct vme_driver - Structure representing a VME driver
+ * @name: Driver name, should be unique among VME drivers and usually the same
+ * as the module name.
+ * @match: Callback used to determine whether probe should be run.
+ * @probe: Callback for device binding, called when new device is detected.
+ * @remove: Callback, called on device removal.
+ * @driver: Underlying generic device driver structure.
+ * @devices: List of VME devices (struct vme_dev) associated with this driver.
+ */
+struct vme_driver {
+ const char *name;
+ int (*match)(struct vme_dev *);
+ int (*probe)(struct vme_dev *);
+ void (*remove)(struct vme_dev *);
+ struct device_driver driver;
+ struct list_head devices;
+};
+
+void *vme_alloc_consistent(struct vme_resource *, size_t, dma_addr_t *);
+void vme_free_consistent(struct vme_resource *, size_t, void *,
+ dma_addr_t);
+
+size_t vme_get_size(struct vme_resource *);
+int vme_check_window(u32 aspace, unsigned long long vme_base,
+ unsigned long long size);
+
+struct vme_resource *vme_slave_request(struct vme_dev *, u32, u32);
+int vme_slave_set(struct vme_resource *, int, unsigned long long,
+ unsigned long long, dma_addr_t, u32, u32);
+int vme_slave_get(struct vme_resource *, int *, unsigned long long *,
+ unsigned long long *, dma_addr_t *, u32 *, u32 *);
+void vme_slave_free(struct vme_resource *);
+
+struct vme_resource *vme_master_request(struct vme_dev *, u32, u32, u32);
+int vme_master_set(struct vme_resource *, int, unsigned long long,
+ unsigned long long, u32, u32, u32);
+int vme_master_get(struct vme_resource *, int *, unsigned long long *,
+ unsigned long long *, u32 *, u32 *, u32 *);
+ssize_t vme_master_read(struct vme_resource *, void *, size_t, loff_t);
+ssize_t vme_master_write(struct vme_resource *, void *, size_t, loff_t);
+unsigned int vme_master_rmw(struct vme_resource *, unsigned int, unsigned int,
+ unsigned int, loff_t);
+int vme_master_mmap(struct vme_resource *resource, struct vm_area_struct *vma);
+void vme_master_free(struct vme_resource *);
+
+struct vme_resource *vme_dma_request(struct vme_dev *, u32);
+struct vme_dma_list *vme_new_dma_list(struct vme_resource *);
+struct vme_dma_attr *vme_dma_pattern_attribute(u32, u32);
+struct vme_dma_attr *vme_dma_pci_attribute(dma_addr_t);
+struct vme_dma_attr *vme_dma_vme_attribute(unsigned long long, u32, u32, u32);
+void vme_dma_free_attribute(struct vme_dma_attr *);
+int vme_dma_list_add(struct vme_dma_list *, struct vme_dma_attr *,
+ struct vme_dma_attr *, size_t);
+int vme_dma_list_exec(struct vme_dma_list *);
+int vme_dma_list_free(struct vme_dma_list *);
+int vme_dma_free(struct vme_resource *);
+
+int vme_irq_request(struct vme_dev *, int, int,
+ void (*callback)(int, int, void *), void *);
+void vme_irq_free(struct vme_dev *, int, int);
+int vme_irq_generate(struct vme_dev *, int, int);
+
+struct vme_resource *vme_lm_request(struct vme_dev *);
+int vme_lm_count(struct vme_resource *);
+int vme_lm_set(struct vme_resource *, unsigned long long, u32, u32);
+int vme_lm_get(struct vme_resource *, unsigned long long *, u32 *, u32 *);
+int vme_lm_attach(struct vme_resource *, int, void (*callback)(void *), void *);
+int vme_lm_detach(struct vme_resource *, int);
+void vme_lm_free(struct vme_resource *);
+
+int vme_slot_num(struct vme_dev *);
+int vme_bus_num(struct vme_dev *);
+
+int vme_register_driver(struct vme_driver *, unsigned int);
+void vme_unregister_driver(struct vme_driver *);
+
+
+#endif /* _VME_H_ */
+
diff --git a/drivers/staging/vme_user/vme_bridge.h b/drivers/staging/vme_user/vme_bridge.h
new file mode 100644
index 000000000000..0bbefe9851d7
--- /dev/null
+++ b/drivers/staging/vme_user/vme_bridge.h
@@ -0,0 +1,190 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _VME_BRIDGE_H_
+#define _VME_BRIDGE_H_
+
+#include "vme.h"
+
+#define VME_CRCSR_BUF_SIZE (508*1024)
+/*
+ * Resource structures
+ */
+struct vme_master_resource {
+ struct list_head list;
+ struct vme_bridge *parent;
+ /*
+ * We are likely to need to access the VME bus in interrupt context, so
+ * protect master routines with a spinlock rather than a mutex.
+ */
+ spinlock_t lock;
+ int locked;
+ int number;
+ u32 address_attr;
+ u32 cycle_attr;
+ u32 width_attr;
+ struct resource bus_resource;
+ void __iomem *kern_base;
+};
+
+struct vme_slave_resource {
+ struct list_head list;
+ struct vme_bridge *parent;
+ struct mutex mtx;
+ int locked;
+ int number;
+ u32 address_attr;
+ u32 cycle_attr;
+};
+
+struct vme_dma_pattern {
+ u32 pattern;
+ u32 type;
+};
+
+struct vme_dma_pci {
+ dma_addr_t address;
+};
+
+struct vme_dma_vme {
+ unsigned long long address;
+ u32 aspace;
+ u32 cycle;
+ u32 dwidth;
+};
+
+struct vme_dma_list {
+ struct list_head list;
+ struct vme_dma_resource *parent;
+ struct list_head entries;
+ struct mutex mtx;
+};
+
+struct vme_dma_resource {
+ struct list_head list;
+ struct vme_bridge *parent;
+ struct mutex mtx;
+ int locked;
+ int number;
+ struct list_head pending;
+ struct list_head running;
+ u32 route_attr;
+};
+
+struct vme_lm_resource {
+ struct list_head list;
+ struct vme_bridge *parent;
+ struct mutex mtx;
+ int locked;
+ int number;
+ int monitors;
+};
+
+struct vme_error_handler {
+ struct list_head list;
+ unsigned long long start; /* Beginning of error window */
+ unsigned long long end; /* End of error window */
+ unsigned long long first_error; /* Address of the first error */
+ u32 aspace; /* Address space of error window*/
+ unsigned num_errors; /* Number of errors */
+};
+
+struct vme_callback {
+ void (*func)(int, int, void*);
+ void *priv_data;
+};
+
+struct vme_irq {
+ int count;
+ struct vme_callback callback[VME_NUM_STATUSID];
+};
+
+/* Allow 16 characters for name (including null character) */
+#define VMENAMSIZ 16
+
+/* This structure stores all the information about one bridge
+ * The structure should be dynamically allocated by the driver and one instance
+ * of the structure should be present for each VME chip present in the system.
+ */
+struct vme_bridge {
+ char name[VMENAMSIZ];
+ int num;
+ struct list_head master_resources;
+ struct list_head slave_resources;
+ struct list_head dma_resources;
+ struct list_head lm_resources;
+
+ /* List for registered errors handlers */
+ struct list_head vme_error_handlers;
+ /* List of devices on this bridge */
+ struct list_head devices;
+
+ /* Bridge Info - XXX Move to private structure? */
+ struct device *parent; /* Parent device (eg. pdev->dev for PCI) */
+ void *driver_priv; /* Private pointer for the bridge driver */
+ struct list_head bus_list; /* list of VME buses */
+
+ /* Interrupt callbacks */
+ struct vme_irq irq[7];
+ /* Locking for VME irq callback configuration */
+ struct mutex irq_mtx;
+
+ /* Slave Functions */
+ int (*slave_get) (struct vme_slave_resource *, int *,
+ unsigned long long *, unsigned long long *, dma_addr_t *,
+ u32 *, u32 *);
+ int (*slave_set) (struct vme_slave_resource *, int, unsigned long long,
+ unsigned long long, dma_addr_t, u32, u32);
+
+ /* Master Functions */
+ int (*master_get) (struct vme_master_resource *, int *,
+ unsigned long long *, unsigned long long *, u32 *, u32 *,
+ u32 *);
+ int (*master_set) (struct vme_master_resource *, int,
+ unsigned long long, unsigned long long, u32, u32, u32);
+ ssize_t (*master_read) (struct vme_master_resource *, void *, size_t,
+ loff_t);
+ ssize_t (*master_write) (struct vme_master_resource *, void *, size_t,
+ loff_t);
+ unsigned int (*master_rmw) (struct vme_master_resource *, unsigned int,
+ unsigned int, unsigned int, loff_t);
+
+ /* DMA Functions */
+ int (*dma_list_add) (struct vme_dma_list *, struct vme_dma_attr *,
+ struct vme_dma_attr *, size_t);
+ int (*dma_list_exec) (struct vme_dma_list *);
+ int (*dma_list_empty) (struct vme_dma_list *);
+
+ /* Interrupt Functions */
+ void (*irq_set) (struct vme_bridge *, int, int, int);
+ int (*irq_generate) (struct vme_bridge *, int, int);
+
+ /* Location monitor functions */
+ int (*lm_set) (struct vme_lm_resource *, unsigned long long, u32, u32);
+ int (*lm_get) (struct vme_lm_resource *, unsigned long long *, u32 *,
+ u32 *);
+ int (*lm_attach)(struct vme_lm_resource *, int,
+ void (*callback)(void *), void *);
+ int (*lm_detach) (struct vme_lm_resource *, int);
+
+ /* CR/CSR space functions */
+ int (*slot_get) (struct vme_bridge *);
+
+ /* Bridge parent interface */
+ void *(*alloc_consistent)(struct device *dev, size_t size,
+ dma_addr_t *dma);
+ void (*free_consistent)(struct device *dev, size_t size,
+ void *vaddr, dma_addr_t dma);
+};
+
+void vme_bus_error_handler(struct vme_bridge *bridge,
+ unsigned long long address, int am);
+void vme_irq_handler(struct vme_bridge *, int, int);
+
+struct vme_bridge *vme_init_bridge(struct vme_bridge *);
+int vme_register_bridge(struct vme_bridge *);
+void vme_unregister_bridge(struct vme_bridge *);
+struct vme_error_handler *vme_register_error_handler(
+ struct vme_bridge *bridge, u32 aspace,
+ unsigned long long address, size_t len);
+void vme_unregister_error_handler(struct vme_error_handler *handler);
+
+#endif /* _VME_BRIDGE_H_ */
diff --git a/drivers/staging/vme_user/vme_fake.c b/drivers/staging/vme_user/vme_fake.c
new file mode 100644
index 000000000000..dd646b0c531d
--- /dev/null
+++ b/drivers/staging/vme_user/vme_fake.c
@@ -0,0 +1,1305 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Fake VME bridge support.
+ *
+ * This drive provides a fake VME bridge chip, this enables debugging of the
+ * VME framework in the absence of a VME system.
+ *
+ * This driver has to do a number of things in software that would be driven
+ * by hardware if it was available, it will also result in extra overhead at
+ * times when compared with driving actual hardware.
+ *
+ * Author: Martyn Welch <martyn@welches.me.uk>
+ * Copyright (c) 2014 Martyn Welch
+ *
+ * Based on vme_tsi148.c:
+ *
+ * Author: Martyn Welch <martyn.welch@ge.com>
+ * Copyright 2008 GE Intelligent Platforms Embedded Systems, Inc.
+ *
+ * Based on work by Tom Armistead and Ajit Prem
+ * Copyright 2004 Motorola Inc.
+ */
+
+#include <linux/device.h>
+#include <linux/errno.h>
+#include <linux/interrupt.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+#include <linux/types.h>
+
+#include "vme.h"
+#include "vme_bridge.h"
+
+/*
+ * Define the number of each that the fake driver supports.
+ */
+#define FAKE_MAX_MASTER 8 /* Max Master Windows */
+#define FAKE_MAX_SLAVE 8 /* Max Slave Windows */
+
+/* Structures to hold information normally held in device registers */
+struct fake_slave_window {
+ int enabled;
+ unsigned long long vme_base;
+ unsigned long long size;
+ void *buf_base;
+ u32 aspace;
+ u32 cycle;
+};
+
+struct fake_master_window {
+ int enabled;
+ unsigned long long vme_base;
+ unsigned long long size;
+ u32 aspace;
+ u32 cycle;
+ u32 dwidth;
+};
+
+/* Structure used to hold driver specific information */
+struct fake_driver {
+ struct vme_bridge *parent;
+ struct fake_slave_window slaves[FAKE_MAX_SLAVE];
+ struct fake_master_window masters[FAKE_MAX_MASTER];
+ u32 lm_enabled;
+ unsigned long long lm_base;
+ u32 lm_aspace;
+ u32 lm_cycle;
+ void (*lm_callback[4])(void *);
+ void *lm_data[4];
+ struct tasklet_struct int_tasklet;
+ int int_level;
+ int int_statid;
+ void *crcsr_kernel;
+ dma_addr_t crcsr_bus;
+ /* Only one VME interrupt can be generated at a time, provide locking */
+ struct mutex vme_int;
+};
+
+/* Module parameter */
+static int geoid;
+
+static const char driver_name[] = "vme_fake";
+
+static struct vme_bridge *exit_pointer;
+
+static struct device *vme_root;
+
+/*
+ * Calling VME bus interrupt callback if provided.
+ */
+static void fake_VIRQ_tasklet(unsigned long data)
+{
+ struct vme_bridge *fake_bridge;
+ struct fake_driver *bridge;
+
+ fake_bridge = (struct vme_bridge *) data;
+ bridge = fake_bridge->driver_priv;
+
+ vme_irq_handler(fake_bridge, bridge->int_level, bridge->int_statid);
+}
+
+/*
+ * Configure VME interrupt
+ */
+static void fake_irq_set(struct vme_bridge *fake_bridge, int level,
+ int state, int sync)
+{
+ /* Nothing to do */
+}
+
+static void *fake_pci_to_ptr(dma_addr_t addr)
+{
+ return (void *)(uintptr_t)addr;
+}
+
+static dma_addr_t fake_ptr_to_pci(void *addr)
+{
+ return (dma_addr_t)(uintptr_t)addr;
+}
+
+/*
+ * Generate a VME bus interrupt at the requested level & vector. Wait for
+ * interrupt to be acked.
+ */
+static int fake_irq_generate(struct vme_bridge *fake_bridge, int level,
+ int statid)
+{
+ struct fake_driver *bridge;
+
+ bridge = fake_bridge->driver_priv;
+
+ mutex_lock(&bridge->vme_int);
+
+ bridge->int_level = level;
+
+ bridge->int_statid = statid;
+
+ /*
+ * Schedule tasklet to run VME handler to emulate normal VME interrupt
+ * handler behaviour.
+ */
+ tasklet_schedule(&bridge->int_tasklet);
+
+ mutex_unlock(&bridge->vme_int);
+
+ return 0;
+}
+
+/*
+ * Initialize a slave window with the requested attributes.
+ */
+static int fake_slave_set(struct vme_slave_resource *image, int enabled,
+ unsigned long long vme_base, unsigned long long size,
+ dma_addr_t buf_base, u32 aspace, u32 cycle)
+{
+ unsigned int i, granularity = 0;
+ unsigned long long vme_bound;
+ struct vme_bridge *fake_bridge;
+ struct fake_driver *bridge;
+
+ fake_bridge = image->parent;
+ bridge = fake_bridge->driver_priv;
+
+ i = image->number;
+
+ switch (aspace) {
+ case VME_A16:
+ granularity = 0x10;
+ break;
+ case VME_A24:
+ granularity = 0x1000;
+ break;
+ case VME_A32:
+ granularity = 0x10000;
+ break;
+ case VME_A64:
+ granularity = 0x10000;
+ break;
+ case VME_CRCSR:
+ case VME_USER1:
+ case VME_USER2:
+ case VME_USER3:
+ case VME_USER4:
+ default:
+ pr_err("Invalid address space\n");
+ return -EINVAL;
+ }
+
+ /*
+ * Bound address is a valid address for the window, adjust
+ * accordingly
+ */
+ vme_bound = vme_base + size - granularity;
+
+ if (vme_base & (granularity - 1)) {
+ pr_err("Invalid VME base alignment\n");
+ return -EINVAL;
+ }
+ if (vme_bound & (granularity - 1)) {
+ pr_err("Invalid VME bound alignment\n");
+ return -EINVAL;
+ }
+
+ mutex_lock(&image->mtx);
+
+ bridge->slaves[i].enabled = enabled;
+ bridge->slaves[i].vme_base = vme_base;
+ bridge->slaves[i].size = size;
+ bridge->slaves[i].buf_base = fake_pci_to_ptr(buf_base);
+ bridge->slaves[i].aspace = aspace;
+ bridge->slaves[i].cycle = cycle;
+
+ mutex_unlock(&image->mtx);
+
+ return 0;
+}
+
+/*
+ * Get slave window configuration.
+ */
+static int fake_slave_get(struct vme_slave_resource *image, int *enabled,
+ unsigned long long *vme_base, unsigned long long *size,
+ dma_addr_t *buf_base, u32 *aspace, u32 *cycle)
+{
+ unsigned int i;
+ struct fake_driver *bridge;
+
+ bridge = image->parent->driver_priv;
+
+ i = image->number;
+
+ mutex_lock(&image->mtx);
+
+ *enabled = bridge->slaves[i].enabled;
+ *vme_base = bridge->slaves[i].vme_base;
+ *size = bridge->slaves[i].size;
+ *buf_base = fake_ptr_to_pci(bridge->slaves[i].buf_base);
+ *aspace = bridge->slaves[i].aspace;
+ *cycle = bridge->slaves[i].cycle;
+
+ mutex_unlock(&image->mtx);
+
+ return 0;
+}
+
+/*
+ * Set the attributes of an outbound window.
+ */
+static int fake_master_set(struct vme_master_resource *image, int enabled,
+ unsigned long long vme_base, unsigned long long size,
+ u32 aspace, u32 cycle, u32 dwidth)
+{
+ int retval = 0;
+ unsigned int i;
+ struct vme_bridge *fake_bridge;
+ struct fake_driver *bridge;
+
+ fake_bridge = image->parent;
+
+ bridge = fake_bridge->driver_priv;
+
+ /* Verify input data */
+ if (vme_base & 0xFFFF) {
+ pr_err("Invalid VME Window alignment\n");
+ retval = -EINVAL;
+ goto err_window;
+ }
+
+ if (size & 0xFFFF) {
+ pr_err("Invalid size alignment\n");
+ retval = -EINVAL;
+ goto err_window;
+ }
+
+ if ((size == 0) && (enabled != 0)) {
+ pr_err("Size must be non-zero for enabled windows\n");
+ retval = -EINVAL;
+ goto err_window;
+ }
+
+ /* Setup data width */
+ switch (dwidth) {
+ case VME_D8:
+ case VME_D16:
+ case VME_D32:
+ break;
+ default:
+ pr_err("Invalid data width\n");
+ retval = -EINVAL;
+ goto err_dwidth;
+ }
+
+ /* Setup address space */
+ switch (aspace) {
+ case VME_A16:
+ case VME_A24:
+ case VME_A32:
+ case VME_A64:
+ case VME_CRCSR:
+ case VME_USER1:
+ case VME_USER2:
+ case VME_USER3:
+ case VME_USER4:
+ break;
+ default:
+ pr_err("Invalid address space\n");
+ retval = -EINVAL;
+ goto err_aspace;
+ }
+
+ spin_lock(&image->lock);
+
+ i = image->number;
+
+ bridge->masters[i].enabled = enabled;
+ bridge->masters[i].vme_base = vme_base;
+ bridge->masters[i].size = size;
+ bridge->masters[i].aspace = aspace;
+ bridge->masters[i].cycle = cycle;
+ bridge->masters[i].dwidth = dwidth;
+
+ spin_unlock(&image->lock);
+
+ return 0;
+
+err_aspace:
+err_dwidth:
+err_window:
+ return retval;
+
+}
+
+/*
+ * Set the attributes of an outbound window.
+ */
+static int __fake_master_get(struct vme_master_resource *image, int *enabled,
+ unsigned long long *vme_base, unsigned long long *size,
+ u32 *aspace, u32 *cycle, u32 *dwidth)
+{
+ unsigned int i;
+ struct fake_driver *bridge;
+
+ bridge = image->parent->driver_priv;
+
+ i = image->number;
+
+ *enabled = bridge->masters[i].enabled;
+ *vme_base = bridge->masters[i].vme_base;
+ *size = bridge->masters[i].size;
+ *aspace = bridge->masters[i].aspace;
+ *cycle = bridge->masters[i].cycle;
+ *dwidth = bridge->masters[i].dwidth;
+
+ return 0;
+}
+
+
+static int fake_master_get(struct vme_master_resource *image, int *enabled,
+ unsigned long long *vme_base, unsigned long long *size,
+ u32 *aspace, u32 *cycle, u32 *dwidth)
+{
+ int retval;
+
+ spin_lock(&image->lock);
+
+ retval = __fake_master_get(image, enabled, vme_base, size, aspace,
+ cycle, dwidth);
+
+ spin_unlock(&image->lock);
+
+ return retval;
+}
+
+
+static void fake_lm_check(struct fake_driver *bridge, unsigned long long addr,
+ u32 aspace, u32 cycle)
+{
+ struct vme_bridge *fake_bridge;
+ unsigned long long lm_base;
+ u32 lm_aspace, lm_cycle;
+ int i;
+ struct vme_lm_resource *lm;
+ struct list_head *pos = NULL, *n;
+
+ /* Get vme_bridge */
+ fake_bridge = bridge->parent;
+
+ /* Loop through each location monitor resource */
+ list_for_each_safe(pos, n, &fake_bridge->lm_resources) {
+ lm = list_entry(pos, struct vme_lm_resource, list);
+
+ /* If disabled, we're done */
+ if (bridge->lm_enabled == 0)
+ return;
+
+ lm_base = bridge->lm_base;
+ lm_aspace = bridge->lm_aspace;
+ lm_cycle = bridge->lm_cycle;
+
+ /* First make sure that the cycle and address space match */
+ if ((lm_aspace == aspace) && (lm_cycle == cycle)) {
+ for (i = 0; i < lm->monitors; i++) {
+ /* Each location monitor covers 8 bytes */
+ if (((lm_base + (8 * i)) <= addr) &&
+ ((lm_base + (8 * i) + 8) > addr)) {
+ if (bridge->lm_callback[i])
+ bridge->lm_callback[i](
+ bridge->lm_data[i]);
+ }
+ }
+ }
+ }
+}
+
+static noinline_for_stack u8 fake_vmeread8(struct fake_driver *bridge,
+ unsigned long long addr,
+ u32 aspace, u32 cycle)
+{
+ u8 retval = 0xff;
+ int i;
+ unsigned long long start, end, offset;
+ u8 *loc;
+
+ for (i = 0; i < FAKE_MAX_SLAVE; i++) {
+ start = bridge->slaves[i].vme_base;
+ end = bridge->slaves[i].vme_base + bridge->slaves[i].size;
+
+ if (aspace != bridge->slaves[i].aspace)
+ continue;
+
+ if (cycle != bridge->slaves[i].cycle)
+ continue;
+
+ if ((addr >= start) && (addr < end)) {
+ offset = addr - bridge->slaves[i].vme_base;
+ loc = (u8 *)(bridge->slaves[i].buf_base + offset);
+ retval = *loc;
+
+ break;
+ }
+ }
+
+ fake_lm_check(bridge, addr, aspace, cycle);
+
+ return retval;
+}
+
+static noinline_for_stack u16 fake_vmeread16(struct fake_driver *bridge,
+ unsigned long long addr,
+ u32 aspace, u32 cycle)
+{
+ u16 retval = 0xffff;
+ int i;
+ unsigned long long start, end, offset;
+ u16 *loc;
+
+ for (i = 0; i < FAKE_MAX_SLAVE; i++) {
+ if (aspace != bridge->slaves[i].aspace)
+ continue;
+
+ if (cycle != bridge->slaves[i].cycle)
+ continue;
+
+ start = bridge->slaves[i].vme_base;
+ end = bridge->slaves[i].vme_base + bridge->slaves[i].size;
+
+ if ((addr >= start) && ((addr + 1) < end)) {
+ offset = addr - bridge->slaves[i].vme_base;
+ loc = (u16 *)(bridge->slaves[i].buf_base + offset);
+ retval = *loc;
+
+ break;
+ }
+ }
+
+ fake_lm_check(bridge, addr, aspace, cycle);
+
+ return retval;
+}
+
+static noinline_for_stack u32 fake_vmeread32(struct fake_driver *bridge,
+ unsigned long long addr,
+ u32 aspace, u32 cycle)
+{
+ u32 retval = 0xffffffff;
+ int i;
+ unsigned long long start, end, offset;
+ u32 *loc;
+
+ for (i = 0; i < FAKE_MAX_SLAVE; i++) {
+ if (aspace != bridge->slaves[i].aspace)
+ continue;
+
+ if (cycle != bridge->slaves[i].cycle)
+ continue;
+
+ start = bridge->slaves[i].vme_base;
+ end = bridge->slaves[i].vme_base + bridge->slaves[i].size;
+
+ if ((addr >= start) && ((addr + 3) < end)) {
+ offset = addr - bridge->slaves[i].vme_base;
+ loc = (u32 *)(bridge->slaves[i].buf_base + offset);
+ retval = *loc;
+
+ break;
+ }
+ }
+
+ fake_lm_check(bridge, addr, aspace, cycle);
+
+ return retval;
+}
+
+static ssize_t fake_master_read(struct vme_master_resource *image, void *buf,
+ size_t count, loff_t offset)
+{
+ int retval;
+ u32 aspace, cycle, dwidth;
+ struct vme_bridge *fake_bridge;
+ struct fake_driver *priv;
+ int i;
+ unsigned long long addr;
+ unsigned int done = 0;
+ unsigned int count32;
+
+ fake_bridge = image->parent;
+
+ priv = fake_bridge->driver_priv;
+
+ i = image->number;
+
+ addr = (unsigned long long)priv->masters[i].vme_base + offset;
+ aspace = priv->masters[i].aspace;
+ cycle = priv->masters[i].cycle;
+ dwidth = priv->masters[i].dwidth;
+
+ spin_lock(&image->lock);
+
+ /* The following code handles VME address alignment. We cannot use
+ * memcpy_xxx here because it may cut data transfers in to 8-bit
+ * cycles when D16 or D32 cycles are required on the VME bus.
+ * On the other hand, the bridge itself assures that the maximum data
+ * cycle configured for the transfer is used and splits it
+ * automatically for non-aligned addresses, so we don't want the
+ * overhead of needlessly forcing small transfers for the entire cycle.
+ */
+ if (addr & 0x1) {
+ *(u8 *)buf = fake_vmeread8(priv, addr, aspace, cycle);
+ done += 1;
+ if (done == count)
+ goto out;
+ }
+ if ((dwidth == VME_D16) || (dwidth == VME_D32)) {
+ if ((addr + done) & 0x2) {
+ if ((count - done) < 2) {
+ *(u8 *)(buf + done) = fake_vmeread8(priv,
+ addr + done, aspace, cycle);
+ done += 1;
+ goto out;
+ } else {
+ *(u16 *)(buf + done) = fake_vmeread16(priv,
+ addr + done, aspace, cycle);
+ done += 2;
+ }
+ }
+ }
+
+ if (dwidth == VME_D32) {
+ count32 = (count - done) & ~0x3;
+ while (done < count32) {
+ *(u32 *)(buf + done) = fake_vmeread32(priv, addr + done,
+ aspace, cycle);
+ done += 4;
+ }
+ } else if (dwidth == VME_D16) {
+ count32 = (count - done) & ~0x3;
+ while (done < count32) {
+ *(u16 *)(buf + done) = fake_vmeread16(priv, addr + done,
+ aspace, cycle);
+ done += 2;
+ }
+ } else if (dwidth == VME_D8) {
+ count32 = (count - done);
+ while (done < count32) {
+ *(u8 *)(buf + done) = fake_vmeread8(priv, addr + done,
+ aspace, cycle);
+ done += 1;
+ }
+
+ }
+
+ if ((dwidth == VME_D16) || (dwidth == VME_D32)) {
+ if ((count - done) & 0x2) {
+ *(u16 *)(buf + done) = fake_vmeread16(priv, addr + done,
+ aspace, cycle);
+ done += 2;
+ }
+ }
+ if ((count - done) & 0x1) {
+ *(u8 *)(buf + done) = fake_vmeread8(priv, addr + done, aspace,
+ cycle);
+ done += 1;
+ }
+
+out:
+ retval = count;
+
+ spin_unlock(&image->lock);
+
+ return retval;
+}
+
+static noinline_for_stack void fake_vmewrite8(struct fake_driver *bridge,
+ u8 *buf, unsigned long long addr,
+ u32 aspace, u32 cycle)
+{
+ int i;
+ unsigned long long start, end, offset;
+ u8 *loc;
+
+ for (i = 0; i < FAKE_MAX_SLAVE; i++) {
+ if (aspace != bridge->slaves[i].aspace)
+ continue;
+
+ if (cycle != bridge->slaves[i].cycle)
+ continue;
+
+ start = bridge->slaves[i].vme_base;
+ end = bridge->slaves[i].vme_base + bridge->slaves[i].size;
+
+ if ((addr >= start) && (addr < end)) {
+ offset = addr - bridge->slaves[i].vme_base;
+ loc = (u8 *)((void *)bridge->slaves[i].buf_base + offset);
+ *loc = *buf;
+
+ break;
+ }
+ }
+
+ fake_lm_check(bridge, addr, aspace, cycle);
+
+}
+
+static noinline_for_stack void fake_vmewrite16(struct fake_driver *bridge,
+ u16 *buf, unsigned long long addr,
+ u32 aspace, u32 cycle)
+{
+ int i;
+ unsigned long long start, end, offset;
+ u16 *loc;
+
+ for (i = 0; i < FAKE_MAX_SLAVE; i++) {
+ if (aspace != bridge->slaves[i].aspace)
+ continue;
+
+ if (cycle != bridge->slaves[i].cycle)
+ continue;
+
+ start = bridge->slaves[i].vme_base;
+ end = bridge->slaves[i].vme_base + bridge->slaves[i].size;
+
+ if ((addr >= start) && ((addr + 1) < end)) {
+ offset = addr - bridge->slaves[i].vme_base;
+ loc = (u16 *)((void *)bridge->slaves[i].buf_base + offset);
+ *loc = *buf;
+
+ break;
+ }
+ }
+
+ fake_lm_check(bridge, addr, aspace, cycle);
+
+}
+
+static noinline_for_stack void fake_vmewrite32(struct fake_driver *bridge,
+ u32 *buf, unsigned long long addr,
+ u32 aspace, u32 cycle)
+{
+ int i;
+ unsigned long long start, end, offset;
+ u32 *loc;
+
+ for (i = 0; i < FAKE_MAX_SLAVE; i++) {
+ if (aspace != bridge->slaves[i].aspace)
+ continue;
+
+ if (cycle != bridge->slaves[i].cycle)
+ continue;
+
+ start = bridge->slaves[i].vme_base;
+ end = bridge->slaves[i].vme_base + bridge->slaves[i].size;
+
+ if ((addr >= start) && ((addr + 3) < end)) {
+ offset = addr - bridge->slaves[i].vme_base;
+ loc = (u32 *)((void *)bridge->slaves[i].buf_base + offset);
+ *loc = *buf;
+
+ break;
+ }
+ }
+
+ fake_lm_check(bridge, addr, aspace, cycle);
+
+}
+
+static ssize_t fake_master_write(struct vme_master_resource *image, void *buf,
+ size_t count, loff_t offset)
+{
+ int retval = 0;
+ u32 aspace, cycle, dwidth;
+ unsigned long long addr;
+ int i;
+ unsigned int done = 0;
+ unsigned int count32;
+
+ struct vme_bridge *fake_bridge;
+ struct fake_driver *bridge;
+
+ fake_bridge = image->parent;
+
+ bridge = fake_bridge->driver_priv;
+
+ i = image->number;
+
+ addr = bridge->masters[i].vme_base + offset;
+ aspace = bridge->masters[i].aspace;
+ cycle = bridge->masters[i].cycle;
+ dwidth = bridge->masters[i].dwidth;
+
+ spin_lock(&image->lock);
+
+ /* Here we apply for the same strategy we do in master_read
+ * function in order to assure the correct cycles.
+ */
+ if (addr & 0x1) {
+ fake_vmewrite8(bridge, (u8 *)buf, addr, aspace, cycle);
+ done += 1;
+ if (done == count)
+ goto out;
+ }
+
+ if ((dwidth == VME_D16) || (dwidth == VME_D32)) {
+ if ((addr + done) & 0x2) {
+ if ((count - done) < 2) {
+ fake_vmewrite8(bridge, (u8 *)(buf + done),
+ addr + done, aspace, cycle);
+ done += 1;
+ goto out;
+ } else {
+ fake_vmewrite16(bridge, (u16 *)(buf + done),
+ addr + done, aspace, cycle);
+ done += 2;
+ }
+ }
+ }
+
+ if (dwidth == VME_D32) {
+ count32 = (count - done) & ~0x3;
+ while (done < count32) {
+ fake_vmewrite32(bridge, (u32 *)(buf + done),
+ addr + done, aspace, cycle);
+ done += 4;
+ }
+ } else if (dwidth == VME_D16) {
+ count32 = (count - done) & ~0x3;
+ while (done < count32) {
+ fake_vmewrite16(bridge, (u16 *)(buf + done),
+ addr + done, aspace, cycle);
+ done += 2;
+ }
+ } else if (dwidth == VME_D8) {
+ count32 = (count - done);
+ while (done < count32) {
+ fake_vmewrite8(bridge, (u8 *)(buf + done), addr + done,
+ aspace, cycle);
+ done += 1;
+ }
+
+ }
+
+ if ((dwidth == VME_D16) || (dwidth == VME_D32)) {
+ if ((count - done) & 0x2) {
+ fake_vmewrite16(bridge, (u16 *)(buf + done),
+ addr + done, aspace, cycle);
+ done += 2;
+ }
+ }
+
+ if ((count - done) & 0x1) {
+ fake_vmewrite8(bridge, (u8 *)(buf + done), addr + done, aspace,
+ cycle);
+ done += 1;
+ }
+
+out:
+ retval = count;
+
+ spin_unlock(&image->lock);
+
+ return retval;
+}
+
+/*
+ * Perform an RMW cycle on the VME bus.
+ *
+ * Requires a previously configured master window, returns final value.
+ */
+static unsigned int fake_master_rmw(struct vme_master_resource *image,
+ unsigned int mask, unsigned int compare, unsigned int swap,
+ loff_t offset)
+{
+ u32 tmp, base;
+ u32 aspace, cycle;
+ int i;
+ struct fake_driver *bridge;
+
+ bridge = image->parent->driver_priv;
+
+ /* Find the PCI address that maps to the desired VME address */
+ i = image->number;
+
+ base = bridge->masters[i].vme_base;
+ aspace = bridge->masters[i].aspace;
+ cycle = bridge->masters[i].cycle;
+
+ /* Lock image */
+ spin_lock(&image->lock);
+
+ /* Read existing value */
+ tmp = fake_vmeread32(bridge, base + offset, aspace, cycle);
+
+ /* Perform check */
+ if ((tmp && mask) == (compare && mask)) {
+ tmp = tmp | (mask | swap);
+ tmp = tmp & (~mask | swap);
+
+ /* Write back */
+ fake_vmewrite32(bridge, &tmp, base + offset, aspace, cycle);
+ }
+
+ /* Unlock image */
+ spin_unlock(&image->lock);
+
+ return tmp;
+}
+
+/*
+ * All 4 location monitors reside at the same base - this is therefore a
+ * system wide configuration.
+ *
+ * This does not enable the LM monitor - that should be done when the first
+ * callback is attached and disabled when the last callback is removed.
+ */
+static int fake_lm_set(struct vme_lm_resource *lm, unsigned long long lm_base,
+ u32 aspace, u32 cycle)
+{
+ int i;
+ struct vme_bridge *fake_bridge;
+ struct fake_driver *bridge;
+
+ fake_bridge = lm->parent;
+
+ bridge = fake_bridge->driver_priv;
+
+ mutex_lock(&lm->mtx);
+
+ /* If we already have a callback attached, we can't move it! */
+ for (i = 0; i < lm->monitors; i++) {
+ if (bridge->lm_callback[i]) {
+ mutex_unlock(&lm->mtx);
+ pr_err("Location monitor callback attached, can't reset\n");
+ return -EBUSY;
+ }
+ }
+
+ switch (aspace) {
+ case VME_A16:
+ case VME_A24:
+ case VME_A32:
+ case VME_A64:
+ break;
+ default:
+ mutex_unlock(&lm->mtx);
+ pr_err("Invalid address space\n");
+ return -EINVAL;
+ }
+
+ bridge->lm_base = lm_base;
+ bridge->lm_aspace = aspace;
+ bridge->lm_cycle = cycle;
+
+ mutex_unlock(&lm->mtx);
+
+ return 0;
+}
+
+/* Get configuration of the callback monitor and return whether it is enabled
+ * or disabled.
+ */
+static int fake_lm_get(struct vme_lm_resource *lm,
+ unsigned long long *lm_base, u32 *aspace, u32 *cycle)
+{
+ struct fake_driver *bridge;
+
+ bridge = lm->parent->driver_priv;
+
+ mutex_lock(&lm->mtx);
+
+ *lm_base = bridge->lm_base;
+ *aspace = bridge->lm_aspace;
+ *cycle = bridge->lm_cycle;
+
+ mutex_unlock(&lm->mtx);
+
+ return bridge->lm_enabled;
+}
+
+/*
+ * Attach a callback to a specific location monitor.
+ *
+ * Callback will be passed the monitor triggered.
+ */
+static int fake_lm_attach(struct vme_lm_resource *lm, int monitor,
+ void (*callback)(void *), void *data)
+{
+ struct vme_bridge *fake_bridge;
+ struct fake_driver *bridge;
+
+ fake_bridge = lm->parent;
+
+ bridge = fake_bridge->driver_priv;
+
+ mutex_lock(&lm->mtx);
+
+ /* Ensure that the location monitor is configured - need PGM or DATA */
+ if (bridge->lm_cycle == 0) {
+ mutex_unlock(&lm->mtx);
+ pr_err("Location monitor not properly configured\n");
+ return -EINVAL;
+ }
+
+ /* Check that a callback isn't already attached */
+ if (bridge->lm_callback[monitor]) {
+ mutex_unlock(&lm->mtx);
+ pr_err("Existing callback attached\n");
+ return -EBUSY;
+ }
+
+ /* Attach callback */
+ bridge->lm_callback[monitor] = callback;
+ bridge->lm_data[monitor] = data;
+
+ /* Ensure that global Location Monitor Enable set */
+ bridge->lm_enabled = 1;
+
+ mutex_unlock(&lm->mtx);
+
+ return 0;
+}
+
+/*
+ * Detach a callback function forn a specific location monitor.
+ */
+static int fake_lm_detach(struct vme_lm_resource *lm, int monitor)
+{
+ u32 tmp;
+ int i;
+ struct fake_driver *bridge;
+
+ bridge = lm->parent->driver_priv;
+
+ mutex_lock(&lm->mtx);
+
+ /* Detach callback */
+ bridge->lm_callback[monitor] = NULL;
+ bridge->lm_data[monitor] = NULL;
+
+ /* If all location monitors disabled, disable global Location Monitor */
+ tmp = 0;
+ for (i = 0; i < lm->monitors; i++) {
+ if (bridge->lm_callback[i])
+ tmp = 1;
+ }
+
+ if (tmp == 0)
+ bridge->lm_enabled = 0;
+
+ mutex_unlock(&lm->mtx);
+
+ return 0;
+}
+
+/*
+ * Determine Geographical Addressing
+ */
+static int fake_slot_get(struct vme_bridge *fake_bridge)
+{
+ return geoid;
+}
+
+static void *fake_alloc_consistent(struct device *parent, size_t size,
+ dma_addr_t *dma)
+{
+ void *alloc = kmalloc(size, GFP_KERNEL);
+
+ if (alloc)
+ *dma = fake_ptr_to_pci(alloc);
+
+ return alloc;
+}
+
+static void fake_free_consistent(struct device *parent, size_t size,
+ void *vaddr, dma_addr_t dma)
+{
+ kfree(vaddr);
+/*
+ dma_free_coherent(parent, size, vaddr, dma);
+*/
+}
+
+/*
+ * Configure CR/CSR space
+ *
+ * Access to the CR/CSR can be configured at power-up. The location of the
+ * CR/CSR registers in the CR/CSR address space is determined by the boards
+ * Geographic address.
+ *
+ * Each board has a 512kB window, with the highest 4kB being used for the
+ * boards registers, this means there is a fix length 508kB window which must
+ * be mapped onto PCI memory.
+ */
+static int fake_crcsr_init(struct vme_bridge *fake_bridge)
+{
+ u32 vstat;
+ struct fake_driver *bridge;
+
+ bridge = fake_bridge->driver_priv;
+
+ /* Allocate mem for CR/CSR image */
+ bridge->crcsr_kernel = kzalloc(VME_CRCSR_BUF_SIZE, GFP_KERNEL);
+ bridge->crcsr_bus = fake_ptr_to_pci(bridge->crcsr_kernel);
+ if (!bridge->crcsr_kernel)
+ return -ENOMEM;
+
+ vstat = fake_slot_get(fake_bridge);
+
+ pr_info("CR/CSR Offset: %d\n", vstat);
+
+ return 0;
+}
+
+static void fake_crcsr_exit(struct vme_bridge *fake_bridge)
+{
+ struct fake_driver *bridge;
+
+ bridge = fake_bridge->driver_priv;
+
+ kfree(bridge->crcsr_kernel);
+}
+
+
+static int __init fake_init(void)
+{
+ int retval, i;
+ struct list_head *pos = NULL, *n;
+ struct vme_bridge *fake_bridge;
+ struct fake_driver *fake_device;
+ struct vme_master_resource *master_image;
+ struct vme_slave_resource *slave_image;
+ struct vme_lm_resource *lm;
+
+ /* We need a fake parent device */
+ vme_root = __root_device_register("vme", THIS_MODULE);
+
+ /* If we want to support more than one bridge at some point, we need to
+ * dynamically allocate this so we get one per device.
+ */
+ fake_bridge = kzalloc(sizeof(*fake_bridge), GFP_KERNEL);
+ if (!fake_bridge) {
+ retval = -ENOMEM;
+ goto err_struct;
+ }
+
+ fake_device = kzalloc(sizeof(*fake_device), GFP_KERNEL);
+ if (!fake_device) {
+ retval = -ENOMEM;
+ goto err_driver;
+ }
+
+ fake_bridge->driver_priv = fake_device;
+
+ fake_bridge->parent = vme_root;
+
+ fake_device->parent = fake_bridge;
+
+ /* Initialize wait queues & mutual exclusion flags */
+ mutex_init(&fake_device->vme_int);
+ mutex_init(&fake_bridge->irq_mtx);
+ tasklet_init(&fake_device->int_tasklet, fake_VIRQ_tasklet,
+ (unsigned long) fake_bridge);
+
+ strcpy(fake_bridge->name, driver_name);
+
+ /* Add master windows to list */
+ INIT_LIST_HEAD(&fake_bridge->master_resources);
+ for (i = 0; i < FAKE_MAX_MASTER; i++) {
+ master_image = kmalloc(sizeof(*master_image), GFP_KERNEL);
+ if (!master_image) {
+ retval = -ENOMEM;
+ goto err_master;
+ }
+ master_image->parent = fake_bridge;
+ spin_lock_init(&master_image->lock);
+ master_image->locked = 0;
+ master_image->number = i;
+ master_image->address_attr = VME_A16 | VME_A24 | VME_A32 |
+ VME_A64;
+ master_image->cycle_attr = VME_SCT | VME_BLT | VME_MBLT |
+ VME_2eVME | VME_2eSST | VME_2eSSTB | VME_2eSST160 |
+ VME_2eSST267 | VME_2eSST320 | VME_SUPER | VME_USER |
+ VME_PROG | VME_DATA;
+ master_image->width_attr = VME_D16 | VME_D32;
+ memset(&master_image->bus_resource, 0,
+ sizeof(struct resource));
+ master_image->kern_base = NULL;
+ list_add_tail(&master_image->list,
+ &fake_bridge->master_resources);
+ }
+
+ /* Add slave windows to list */
+ INIT_LIST_HEAD(&fake_bridge->slave_resources);
+ for (i = 0; i < FAKE_MAX_SLAVE; i++) {
+ slave_image = kmalloc(sizeof(*slave_image), GFP_KERNEL);
+ if (!slave_image) {
+ retval = -ENOMEM;
+ goto err_slave;
+ }
+ slave_image->parent = fake_bridge;
+ mutex_init(&slave_image->mtx);
+ slave_image->locked = 0;
+ slave_image->number = i;
+ slave_image->address_attr = VME_A16 | VME_A24 | VME_A32 |
+ VME_A64 | VME_CRCSR | VME_USER1 | VME_USER2 |
+ VME_USER3 | VME_USER4;
+ slave_image->cycle_attr = VME_SCT | VME_BLT | VME_MBLT |
+ VME_2eVME | VME_2eSST | VME_2eSSTB | VME_2eSST160 |
+ VME_2eSST267 | VME_2eSST320 | VME_SUPER | VME_USER |
+ VME_PROG | VME_DATA;
+ list_add_tail(&slave_image->list,
+ &fake_bridge->slave_resources);
+ }
+
+ /* Add location monitor to list */
+ INIT_LIST_HEAD(&fake_bridge->lm_resources);
+ lm = kmalloc(sizeof(*lm), GFP_KERNEL);
+ if (!lm) {
+ retval = -ENOMEM;
+ goto err_lm;
+ }
+ lm->parent = fake_bridge;
+ mutex_init(&lm->mtx);
+ lm->locked = 0;
+ lm->number = 1;
+ lm->monitors = 4;
+ list_add_tail(&lm->list, &fake_bridge->lm_resources);
+
+ fake_bridge->slave_get = fake_slave_get;
+ fake_bridge->slave_set = fake_slave_set;
+ fake_bridge->master_get = fake_master_get;
+ fake_bridge->master_set = fake_master_set;
+ fake_bridge->master_read = fake_master_read;
+ fake_bridge->master_write = fake_master_write;
+ fake_bridge->master_rmw = fake_master_rmw;
+ fake_bridge->irq_set = fake_irq_set;
+ fake_bridge->irq_generate = fake_irq_generate;
+ fake_bridge->lm_set = fake_lm_set;
+ fake_bridge->lm_get = fake_lm_get;
+ fake_bridge->lm_attach = fake_lm_attach;
+ fake_bridge->lm_detach = fake_lm_detach;
+ fake_bridge->slot_get = fake_slot_get;
+ fake_bridge->alloc_consistent = fake_alloc_consistent;
+ fake_bridge->free_consistent = fake_free_consistent;
+
+ pr_info("Board is%s the VME system controller\n",
+ (geoid == 1) ? "" : " not");
+
+ pr_info("VME geographical address is set to %d\n", geoid);
+
+ retval = fake_crcsr_init(fake_bridge);
+ if (retval) {
+ pr_err("CR/CSR configuration failed.\n");
+ goto err_crcsr;
+ }
+
+ retval = vme_register_bridge(fake_bridge);
+ if (retval != 0) {
+ pr_err("Chip Registration failed.\n");
+ goto err_reg;
+ }
+
+ exit_pointer = fake_bridge;
+
+ return 0;
+
+err_reg:
+ fake_crcsr_exit(fake_bridge);
+err_crcsr:
+err_lm:
+ /* resources are stored in link list */
+ list_for_each_safe(pos, n, &fake_bridge->lm_resources) {
+ lm = list_entry(pos, struct vme_lm_resource, list);
+ list_del(pos);
+ kfree(lm);
+ }
+err_slave:
+ /* resources are stored in link list */
+ list_for_each_safe(pos, n, &fake_bridge->slave_resources) {
+ slave_image = list_entry(pos, struct vme_slave_resource, list);
+ list_del(pos);
+ kfree(slave_image);
+ }
+err_master:
+ /* resources are stored in link list */
+ list_for_each_safe(pos, n, &fake_bridge->master_resources) {
+ master_image = list_entry(pos, struct vme_master_resource,
+ list);
+ list_del(pos);
+ kfree(master_image);
+ }
+
+ kfree(fake_device);
+err_driver:
+ kfree(fake_bridge);
+err_struct:
+ return retval;
+
+}
+
+
+static void __exit fake_exit(void)
+{
+ struct list_head *pos = NULL;
+ struct list_head *tmplist;
+ struct vme_master_resource *master_image;
+ struct vme_slave_resource *slave_image;
+ int i;
+ struct vme_bridge *fake_bridge;
+ struct fake_driver *bridge;
+
+ fake_bridge = exit_pointer;
+
+ bridge = fake_bridge->driver_priv;
+
+ pr_debug("Driver is being unloaded.\n");
+
+ /*
+ * Shutdown all inbound and outbound windows.
+ */
+ for (i = 0; i < FAKE_MAX_MASTER; i++)
+ bridge->masters[i].enabled = 0;
+
+ for (i = 0; i < FAKE_MAX_SLAVE; i++)
+ bridge->slaves[i].enabled = 0;
+
+ /*
+ * Shutdown Location monitor.
+ */
+ bridge->lm_enabled = 0;
+
+ vme_unregister_bridge(fake_bridge);
+
+ fake_crcsr_exit(fake_bridge);
+ /* resources are stored in link list */
+ list_for_each_safe(pos, tmplist, &fake_bridge->slave_resources) {
+ slave_image = list_entry(pos, struct vme_slave_resource, list);
+ list_del(pos);
+ kfree(slave_image);
+ }
+
+ /* resources are stored in link list */
+ list_for_each_safe(pos, tmplist, &fake_bridge->master_resources) {
+ master_image = list_entry(pos, struct vme_master_resource,
+ list);
+ list_del(pos);
+ kfree(master_image);
+ }
+
+ kfree(fake_bridge->driver_priv);
+
+ kfree(fake_bridge);
+
+ root_device_unregister(vme_root);
+}
+
+
+MODULE_PARM_DESC(geoid, "Set geographical addressing");
+module_param(geoid, int, 0);
+
+MODULE_DESCRIPTION("Fake VME bridge driver");
+MODULE_LICENSE("GPL");
+
+module_init(fake_init);
+module_exit(fake_exit);
diff --git a/drivers/staging/vme_user/vme_tsi148.c b/drivers/staging/vme_user/vme_tsi148.c
new file mode 100644
index 000000000000..956476213241
--- /dev/null
+++ b/drivers/staging/vme_user/vme_tsi148.c
@@ -0,0 +1,2661 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Support for the Tundra TSI148 VME-PCI Bridge Chip
+ *
+ * Author: Martyn Welch <martyn.welch@ge.com>
+ * Copyright 2008 GE Intelligent Platforms Embedded Systems, Inc.
+ *
+ * Based on work by Tom Armistead and Ajit Prem
+ * Copyright 2004 Motorola Inc.
+ */
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/mm.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/proc_fs.h>
+#include <linux/pci.h>
+#include <linux/poll.h>
+#include <linux/dma-mapping.h>
+#include <linux/interrupt.h>
+#include <linux/spinlock.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/time.h>
+#include <linux/io.h>
+#include <linux/uaccess.h>
+#include <linux/byteorder/generic.h>
+
+#include "vme.h"
+#include "vme_bridge.h"
+#include "vme_tsi148.h"
+
+static int tsi148_probe(struct pci_dev *, const struct pci_device_id *);
+static void tsi148_remove(struct pci_dev *);
+
+
+/* Module parameter */
+static bool err_chk;
+static int geoid;
+
+static const char driver_name[] = "vme_tsi148";
+
+static const struct pci_device_id tsi148_ids[] = {
+ { PCI_DEVICE(PCI_VENDOR_ID_TUNDRA, PCI_DEVICE_ID_TUNDRA_TSI148) },
+ { },
+};
+
+MODULE_DEVICE_TABLE(pci, tsi148_ids);
+
+static struct pci_driver tsi148_driver = {
+ .name = driver_name,
+ .id_table = tsi148_ids,
+ .probe = tsi148_probe,
+ .remove = tsi148_remove,
+};
+
+static void reg_join(unsigned int high, unsigned int low,
+ unsigned long long *variable)
+{
+ *variable = (unsigned long long)high << 32;
+ *variable |= (unsigned long long)low;
+}
+
+static void reg_split(unsigned long long variable, unsigned int *high,
+ unsigned int *low)
+{
+ *low = (unsigned int)variable & 0xFFFFFFFF;
+ *high = (unsigned int)(variable >> 32);
+}
+
+/*
+ * Wakes up DMA queue.
+ */
+static u32 tsi148_DMA_irqhandler(struct tsi148_driver *bridge,
+ int channel_mask)
+{
+ u32 serviced = 0;
+
+ if (channel_mask & TSI148_LCSR_INTS_DMA0S) {
+ wake_up(&bridge->dma_queue[0]);
+ serviced |= TSI148_LCSR_INTC_DMA0C;
+ }
+ if (channel_mask & TSI148_LCSR_INTS_DMA1S) {
+ wake_up(&bridge->dma_queue[1]);
+ serviced |= TSI148_LCSR_INTC_DMA1C;
+ }
+
+ return serviced;
+}
+
+/*
+ * Wake up location monitor queue
+ */
+static u32 tsi148_LM_irqhandler(struct tsi148_driver *bridge, u32 stat)
+{
+ int i;
+ u32 serviced = 0;
+
+ for (i = 0; i < 4; i++) {
+ if (stat & TSI148_LCSR_INTS_LMS[i]) {
+ /* We only enable interrupts if the callback is set */
+ bridge->lm_callback[i](bridge->lm_data[i]);
+ serviced |= TSI148_LCSR_INTC_LMC[i];
+ }
+ }
+
+ return serviced;
+}
+
+/*
+ * Wake up mail box queue.
+ *
+ * XXX This functionality is not exposed up though API.
+ */
+static u32 tsi148_MB_irqhandler(struct vme_bridge *tsi148_bridge, u32 stat)
+{
+ int i;
+ u32 val;
+ u32 serviced = 0;
+ struct tsi148_driver *bridge;
+
+ bridge = tsi148_bridge->driver_priv;
+
+ for (i = 0; i < 4; i++) {
+ if (stat & TSI148_LCSR_INTS_MBS[i]) {
+ val = ioread32be(bridge->base + TSI148_GCSR_MBOX[i]);
+ dev_err(tsi148_bridge->parent, "VME Mailbox %d received"
+ ": 0x%x\n", i, val);
+ serviced |= TSI148_LCSR_INTC_MBC[i];
+ }
+ }
+
+ return serviced;
+}
+
+/*
+ * Display error & status message when PERR (PCI) exception interrupt occurs.
+ */
+static u32 tsi148_PERR_irqhandler(struct vme_bridge *tsi148_bridge)
+{
+ struct tsi148_driver *bridge;
+
+ bridge = tsi148_bridge->driver_priv;
+
+ dev_err(tsi148_bridge->parent, "PCI Exception at address: 0x%08x:%08x, "
+ "attributes: %08x\n",
+ ioread32be(bridge->base + TSI148_LCSR_EDPAU),
+ ioread32be(bridge->base + TSI148_LCSR_EDPAL),
+ ioread32be(bridge->base + TSI148_LCSR_EDPAT));
+
+ dev_err(tsi148_bridge->parent, "PCI-X attribute reg: %08x, PCI-X split "
+ "completion reg: %08x\n",
+ ioread32be(bridge->base + TSI148_LCSR_EDPXA),
+ ioread32be(bridge->base + TSI148_LCSR_EDPXS));
+
+ iowrite32be(TSI148_LCSR_EDPAT_EDPCL, bridge->base + TSI148_LCSR_EDPAT);
+
+ return TSI148_LCSR_INTC_PERRC;
+}
+
+/*
+ * Save address and status when VME error interrupt occurs.
+ */
+static u32 tsi148_VERR_irqhandler(struct vme_bridge *tsi148_bridge)
+{
+ unsigned int error_addr_high, error_addr_low;
+ unsigned long long error_addr;
+ u32 error_attrib;
+ int error_am;
+ struct tsi148_driver *bridge;
+
+ bridge = tsi148_bridge->driver_priv;
+
+ error_addr_high = ioread32be(bridge->base + TSI148_LCSR_VEAU);
+ error_addr_low = ioread32be(bridge->base + TSI148_LCSR_VEAL);
+ error_attrib = ioread32be(bridge->base + TSI148_LCSR_VEAT);
+ error_am = (error_attrib & TSI148_LCSR_VEAT_AM_M) >> 8;
+
+ reg_join(error_addr_high, error_addr_low, &error_addr);
+
+ /* Check for exception register overflow (we have lost error data) */
+ if (error_attrib & TSI148_LCSR_VEAT_VEOF) {
+ dev_err(tsi148_bridge->parent, "VME Bus Exception Overflow "
+ "Occurred\n");
+ }
+
+ if (err_chk)
+ vme_bus_error_handler(tsi148_bridge, error_addr, error_am);
+ else
+ dev_err(tsi148_bridge->parent,
+ "VME Bus Error at address: 0x%llx, attributes: %08x\n",
+ error_addr, error_attrib);
+
+ /* Clear Status */
+ iowrite32be(TSI148_LCSR_VEAT_VESCL, bridge->base + TSI148_LCSR_VEAT);
+
+ return TSI148_LCSR_INTC_VERRC;
+}
+
+/*
+ * Wake up IACK queue.
+ */
+static u32 tsi148_IACK_irqhandler(struct tsi148_driver *bridge)
+{
+ wake_up(&bridge->iack_queue);
+
+ return TSI148_LCSR_INTC_IACKC;
+}
+
+/*
+ * Calling VME bus interrupt callback if provided.
+ */
+static u32 tsi148_VIRQ_irqhandler(struct vme_bridge *tsi148_bridge,
+ u32 stat)
+{
+ int vec, i, serviced = 0;
+ struct tsi148_driver *bridge;
+
+ bridge = tsi148_bridge->driver_priv;
+
+ for (i = 7; i > 0; i--) {
+ if (stat & (1 << i)) {
+ /*
+ * Note: Even though the registers are defined as
+ * 32-bits in the spec, we only want to issue 8-bit
+ * IACK cycles on the bus, read from offset 3.
+ */
+ vec = ioread8(bridge->base + TSI148_LCSR_VIACK[i] + 3);
+
+ vme_irq_handler(tsi148_bridge, i, vec);
+
+ serviced |= (1 << i);
+ }
+ }
+
+ return serviced;
+}
+
+/*
+ * Top level interrupt handler. Clears appropriate interrupt status bits and
+ * then calls appropriate sub handler(s).
+ */
+static irqreturn_t tsi148_irqhandler(int irq, void *ptr)
+{
+ u32 stat, enable, serviced = 0;
+ struct vme_bridge *tsi148_bridge;
+ struct tsi148_driver *bridge;
+
+ tsi148_bridge = ptr;
+
+ bridge = tsi148_bridge->driver_priv;
+
+ /* Determine which interrupts are unmasked and set */
+ enable = ioread32be(bridge->base + TSI148_LCSR_INTEO);
+ stat = ioread32be(bridge->base + TSI148_LCSR_INTS);
+
+ /* Only look at unmasked interrupts */
+ stat &= enable;
+
+ if (unlikely(!stat))
+ return IRQ_NONE;
+
+ /* Call subhandlers as appropriate */
+ /* DMA irqs */
+ if (stat & (TSI148_LCSR_INTS_DMA1S | TSI148_LCSR_INTS_DMA0S))
+ serviced |= tsi148_DMA_irqhandler(bridge, stat);
+
+ /* Location monitor irqs */
+ if (stat & (TSI148_LCSR_INTS_LM3S | TSI148_LCSR_INTS_LM2S |
+ TSI148_LCSR_INTS_LM1S | TSI148_LCSR_INTS_LM0S))
+ serviced |= tsi148_LM_irqhandler(bridge, stat);
+
+ /* Mail box irqs */
+ if (stat & (TSI148_LCSR_INTS_MB3S | TSI148_LCSR_INTS_MB2S |
+ TSI148_LCSR_INTS_MB1S | TSI148_LCSR_INTS_MB0S))
+ serviced |= tsi148_MB_irqhandler(tsi148_bridge, stat);
+
+ /* PCI bus error */
+ if (stat & TSI148_LCSR_INTS_PERRS)
+ serviced |= tsi148_PERR_irqhandler(tsi148_bridge);
+
+ /* VME bus error */
+ if (stat & TSI148_LCSR_INTS_VERRS)
+ serviced |= tsi148_VERR_irqhandler(tsi148_bridge);
+
+ /* IACK irq */
+ if (stat & TSI148_LCSR_INTS_IACKS)
+ serviced |= tsi148_IACK_irqhandler(bridge);
+
+ /* VME bus irqs */
+ if (stat & (TSI148_LCSR_INTS_IRQ7S | TSI148_LCSR_INTS_IRQ6S |
+ TSI148_LCSR_INTS_IRQ5S | TSI148_LCSR_INTS_IRQ4S |
+ TSI148_LCSR_INTS_IRQ3S | TSI148_LCSR_INTS_IRQ2S |
+ TSI148_LCSR_INTS_IRQ1S))
+ serviced |= tsi148_VIRQ_irqhandler(tsi148_bridge, stat);
+
+ /* Clear serviced interrupts */
+ iowrite32be(serviced, bridge->base + TSI148_LCSR_INTC);
+
+ return IRQ_HANDLED;
+}
+
+static int tsi148_irq_init(struct vme_bridge *tsi148_bridge)
+{
+ int result;
+ unsigned int tmp;
+ struct pci_dev *pdev;
+ struct tsi148_driver *bridge;
+
+ pdev = to_pci_dev(tsi148_bridge->parent);
+
+ bridge = tsi148_bridge->driver_priv;
+
+ result = request_irq(pdev->irq,
+ tsi148_irqhandler,
+ IRQF_SHARED,
+ driver_name, tsi148_bridge);
+ if (result) {
+ dev_err(tsi148_bridge->parent, "Can't get assigned pci irq "
+ "vector %02X\n", pdev->irq);
+ return result;
+ }
+
+ /* Enable and unmask interrupts */
+ tmp = TSI148_LCSR_INTEO_DMA1EO | TSI148_LCSR_INTEO_DMA0EO |
+ TSI148_LCSR_INTEO_MB3EO | TSI148_LCSR_INTEO_MB2EO |
+ TSI148_LCSR_INTEO_MB1EO | TSI148_LCSR_INTEO_MB0EO |
+ TSI148_LCSR_INTEO_PERREO | TSI148_LCSR_INTEO_VERREO |
+ TSI148_LCSR_INTEO_IACKEO;
+
+ /* This leaves the following interrupts masked.
+ * TSI148_LCSR_INTEO_VIEEO
+ * TSI148_LCSR_INTEO_SYSFLEO
+ * TSI148_LCSR_INTEO_ACFLEO
+ */
+
+ /* Don't enable Location Monitor interrupts here - they will be
+ * enabled when the location monitors are properly configured and
+ * a callback has been attached.
+ * TSI148_LCSR_INTEO_LM0EO
+ * TSI148_LCSR_INTEO_LM1EO
+ * TSI148_LCSR_INTEO_LM2EO
+ * TSI148_LCSR_INTEO_LM3EO
+ */
+
+ /* Don't enable VME interrupts until we add a handler, else the board
+ * will respond to it and we don't want that unless it knows how to
+ * properly deal with it.
+ * TSI148_LCSR_INTEO_IRQ7EO
+ * TSI148_LCSR_INTEO_IRQ6EO
+ * TSI148_LCSR_INTEO_IRQ5EO
+ * TSI148_LCSR_INTEO_IRQ4EO
+ * TSI148_LCSR_INTEO_IRQ3EO
+ * TSI148_LCSR_INTEO_IRQ2EO
+ * TSI148_LCSR_INTEO_IRQ1EO
+ */
+
+ iowrite32be(tmp, bridge->base + TSI148_LCSR_INTEO);
+ iowrite32be(tmp, bridge->base + TSI148_LCSR_INTEN);
+
+ return 0;
+}
+
+static void tsi148_irq_exit(struct vme_bridge *tsi148_bridge,
+ struct pci_dev *pdev)
+{
+ struct tsi148_driver *bridge = tsi148_bridge->driver_priv;
+
+ /* Turn off interrupts */
+ iowrite32be(0x0, bridge->base + TSI148_LCSR_INTEO);
+ iowrite32be(0x0, bridge->base + TSI148_LCSR_INTEN);
+
+ /* Clear all interrupts */
+ iowrite32be(0xFFFFFFFF, bridge->base + TSI148_LCSR_INTC);
+
+ /* Detach interrupt handler */
+ free_irq(pdev->irq, tsi148_bridge);
+}
+
+/*
+ * Check to see if an IACk has been received, return true (1) or false (0).
+ */
+static int tsi148_iack_received(struct tsi148_driver *bridge)
+{
+ u32 tmp;
+
+ tmp = ioread32be(bridge->base + TSI148_LCSR_VICR);
+
+ if (tmp & TSI148_LCSR_VICR_IRQS)
+ return 0;
+ else
+ return 1;
+}
+
+/*
+ * Configure VME interrupt
+ */
+static void tsi148_irq_set(struct vme_bridge *tsi148_bridge, int level,
+ int state, int sync)
+{
+ struct pci_dev *pdev;
+ u32 tmp;
+ struct tsi148_driver *bridge;
+
+ bridge = tsi148_bridge->driver_priv;
+
+ /* We need to do the ordering differently for enabling and disabling */
+ if (state == 0) {
+ tmp = ioread32be(bridge->base + TSI148_LCSR_INTEN);
+ tmp &= ~TSI148_LCSR_INTEN_IRQEN[level - 1];
+ iowrite32be(tmp, bridge->base + TSI148_LCSR_INTEN);
+
+ tmp = ioread32be(bridge->base + TSI148_LCSR_INTEO);
+ tmp &= ~TSI148_LCSR_INTEO_IRQEO[level - 1];
+ iowrite32be(tmp, bridge->base + TSI148_LCSR_INTEO);
+
+ if (sync != 0) {
+ pdev = to_pci_dev(tsi148_bridge->parent);
+ synchronize_irq(pdev->irq);
+ }
+ } else {
+ tmp = ioread32be(bridge->base + TSI148_LCSR_INTEO);
+ tmp |= TSI148_LCSR_INTEO_IRQEO[level - 1];
+ iowrite32be(tmp, bridge->base + TSI148_LCSR_INTEO);
+
+ tmp = ioread32be(bridge->base + TSI148_LCSR_INTEN);
+ tmp |= TSI148_LCSR_INTEN_IRQEN[level - 1];
+ iowrite32be(tmp, bridge->base + TSI148_LCSR_INTEN);
+ }
+}
+
+/*
+ * Generate a VME bus interrupt at the requested level & vector. Wait for
+ * interrupt to be acked.
+ */
+static int tsi148_irq_generate(struct vme_bridge *tsi148_bridge, int level,
+ int statid)
+{
+ u32 tmp;
+ struct tsi148_driver *bridge;
+
+ bridge = tsi148_bridge->driver_priv;
+
+ mutex_lock(&bridge->vme_int);
+
+ /* Read VICR register */
+ tmp = ioread32be(bridge->base + TSI148_LCSR_VICR);
+
+ /* Set Status/ID */
+ tmp = (tmp & ~TSI148_LCSR_VICR_STID_M) |
+ (statid & TSI148_LCSR_VICR_STID_M);
+ iowrite32be(tmp, bridge->base + TSI148_LCSR_VICR);
+
+ /* Assert VMEbus IRQ */
+ tmp = tmp | TSI148_LCSR_VICR_IRQL[level];
+ iowrite32be(tmp, bridge->base + TSI148_LCSR_VICR);
+
+ /* XXX Consider implementing a timeout? */
+ wait_event_interruptible(bridge->iack_queue,
+ tsi148_iack_received(bridge));
+
+ mutex_unlock(&bridge->vme_int);
+
+ return 0;
+}
+
+/*
+ * Initialize a slave window with the requested attributes.
+ */
+static int tsi148_slave_set(struct vme_slave_resource *image, int enabled,
+ unsigned long long vme_base, unsigned long long size,
+ dma_addr_t pci_base, u32 aspace, u32 cycle)
+{
+ unsigned int i, addr = 0, granularity = 0;
+ unsigned int temp_ctl = 0;
+ unsigned int vme_base_low, vme_base_high;
+ unsigned int vme_bound_low, vme_bound_high;
+ unsigned int pci_offset_low, pci_offset_high;
+ unsigned long long vme_bound, pci_offset;
+ struct vme_bridge *tsi148_bridge;
+ struct tsi148_driver *bridge;
+
+ tsi148_bridge = image->parent;
+ bridge = tsi148_bridge->driver_priv;
+
+ i = image->number;
+
+ switch (aspace) {
+ case VME_A16:
+ granularity = 0x10;
+ addr |= TSI148_LCSR_ITAT_AS_A16;
+ break;
+ case VME_A24:
+ granularity = 0x1000;
+ addr |= TSI148_LCSR_ITAT_AS_A24;
+ break;
+ case VME_A32:
+ granularity = 0x10000;
+ addr |= TSI148_LCSR_ITAT_AS_A32;
+ break;
+ case VME_A64:
+ granularity = 0x10000;
+ addr |= TSI148_LCSR_ITAT_AS_A64;
+ break;
+ default:
+ dev_err(tsi148_bridge->parent, "Invalid address space\n");
+ return -EINVAL;
+ }
+
+ /* Convert 64-bit variables to 2x 32-bit variables */
+ reg_split(vme_base, &vme_base_high, &vme_base_low);
+
+ /*
+ * Bound address is a valid address for the window, adjust
+ * accordingly
+ */
+ vme_bound = vme_base + size - granularity;
+ reg_split(vme_bound, &vme_bound_high, &vme_bound_low);
+ pci_offset = (unsigned long long)pci_base - vme_base;
+ reg_split(pci_offset, &pci_offset_high, &pci_offset_low);
+
+ if (vme_base_low & (granularity - 1)) {
+ dev_err(tsi148_bridge->parent, "Invalid VME base alignment\n");
+ return -EINVAL;
+ }
+ if (vme_bound_low & (granularity - 1)) {
+ dev_err(tsi148_bridge->parent, "Invalid VME bound alignment\n");
+ return -EINVAL;
+ }
+ if (pci_offset_low & (granularity - 1)) {
+ dev_err(tsi148_bridge->parent, "Invalid PCI Offset "
+ "alignment\n");
+ return -EINVAL;
+ }
+
+ /* Disable while we are mucking around */
+ temp_ctl = ioread32be(bridge->base + TSI148_LCSR_IT[i] +
+ TSI148_LCSR_OFFSET_ITAT);
+ temp_ctl &= ~TSI148_LCSR_ITAT_EN;
+ iowrite32be(temp_ctl, bridge->base + TSI148_LCSR_IT[i] +
+ TSI148_LCSR_OFFSET_ITAT);
+
+ /* Setup mapping */
+ iowrite32be(vme_base_high, bridge->base + TSI148_LCSR_IT[i] +
+ TSI148_LCSR_OFFSET_ITSAU);
+ iowrite32be(vme_base_low, bridge->base + TSI148_LCSR_IT[i] +
+ TSI148_LCSR_OFFSET_ITSAL);
+ iowrite32be(vme_bound_high, bridge->base + TSI148_LCSR_IT[i] +
+ TSI148_LCSR_OFFSET_ITEAU);
+ iowrite32be(vme_bound_low, bridge->base + TSI148_LCSR_IT[i] +
+ TSI148_LCSR_OFFSET_ITEAL);
+ iowrite32be(pci_offset_high, bridge->base + TSI148_LCSR_IT[i] +
+ TSI148_LCSR_OFFSET_ITOFU);
+ iowrite32be(pci_offset_low, bridge->base + TSI148_LCSR_IT[i] +
+ TSI148_LCSR_OFFSET_ITOFL);
+
+ /* Setup 2eSST speeds */
+ temp_ctl &= ~TSI148_LCSR_ITAT_2eSSTM_M;
+ switch (cycle & (VME_2eSST160 | VME_2eSST267 | VME_2eSST320)) {
+ case VME_2eSST160:
+ temp_ctl |= TSI148_LCSR_ITAT_2eSSTM_160;
+ break;
+ case VME_2eSST267:
+ temp_ctl |= TSI148_LCSR_ITAT_2eSSTM_267;
+ break;
+ case VME_2eSST320:
+ temp_ctl |= TSI148_LCSR_ITAT_2eSSTM_320;
+ break;
+ }
+
+ /* Setup cycle types */
+ temp_ctl &= ~(0x1F << 7);
+ if (cycle & VME_BLT)
+ temp_ctl |= TSI148_LCSR_ITAT_BLT;
+ if (cycle & VME_MBLT)
+ temp_ctl |= TSI148_LCSR_ITAT_MBLT;
+ if (cycle & VME_2eVME)
+ temp_ctl |= TSI148_LCSR_ITAT_2eVME;
+ if (cycle & VME_2eSST)
+ temp_ctl |= TSI148_LCSR_ITAT_2eSST;
+ if (cycle & VME_2eSSTB)
+ temp_ctl |= TSI148_LCSR_ITAT_2eSSTB;
+
+ /* Setup address space */
+ temp_ctl &= ~TSI148_LCSR_ITAT_AS_M;
+ temp_ctl |= addr;
+
+ temp_ctl &= ~0xF;
+ if (cycle & VME_SUPER)
+ temp_ctl |= TSI148_LCSR_ITAT_SUPR ;
+ if (cycle & VME_USER)
+ temp_ctl |= TSI148_LCSR_ITAT_NPRIV;
+ if (cycle & VME_PROG)
+ temp_ctl |= TSI148_LCSR_ITAT_PGM;
+ if (cycle & VME_DATA)
+ temp_ctl |= TSI148_LCSR_ITAT_DATA;
+
+ /* Write ctl reg without enable */
+ iowrite32be(temp_ctl, bridge->base + TSI148_LCSR_IT[i] +
+ TSI148_LCSR_OFFSET_ITAT);
+
+ if (enabled)
+ temp_ctl |= TSI148_LCSR_ITAT_EN;
+
+ iowrite32be(temp_ctl, bridge->base + TSI148_LCSR_IT[i] +
+ TSI148_LCSR_OFFSET_ITAT);
+
+ return 0;
+}
+
+/*
+ * Get slave window configuration.
+ */
+static int tsi148_slave_get(struct vme_slave_resource *image, int *enabled,
+ unsigned long long *vme_base, unsigned long long *size,
+ dma_addr_t *pci_base, u32 *aspace, u32 *cycle)
+{
+ unsigned int i, granularity = 0, ctl = 0;
+ unsigned int vme_base_low, vme_base_high;
+ unsigned int vme_bound_low, vme_bound_high;
+ unsigned int pci_offset_low, pci_offset_high;
+ unsigned long long vme_bound, pci_offset;
+ struct tsi148_driver *bridge;
+
+ bridge = image->parent->driver_priv;
+
+ i = image->number;
+
+ /* Read registers */
+ ctl = ioread32be(bridge->base + TSI148_LCSR_IT[i] +
+ TSI148_LCSR_OFFSET_ITAT);
+
+ vme_base_high = ioread32be(bridge->base + TSI148_LCSR_IT[i] +
+ TSI148_LCSR_OFFSET_ITSAU);
+ vme_base_low = ioread32be(bridge->base + TSI148_LCSR_IT[i] +
+ TSI148_LCSR_OFFSET_ITSAL);
+ vme_bound_high = ioread32be(bridge->base + TSI148_LCSR_IT[i] +
+ TSI148_LCSR_OFFSET_ITEAU);
+ vme_bound_low = ioread32be(bridge->base + TSI148_LCSR_IT[i] +
+ TSI148_LCSR_OFFSET_ITEAL);
+ pci_offset_high = ioread32be(bridge->base + TSI148_LCSR_IT[i] +
+ TSI148_LCSR_OFFSET_ITOFU);
+ pci_offset_low = ioread32be(bridge->base + TSI148_LCSR_IT[i] +
+ TSI148_LCSR_OFFSET_ITOFL);
+
+ /* Convert 64-bit variables to 2x 32-bit variables */
+ reg_join(vme_base_high, vme_base_low, vme_base);
+ reg_join(vme_bound_high, vme_bound_low, &vme_bound);
+ reg_join(pci_offset_high, pci_offset_low, &pci_offset);
+
+ *pci_base = (dma_addr_t)(*vme_base + pci_offset);
+
+ *enabled = 0;
+ *aspace = 0;
+ *cycle = 0;
+
+ if (ctl & TSI148_LCSR_ITAT_EN)
+ *enabled = 1;
+
+ if ((ctl & TSI148_LCSR_ITAT_AS_M) == TSI148_LCSR_ITAT_AS_A16) {
+ granularity = 0x10;
+ *aspace |= VME_A16;
+ }
+ if ((ctl & TSI148_LCSR_ITAT_AS_M) == TSI148_LCSR_ITAT_AS_A24) {
+ granularity = 0x1000;
+ *aspace |= VME_A24;
+ }
+ if ((ctl & TSI148_LCSR_ITAT_AS_M) == TSI148_LCSR_ITAT_AS_A32) {
+ granularity = 0x10000;
+ *aspace |= VME_A32;
+ }
+ if ((ctl & TSI148_LCSR_ITAT_AS_M) == TSI148_LCSR_ITAT_AS_A64) {
+ granularity = 0x10000;
+ *aspace |= VME_A64;
+ }
+
+ /* Need granularity before we set the size */
+ *size = (unsigned long long)((vme_bound - *vme_base) + granularity);
+
+
+ if ((ctl & TSI148_LCSR_ITAT_2eSSTM_M) == TSI148_LCSR_ITAT_2eSSTM_160)
+ *cycle |= VME_2eSST160;
+ if ((ctl & TSI148_LCSR_ITAT_2eSSTM_M) == TSI148_LCSR_ITAT_2eSSTM_267)
+ *cycle |= VME_2eSST267;
+ if ((ctl & TSI148_LCSR_ITAT_2eSSTM_M) == TSI148_LCSR_ITAT_2eSSTM_320)
+ *cycle |= VME_2eSST320;
+
+ if (ctl & TSI148_LCSR_ITAT_BLT)
+ *cycle |= VME_BLT;
+ if (ctl & TSI148_LCSR_ITAT_MBLT)
+ *cycle |= VME_MBLT;
+ if (ctl & TSI148_LCSR_ITAT_2eVME)
+ *cycle |= VME_2eVME;
+ if (ctl & TSI148_LCSR_ITAT_2eSST)
+ *cycle |= VME_2eSST;
+ if (ctl & TSI148_LCSR_ITAT_2eSSTB)
+ *cycle |= VME_2eSSTB;
+
+ if (ctl & TSI148_LCSR_ITAT_SUPR)
+ *cycle |= VME_SUPER;
+ if (ctl & TSI148_LCSR_ITAT_NPRIV)
+ *cycle |= VME_USER;
+ if (ctl & TSI148_LCSR_ITAT_PGM)
+ *cycle |= VME_PROG;
+ if (ctl & TSI148_LCSR_ITAT_DATA)
+ *cycle |= VME_DATA;
+
+ return 0;
+}
+
+/*
+ * Allocate and map PCI Resource
+ */
+static int tsi148_alloc_resource(struct vme_master_resource *image,
+ unsigned long long size)
+{
+ unsigned long long existing_size;
+ int retval = 0;
+ struct pci_dev *pdev;
+ struct vme_bridge *tsi148_bridge;
+
+ tsi148_bridge = image->parent;
+
+ pdev = to_pci_dev(tsi148_bridge->parent);
+
+ existing_size = (unsigned long long)(image->bus_resource.end -
+ image->bus_resource.start);
+
+ /* If the existing size is OK, return */
+ if ((size != 0) && (existing_size == (size - 1)))
+ return 0;
+
+ if (existing_size != 0) {
+ iounmap(image->kern_base);
+ image->kern_base = NULL;
+ kfree(image->bus_resource.name);
+ release_resource(&image->bus_resource);
+ memset(&image->bus_resource, 0, sizeof(image->bus_resource));
+ }
+
+ /* Exit here if size is zero */
+ if (size == 0)
+ return 0;
+
+ if (!image->bus_resource.name) {
+ image->bus_resource.name = kmalloc(VMENAMSIZ+3, GFP_ATOMIC);
+ if (!image->bus_resource.name) {
+ retval = -ENOMEM;
+ goto err_name;
+ }
+ }
+
+ sprintf((char *)image->bus_resource.name, "%s.%d", tsi148_bridge->name,
+ image->number);
+
+ image->bus_resource.start = 0;
+ image->bus_resource.end = (unsigned long)size;
+ image->bus_resource.flags = IORESOURCE_MEM;
+
+ retval = pci_bus_alloc_resource(pdev->bus,
+ &image->bus_resource, size, 0x10000, PCIBIOS_MIN_MEM,
+ 0, NULL, NULL);
+ if (retval) {
+ dev_err(tsi148_bridge->parent, "Failed to allocate mem "
+ "resource for window %d size 0x%lx start 0x%lx\n",
+ image->number, (unsigned long)size,
+ (unsigned long)image->bus_resource.start);
+ goto err_resource;
+ }
+
+ image->kern_base = ioremap(
+ image->bus_resource.start, size);
+ if (!image->kern_base) {
+ dev_err(tsi148_bridge->parent, "Failed to remap resource\n");
+ retval = -ENOMEM;
+ goto err_remap;
+ }
+
+ return 0;
+
+err_remap:
+ release_resource(&image->bus_resource);
+err_resource:
+ kfree(image->bus_resource.name);
+ memset(&image->bus_resource, 0, sizeof(image->bus_resource));
+err_name:
+ return retval;
+}
+
+/*
+ * Free and unmap PCI Resource
+ */
+static void tsi148_free_resource(struct vme_master_resource *image)
+{
+ iounmap(image->kern_base);
+ image->kern_base = NULL;
+ release_resource(&image->bus_resource);
+ kfree(image->bus_resource.name);
+ memset(&image->bus_resource, 0, sizeof(image->bus_resource));
+}
+
+/*
+ * Set the attributes of an outbound window.
+ */
+static int tsi148_master_set(struct vme_master_resource *image, int enabled,
+ unsigned long long vme_base, unsigned long long size, u32 aspace,
+ u32 cycle, u32 dwidth)
+{
+ int retval = 0;
+ unsigned int i;
+ unsigned int temp_ctl = 0;
+ unsigned int pci_base_low, pci_base_high;
+ unsigned int pci_bound_low, pci_bound_high;
+ unsigned int vme_offset_low, vme_offset_high;
+ unsigned long long pci_bound, vme_offset, pci_base;
+ struct vme_bridge *tsi148_bridge;
+ struct tsi148_driver *bridge;
+ struct pci_bus_region region;
+ struct pci_dev *pdev;
+
+ tsi148_bridge = image->parent;
+
+ bridge = tsi148_bridge->driver_priv;
+
+ pdev = to_pci_dev(tsi148_bridge->parent);
+
+ /* Verify input data */
+ if (vme_base & 0xFFFF) {
+ dev_err(tsi148_bridge->parent, "Invalid VME Window "
+ "alignment\n");
+ retval = -EINVAL;
+ goto err_window;
+ }
+
+ if ((size == 0) && (enabled != 0)) {
+ dev_err(tsi148_bridge->parent, "Size must be non-zero for "
+ "enabled windows\n");
+ retval = -EINVAL;
+ goto err_window;
+ }
+
+ spin_lock(&image->lock);
+
+ /* Let's allocate the resource here rather than further up the stack as
+ * it avoids pushing loads of bus dependent stuff up the stack. If size
+ * is zero, any existing resource will be freed.
+ */
+ retval = tsi148_alloc_resource(image, size);
+ if (retval) {
+ spin_unlock(&image->lock);
+ dev_err(tsi148_bridge->parent, "Unable to allocate memory for "
+ "resource\n");
+ goto err_res;
+ }
+
+ if (size == 0) {
+ pci_base = 0;
+ pci_bound = 0;
+ vme_offset = 0;
+ } else {
+ pcibios_resource_to_bus(pdev->bus, &region,
+ &image->bus_resource);
+ pci_base = region.start;
+
+ /*
+ * Bound address is a valid address for the window, adjust
+ * according to window granularity.
+ */
+ pci_bound = pci_base + (size - 0x10000);
+ vme_offset = vme_base - pci_base;
+ }
+
+ /* Convert 64-bit variables to 2x 32-bit variables */
+ reg_split(pci_base, &pci_base_high, &pci_base_low);
+ reg_split(pci_bound, &pci_bound_high, &pci_bound_low);
+ reg_split(vme_offset, &vme_offset_high, &vme_offset_low);
+
+ if (pci_base_low & 0xFFFF) {
+ spin_unlock(&image->lock);
+ dev_err(tsi148_bridge->parent, "Invalid PCI base alignment\n");
+ retval = -EINVAL;
+ goto err_gran;
+ }
+ if (pci_bound_low & 0xFFFF) {
+ spin_unlock(&image->lock);
+ dev_err(tsi148_bridge->parent, "Invalid PCI bound alignment\n");
+ retval = -EINVAL;
+ goto err_gran;
+ }
+ if (vme_offset_low & 0xFFFF) {
+ spin_unlock(&image->lock);
+ dev_err(tsi148_bridge->parent, "Invalid VME Offset "
+ "alignment\n");
+ retval = -EINVAL;
+ goto err_gran;
+ }
+
+ i = image->number;
+
+ /* Disable while we are mucking around */
+ temp_ctl = ioread32be(bridge->base + TSI148_LCSR_OT[i] +
+ TSI148_LCSR_OFFSET_OTAT);
+ temp_ctl &= ~TSI148_LCSR_OTAT_EN;
+ iowrite32be(temp_ctl, bridge->base + TSI148_LCSR_OT[i] +
+ TSI148_LCSR_OFFSET_OTAT);
+
+ /* Setup 2eSST speeds */
+ temp_ctl &= ~TSI148_LCSR_OTAT_2eSSTM_M;
+ switch (cycle & (VME_2eSST160 | VME_2eSST267 | VME_2eSST320)) {
+ case VME_2eSST160:
+ temp_ctl |= TSI148_LCSR_OTAT_2eSSTM_160;
+ break;
+ case VME_2eSST267:
+ temp_ctl |= TSI148_LCSR_OTAT_2eSSTM_267;
+ break;
+ case VME_2eSST320:
+ temp_ctl |= TSI148_LCSR_OTAT_2eSSTM_320;
+ break;
+ }
+
+ /* Setup cycle types */
+ if (cycle & VME_BLT) {
+ temp_ctl &= ~TSI148_LCSR_OTAT_TM_M;
+ temp_ctl |= TSI148_LCSR_OTAT_TM_BLT;
+ }
+ if (cycle & VME_MBLT) {
+ temp_ctl &= ~TSI148_LCSR_OTAT_TM_M;
+ temp_ctl |= TSI148_LCSR_OTAT_TM_MBLT;
+ }
+ if (cycle & VME_2eVME) {
+ temp_ctl &= ~TSI148_LCSR_OTAT_TM_M;
+ temp_ctl |= TSI148_LCSR_OTAT_TM_2eVME;
+ }
+ if (cycle & VME_2eSST) {
+ temp_ctl &= ~TSI148_LCSR_OTAT_TM_M;
+ temp_ctl |= TSI148_LCSR_OTAT_TM_2eSST;
+ }
+ if (cycle & VME_2eSSTB) {
+ dev_warn(tsi148_bridge->parent, "Currently not setting "
+ "Broadcast Select Registers\n");
+ temp_ctl &= ~TSI148_LCSR_OTAT_TM_M;
+ temp_ctl |= TSI148_LCSR_OTAT_TM_2eSSTB;
+ }
+
+ /* Setup data width */
+ temp_ctl &= ~TSI148_LCSR_OTAT_DBW_M;
+ switch (dwidth) {
+ case VME_D16:
+ temp_ctl |= TSI148_LCSR_OTAT_DBW_16;
+ break;
+ case VME_D32:
+ temp_ctl |= TSI148_LCSR_OTAT_DBW_32;
+ break;
+ default:
+ spin_unlock(&image->lock);
+ dev_err(tsi148_bridge->parent, "Invalid data width\n");
+ retval = -EINVAL;
+ goto err_dwidth;
+ }
+
+ /* Setup address space */
+ temp_ctl &= ~TSI148_LCSR_OTAT_AMODE_M;
+ switch (aspace) {
+ case VME_A16:
+ temp_ctl |= TSI148_LCSR_OTAT_AMODE_A16;
+ break;
+ case VME_A24:
+ temp_ctl |= TSI148_LCSR_OTAT_AMODE_A24;
+ break;
+ case VME_A32:
+ temp_ctl |= TSI148_LCSR_OTAT_AMODE_A32;
+ break;
+ case VME_A64:
+ temp_ctl |= TSI148_LCSR_OTAT_AMODE_A64;
+ break;
+ case VME_CRCSR:
+ temp_ctl |= TSI148_LCSR_OTAT_AMODE_CRCSR;
+ break;
+ case VME_USER1:
+ temp_ctl |= TSI148_LCSR_OTAT_AMODE_USER1;
+ break;
+ case VME_USER2:
+ temp_ctl |= TSI148_LCSR_OTAT_AMODE_USER2;
+ break;
+ case VME_USER3:
+ temp_ctl |= TSI148_LCSR_OTAT_AMODE_USER3;
+ break;
+ case VME_USER4:
+ temp_ctl |= TSI148_LCSR_OTAT_AMODE_USER4;
+ break;
+ default:
+ spin_unlock(&image->lock);
+ dev_err(tsi148_bridge->parent, "Invalid address space\n");
+ retval = -EINVAL;
+ goto err_aspace;
+ }
+
+ temp_ctl &= ~(3<<4);
+ if (cycle & VME_SUPER)
+ temp_ctl |= TSI148_LCSR_OTAT_SUP;
+ if (cycle & VME_PROG)
+ temp_ctl |= TSI148_LCSR_OTAT_PGM;
+
+ /* Setup mapping */
+ iowrite32be(pci_base_high, bridge->base + TSI148_LCSR_OT[i] +
+ TSI148_LCSR_OFFSET_OTSAU);
+ iowrite32be(pci_base_low, bridge->base + TSI148_LCSR_OT[i] +
+ TSI148_LCSR_OFFSET_OTSAL);
+ iowrite32be(pci_bound_high, bridge->base + TSI148_LCSR_OT[i] +
+ TSI148_LCSR_OFFSET_OTEAU);
+ iowrite32be(pci_bound_low, bridge->base + TSI148_LCSR_OT[i] +
+ TSI148_LCSR_OFFSET_OTEAL);
+ iowrite32be(vme_offset_high, bridge->base + TSI148_LCSR_OT[i] +
+ TSI148_LCSR_OFFSET_OTOFU);
+ iowrite32be(vme_offset_low, bridge->base + TSI148_LCSR_OT[i] +
+ TSI148_LCSR_OFFSET_OTOFL);
+
+ /* Write ctl reg without enable */
+ iowrite32be(temp_ctl, bridge->base + TSI148_LCSR_OT[i] +
+ TSI148_LCSR_OFFSET_OTAT);
+
+ if (enabled)
+ temp_ctl |= TSI148_LCSR_OTAT_EN;
+
+ iowrite32be(temp_ctl, bridge->base + TSI148_LCSR_OT[i] +
+ TSI148_LCSR_OFFSET_OTAT);
+
+ spin_unlock(&image->lock);
+ return 0;
+
+err_aspace:
+err_dwidth:
+err_gran:
+ tsi148_free_resource(image);
+err_res:
+err_window:
+ return retval;
+
+}
+
+/*
+ * Set the attributes of an outbound window.
+ *
+ * XXX Not parsing prefetch information.
+ */
+static int __tsi148_master_get(struct vme_master_resource *image, int *enabled,
+ unsigned long long *vme_base, unsigned long long *size, u32 *aspace,
+ u32 *cycle, u32 *dwidth)
+{
+ unsigned int i, ctl;
+ unsigned int pci_base_low, pci_base_high;
+ unsigned int pci_bound_low, pci_bound_high;
+ unsigned int vme_offset_low, vme_offset_high;
+
+ unsigned long long pci_base, pci_bound, vme_offset;
+ struct tsi148_driver *bridge;
+
+ bridge = image->parent->driver_priv;
+
+ i = image->number;
+
+ ctl = ioread32be(bridge->base + TSI148_LCSR_OT[i] +
+ TSI148_LCSR_OFFSET_OTAT);
+
+ pci_base_high = ioread32be(bridge->base + TSI148_LCSR_OT[i] +
+ TSI148_LCSR_OFFSET_OTSAU);
+ pci_base_low = ioread32be(bridge->base + TSI148_LCSR_OT[i] +
+ TSI148_LCSR_OFFSET_OTSAL);
+ pci_bound_high = ioread32be(bridge->base + TSI148_LCSR_OT[i] +
+ TSI148_LCSR_OFFSET_OTEAU);
+ pci_bound_low = ioread32be(bridge->base + TSI148_LCSR_OT[i] +
+ TSI148_LCSR_OFFSET_OTEAL);
+ vme_offset_high = ioread32be(bridge->base + TSI148_LCSR_OT[i] +
+ TSI148_LCSR_OFFSET_OTOFU);
+ vme_offset_low = ioread32be(bridge->base + TSI148_LCSR_OT[i] +
+ TSI148_LCSR_OFFSET_OTOFL);
+
+ /* Convert 64-bit variables to 2x 32-bit variables */
+ reg_join(pci_base_high, pci_base_low, &pci_base);
+ reg_join(pci_bound_high, pci_bound_low, &pci_bound);
+ reg_join(vme_offset_high, vme_offset_low, &vme_offset);
+
+ *vme_base = pci_base + vme_offset;
+ *size = (unsigned long long)(pci_bound - pci_base) + 0x10000;
+
+ *enabled = 0;
+ *aspace = 0;
+ *cycle = 0;
+ *dwidth = 0;
+
+ if (ctl & TSI148_LCSR_OTAT_EN)
+ *enabled = 1;
+
+ /* Setup address space */
+ if ((ctl & TSI148_LCSR_OTAT_AMODE_M) == TSI148_LCSR_OTAT_AMODE_A16)
+ *aspace |= VME_A16;
+ if ((ctl & TSI148_LCSR_OTAT_AMODE_M) == TSI148_LCSR_OTAT_AMODE_A24)
+ *aspace |= VME_A24;
+ if ((ctl & TSI148_LCSR_OTAT_AMODE_M) == TSI148_LCSR_OTAT_AMODE_A32)
+ *aspace |= VME_A32;
+ if ((ctl & TSI148_LCSR_OTAT_AMODE_M) == TSI148_LCSR_OTAT_AMODE_A64)
+ *aspace |= VME_A64;
+ if ((ctl & TSI148_LCSR_OTAT_AMODE_M) == TSI148_LCSR_OTAT_AMODE_CRCSR)
+ *aspace |= VME_CRCSR;
+ if ((ctl & TSI148_LCSR_OTAT_AMODE_M) == TSI148_LCSR_OTAT_AMODE_USER1)
+ *aspace |= VME_USER1;
+ if ((ctl & TSI148_LCSR_OTAT_AMODE_M) == TSI148_LCSR_OTAT_AMODE_USER2)
+ *aspace |= VME_USER2;
+ if ((ctl & TSI148_LCSR_OTAT_AMODE_M) == TSI148_LCSR_OTAT_AMODE_USER3)
+ *aspace |= VME_USER3;
+ if ((ctl & TSI148_LCSR_OTAT_AMODE_M) == TSI148_LCSR_OTAT_AMODE_USER4)
+ *aspace |= VME_USER4;
+
+ /* Setup 2eSST speeds */
+ if ((ctl & TSI148_LCSR_OTAT_2eSSTM_M) == TSI148_LCSR_OTAT_2eSSTM_160)
+ *cycle |= VME_2eSST160;
+ if ((ctl & TSI148_LCSR_OTAT_2eSSTM_M) == TSI148_LCSR_OTAT_2eSSTM_267)
+ *cycle |= VME_2eSST267;
+ if ((ctl & TSI148_LCSR_OTAT_2eSSTM_M) == TSI148_LCSR_OTAT_2eSSTM_320)
+ *cycle |= VME_2eSST320;
+
+ /* Setup cycle types */
+ if ((ctl & TSI148_LCSR_OTAT_TM_M) == TSI148_LCSR_OTAT_TM_SCT)
+ *cycle |= VME_SCT;
+ if ((ctl & TSI148_LCSR_OTAT_TM_M) == TSI148_LCSR_OTAT_TM_BLT)
+ *cycle |= VME_BLT;
+ if ((ctl & TSI148_LCSR_OTAT_TM_M) == TSI148_LCSR_OTAT_TM_MBLT)
+ *cycle |= VME_MBLT;
+ if ((ctl & TSI148_LCSR_OTAT_TM_M) == TSI148_LCSR_OTAT_TM_2eVME)
+ *cycle |= VME_2eVME;
+ if ((ctl & TSI148_LCSR_OTAT_TM_M) == TSI148_LCSR_OTAT_TM_2eSST)
+ *cycle |= VME_2eSST;
+ if ((ctl & TSI148_LCSR_OTAT_TM_M) == TSI148_LCSR_OTAT_TM_2eSSTB)
+ *cycle |= VME_2eSSTB;
+
+ if (ctl & TSI148_LCSR_OTAT_SUP)
+ *cycle |= VME_SUPER;
+ else
+ *cycle |= VME_USER;
+
+ if (ctl & TSI148_LCSR_OTAT_PGM)
+ *cycle |= VME_PROG;
+ else
+ *cycle |= VME_DATA;
+
+ /* Setup data width */
+ if ((ctl & TSI148_LCSR_OTAT_DBW_M) == TSI148_LCSR_OTAT_DBW_16)
+ *dwidth = VME_D16;
+ if ((ctl & TSI148_LCSR_OTAT_DBW_M) == TSI148_LCSR_OTAT_DBW_32)
+ *dwidth = VME_D32;
+
+ return 0;
+}
+
+
+static int tsi148_master_get(struct vme_master_resource *image, int *enabled,
+ unsigned long long *vme_base, unsigned long long *size, u32 *aspace,
+ u32 *cycle, u32 *dwidth)
+{
+ int retval;
+
+ spin_lock(&image->lock);
+
+ retval = __tsi148_master_get(image, enabled, vme_base, size, aspace,
+ cycle, dwidth);
+
+ spin_unlock(&image->lock);
+
+ return retval;
+}
+
+static ssize_t tsi148_master_read(struct vme_master_resource *image, void *buf,
+ size_t count, loff_t offset)
+{
+ int retval, enabled;
+ unsigned long long vme_base, size;
+ u32 aspace, cycle, dwidth;
+ struct vme_error_handler *handler = NULL;
+ struct vme_bridge *tsi148_bridge;
+ void __iomem *addr = image->kern_base + offset;
+ unsigned int done = 0;
+ unsigned int count32;
+
+ tsi148_bridge = image->parent;
+
+ spin_lock(&image->lock);
+
+ if (err_chk) {
+ __tsi148_master_get(image, &enabled, &vme_base, &size, &aspace,
+ &cycle, &dwidth);
+ handler = vme_register_error_handler(tsi148_bridge, aspace,
+ vme_base + offset, count);
+ if (!handler) {
+ spin_unlock(&image->lock);
+ return -ENOMEM;
+ }
+ }
+
+ /* The following code handles VME address alignment. We cannot use
+ * memcpy_xxx here because it may cut data transfers in to 8-bit
+ * cycles when D16 or D32 cycles are required on the VME bus.
+ * On the other hand, the bridge itself assures that the maximum data
+ * cycle configured for the transfer is used and splits it
+ * automatically for non-aligned addresses, so we don't want the
+ * overhead of needlessly forcing small transfers for the entire cycle.
+ */
+ if ((uintptr_t)addr & 0x1) {
+ *(u8 *)buf = ioread8(addr);
+ done += 1;
+ if (done == count)
+ goto out;
+ }
+ if ((uintptr_t)(addr + done) & 0x2) {
+ if ((count - done) < 2) {
+ *(u8 *)(buf + done) = ioread8(addr + done);
+ done += 1;
+ goto out;
+ } else {
+ *(u16 *)(buf + done) = ioread16(addr + done);
+ done += 2;
+ }
+ }
+
+ count32 = (count - done) & ~0x3;
+ while (done < count32) {
+ *(u32 *)(buf + done) = ioread32(addr + done);
+ done += 4;
+ }
+
+ if ((count - done) & 0x2) {
+ *(u16 *)(buf + done) = ioread16(addr + done);
+ done += 2;
+ }
+ if ((count - done) & 0x1) {
+ *(u8 *)(buf + done) = ioread8(addr + done);
+ done += 1;
+ }
+
+out:
+ retval = count;
+
+ if (err_chk) {
+ if (handler->num_errors) {
+ dev_err(image->parent->parent,
+ "First VME read error detected an at address 0x%llx\n",
+ handler->first_error);
+ retval = handler->first_error - (vme_base + offset);
+ }
+ vme_unregister_error_handler(handler);
+ }
+
+ spin_unlock(&image->lock);
+
+ return retval;
+}
+
+
+static ssize_t tsi148_master_write(struct vme_master_resource *image, void *buf,
+ size_t count, loff_t offset)
+{
+ int retval = 0, enabled;
+ unsigned long long vme_base, size;
+ u32 aspace, cycle, dwidth;
+ void __iomem *addr = image->kern_base + offset;
+ unsigned int done = 0;
+ unsigned int count32;
+
+ struct vme_error_handler *handler = NULL;
+ struct vme_bridge *tsi148_bridge;
+ struct tsi148_driver *bridge;
+
+ tsi148_bridge = image->parent;
+
+ bridge = tsi148_bridge->driver_priv;
+
+ spin_lock(&image->lock);
+
+ if (err_chk) {
+ __tsi148_master_get(image, &enabled, &vme_base, &size, &aspace,
+ &cycle, &dwidth);
+ handler = vme_register_error_handler(tsi148_bridge, aspace,
+ vme_base + offset, count);
+ if (!handler) {
+ spin_unlock(&image->lock);
+ return -ENOMEM;
+ }
+ }
+
+ /* Here we apply for the same strategy we do in master_read
+ * function in order to assure the correct cycles.
+ */
+ if ((uintptr_t)addr & 0x1) {
+ iowrite8(*(u8 *)buf, addr);
+ done += 1;
+ if (done == count)
+ goto out;
+ }
+ if ((uintptr_t)(addr + done) & 0x2) {
+ if ((count - done) < 2) {
+ iowrite8(*(u8 *)(buf + done), addr + done);
+ done += 1;
+ goto out;
+ } else {
+ iowrite16(*(u16 *)(buf + done), addr + done);
+ done += 2;
+ }
+ }
+
+ count32 = (count - done) & ~0x3;
+ while (done < count32) {
+ iowrite32(*(u32 *)(buf + done), addr + done);
+ done += 4;
+ }
+
+ if ((count - done) & 0x2) {
+ iowrite16(*(u16 *)(buf + done), addr + done);
+ done += 2;
+ }
+ if ((count - done) & 0x1) {
+ iowrite8(*(u8 *)(buf + done), addr + done);
+ done += 1;
+ }
+
+out:
+ retval = count;
+
+ /*
+ * Writes are posted. We need to do a read on the VME bus to flush out
+ * all of the writes before we check for errors. We can't guarantee
+ * that reading the data we have just written is safe. It is believed
+ * that there isn't any read, write re-ordering, so we can read any
+ * location in VME space, so lets read the Device ID from the tsi148's
+ * own registers as mapped into CR/CSR space.
+ *
+ * We check for saved errors in the written address range/space.
+ */
+
+ if (err_chk) {
+ ioread16(bridge->flush_image->kern_base + 0x7F000);
+
+ if (handler->num_errors) {
+ dev_warn(tsi148_bridge->parent,
+ "First VME write error detected an at address 0x%llx\n",
+ handler->first_error);
+ retval = handler->first_error - (vme_base + offset);
+ }
+ vme_unregister_error_handler(handler);
+ }
+
+ spin_unlock(&image->lock);
+
+ return retval;
+}
+
+/*
+ * Perform an RMW cycle on the VME bus.
+ *
+ * Requires a previously configured master window, returns final value.
+ */
+static unsigned int tsi148_master_rmw(struct vme_master_resource *image,
+ unsigned int mask, unsigned int compare, unsigned int swap,
+ loff_t offset)
+{
+ unsigned long long pci_addr;
+ unsigned int pci_addr_high, pci_addr_low;
+ u32 tmp, result;
+ int i;
+ struct tsi148_driver *bridge;
+
+ bridge = image->parent->driver_priv;
+
+ /* Find the PCI address that maps to the desired VME address */
+ i = image->number;
+
+ /* Locking as we can only do one of these at a time */
+ mutex_lock(&bridge->vme_rmw);
+
+ /* Lock image */
+ spin_lock(&image->lock);
+
+ pci_addr_high = ioread32be(bridge->base + TSI148_LCSR_OT[i] +
+ TSI148_LCSR_OFFSET_OTSAU);
+ pci_addr_low = ioread32be(bridge->base + TSI148_LCSR_OT[i] +
+ TSI148_LCSR_OFFSET_OTSAL);
+
+ reg_join(pci_addr_high, pci_addr_low, &pci_addr);
+ reg_split(pci_addr + offset, &pci_addr_high, &pci_addr_low);
+
+ /* Configure registers */
+ iowrite32be(mask, bridge->base + TSI148_LCSR_RMWEN);
+ iowrite32be(compare, bridge->base + TSI148_LCSR_RMWC);
+ iowrite32be(swap, bridge->base + TSI148_LCSR_RMWS);
+ iowrite32be(pci_addr_high, bridge->base + TSI148_LCSR_RMWAU);
+ iowrite32be(pci_addr_low, bridge->base + TSI148_LCSR_RMWAL);
+
+ /* Enable RMW */
+ tmp = ioread32be(bridge->base + TSI148_LCSR_VMCTRL);
+ tmp |= TSI148_LCSR_VMCTRL_RMWEN;
+ iowrite32be(tmp, bridge->base + TSI148_LCSR_VMCTRL);
+
+ /* Kick process off with a read to the required address. */
+ result = ioread32be(image->kern_base + offset);
+
+ /* Disable RMW */
+ tmp = ioread32be(bridge->base + TSI148_LCSR_VMCTRL);
+ tmp &= ~TSI148_LCSR_VMCTRL_RMWEN;
+ iowrite32be(tmp, bridge->base + TSI148_LCSR_VMCTRL);
+
+ spin_unlock(&image->lock);
+
+ mutex_unlock(&bridge->vme_rmw);
+
+ return result;
+}
+
+static int tsi148_dma_set_vme_src_attributes(struct device *dev, __be32 *attr,
+ u32 aspace, u32 cycle, u32 dwidth)
+{
+ u32 val;
+
+ val = be32_to_cpu(*attr);
+
+ /* Setup 2eSST speeds */
+ switch (cycle & (VME_2eSST160 | VME_2eSST267 | VME_2eSST320)) {
+ case VME_2eSST160:
+ val |= TSI148_LCSR_DSAT_2eSSTM_160;
+ break;
+ case VME_2eSST267:
+ val |= TSI148_LCSR_DSAT_2eSSTM_267;
+ break;
+ case VME_2eSST320:
+ val |= TSI148_LCSR_DSAT_2eSSTM_320;
+ break;
+ }
+
+ /* Setup cycle types */
+ if (cycle & VME_SCT)
+ val |= TSI148_LCSR_DSAT_TM_SCT;
+
+ if (cycle & VME_BLT)
+ val |= TSI148_LCSR_DSAT_TM_BLT;
+
+ if (cycle & VME_MBLT)
+ val |= TSI148_LCSR_DSAT_TM_MBLT;
+
+ if (cycle & VME_2eVME)
+ val |= TSI148_LCSR_DSAT_TM_2eVME;
+
+ if (cycle & VME_2eSST)
+ val |= TSI148_LCSR_DSAT_TM_2eSST;
+
+ if (cycle & VME_2eSSTB) {
+ dev_err(dev, "Currently not setting Broadcast Select "
+ "Registers\n");
+ val |= TSI148_LCSR_DSAT_TM_2eSSTB;
+ }
+
+ /* Setup data width */
+ switch (dwidth) {
+ case VME_D16:
+ val |= TSI148_LCSR_DSAT_DBW_16;
+ break;
+ case VME_D32:
+ val |= TSI148_LCSR_DSAT_DBW_32;
+ break;
+ default:
+ dev_err(dev, "Invalid data width\n");
+ return -EINVAL;
+ }
+
+ /* Setup address space */
+ switch (aspace) {
+ case VME_A16:
+ val |= TSI148_LCSR_DSAT_AMODE_A16;
+ break;
+ case VME_A24:
+ val |= TSI148_LCSR_DSAT_AMODE_A24;
+ break;
+ case VME_A32:
+ val |= TSI148_LCSR_DSAT_AMODE_A32;
+ break;
+ case VME_A64:
+ val |= TSI148_LCSR_DSAT_AMODE_A64;
+ break;
+ case VME_CRCSR:
+ val |= TSI148_LCSR_DSAT_AMODE_CRCSR;
+ break;
+ case VME_USER1:
+ val |= TSI148_LCSR_DSAT_AMODE_USER1;
+ break;
+ case VME_USER2:
+ val |= TSI148_LCSR_DSAT_AMODE_USER2;
+ break;
+ case VME_USER3:
+ val |= TSI148_LCSR_DSAT_AMODE_USER3;
+ break;
+ case VME_USER4:
+ val |= TSI148_LCSR_DSAT_AMODE_USER4;
+ break;
+ default:
+ dev_err(dev, "Invalid address space\n");
+ return -EINVAL;
+ }
+
+ if (cycle & VME_SUPER)
+ val |= TSI148_LCSR_DSAT_SUP;
+ if (cycle & VME_PROG)
+ val |= TSI148_LCSR_DSAT_PGM;
+
+ *attr = cpu_to_be32(val);
+
+ return 0;
+}
+
+static int tsi148_dma_set_vme_dest_attributes(struct device *dev, __be32 *attr,
+ u32 aspace, u32 cycle, u32 dwidth)
+{
+ u32 val;
+
+ val = be32_to_cpu(*attr);
+
+ /* Setup 2eSST speeds */
+ switch (cycle & (VME_2eSST160 | VME_2eSST267 | VME_2eSST320)) {
+ case VME_2eSST160:
+ val |= TSI148_LCSR_DDAT_2eSSTM_160;
+ break;
+ case VME_2eSST267:
+ val |= TSI148_LCSR_DDAT_2eSSTM_267;
+ break;
+ case VME_2eSST320:
+ val |= TSI148_LCSR_DDAT_2eSSTM_320;
+ break;
+ }
+
+ /* Setup cycle types */
+ if (cycle & VME_SCT)
+ val |= TSI148_LCSR_DDAT_TM_SCT;
+
+ if (cycle & VME_BLT)
+ val |= TSI148_LCSR_DDAT_TM_BLT;
+
+ if (cycle & VME_MBLT)
+ val |= TSI148_LCSR_DDAT_TM_MBLT;
+
+ if (cycle & VME_2eVME)
+ val |= TSI148_LCSR_DDAT_TM_2eVME;
+
+ if (cycle & VME_2eSST)
+ val |= TSI148_LCSR_DDAT_TM_2eSST;
+
+ if (cycle & VME_2eSSTB) {
+ dev_err(dev, "Currently not setting Broadcast Select "
+ "Registers\n");
+ val |= TSI148_LCSR_DDAT_TM_2eSSTB;
+ }
+
+ /* Setup data width */
+ switch (dwidth) {
+ case VME_D16:
+ val |= TSI148_LCSR_DDAT_DBW_16;
+ break;
+ case VME_D32:
+ val |= TSI148_LCSR_DDAT_DBW_32;
+ break;
+ default:
+ dev_err(dev, "Invalid data width\n");
+ return -EINVAL;
+ }
+
+ /* Setup address space */
+ switch (aspace) {
+ case VME_A16:
+ val |= TSI148_LCSR_DDAT_AMODE_A16;
+ break;
+ case VME_A24:
+ val |= TSI148_LCSR_DDAT_AMODE_A24;
+ break;
+ case VME_A32:
+ val |= TSI148_LCSR_DDAT_AMODE_A32;
+ break;
+ case VME_A64:
+ val |= TSI148_LCSR_DDAT_AMODE_A64;
+ break;
+ case VME_CRCSR:
+ val |= TSI148_LCSR_DDAT_AMODE_CRCSR;
+ break;
+ case VME_USER1:
+ val |= TSI148_LCSR_DDAT_AMODE_USER1;
+ break;
+ case VME_USER2:
+ val |= TSI148_LCSR_DDAT_AMODE_USER2;
+ break;
+ case VME_USER3:
+ val |= TSI148_LCSR_DDAT_AMODE_USER3;
+ break;
+ case VME_USER4:
+ val |= TSI148_LCSR_DDAT_AMODE_USER4;
+ break;
+ default:
+ dev_err(dev, "Invalid address space\n");
+ return -EINVAL;
+ }
+
+ if (cycle & VME_SUPER)
+ val |= TSI148_LCSR_DDAT_SUP;
+ if (cycle & VME_PROG)
+ val |= TSI148_LCSR_DDAT_PGM;
+
+ *attr = cpu_to_be32(val);
+
+ return 0;
+}
+
+/*
+ * Add a link list descriptor to the list
+ *
+ * Note: DMA engine expects the DMA descriptor to be big endian.
+ */
+static int tsi148_dma_list_add(struct vme_dma_list *list,
+ struct vme_dma_attr *src, struct vme_dma_attr *dest, size_t count)
+{
+ struct tsi148_dma_entry *entry, *prev;
+ u32 address_high, address_low, val;
+ struct vme_dma_pattern *pattern_attr;
+ struct vme_dma_pci *pci_attr;
+ struct vme_dma_vme *vme_attr;
+ int retval = 0;
+ struct vme_bridge *tsi148_bridge;
+
+ tsi148_bridge = list->parent->parent;
+
+ /* Descriptor must be aligned on 64-bit boundaries */
+ entry = kmalloc(sizeof(*entry), GFP_KERNEL);
+ if (!entry) {
+ retval = -ENOMEM;
+ goto err_mem;
+ }
+
+ /* Test descriptor alignment */
+ if ((unsigned long)&entry->descriptor & 0x7) {
+ dev_err(tsi148_bridge->parent, "Descriptor not aligned to 8 "
+ "byte boundary as required: %p\n",
+ &entry->descriptor);
+ retval = -EINVAL;
+ goto err_align;
+ }
+
+ /* Given we are going to fill out the structure, we probably don't
+ * need to zero it, but better safe than sorry for now.
+ */
+ memset(&entry->descriptor, 0, sizeof(entry->descriptor));
+
+ /* Fill out source part */
+ switch (src->type) {
+ case VME_DMA_PATTERN:
+ pattern_attr = src->private;
+
+ entry->descriptor.dsal = cpu_to_be32(pattern_attr->pattern);
+
+ val = TSI148_LCSR_DSAT_TYP_PAT;
+
+ /* Default behaviour is 32 bit pattern */
+ if (pattern_attr->type & VME_DMA_PATTERN_BYTE)
+ val |= TSI148_LCSR_DSAT_PSZ;
+
+ /* It seems that the default behaviour is to increment */
+ if ((pattern_attr->type & VME_DMA_PATTERN_INCREMENT) == 0)
+ val |= TSI148_LCSR_DSAT_NIN;
+ entry->descriptor.dsat = cpu_to_be32(val);
+ break;
+ case VME_DMA_PCI:
+ pci_attr = src->private;
+
+ reg_split((unsigned long long)pci_attr->address, &address_high,
+ &address_low);
+ entry->descriptor.dsau = cpu_to_be32(address_high);
+ entry->descriptor.dsal = cpu_to_be32(address_low);
+ entry->descriptor.dsat = cpu_to_be32(TSI148_LCSR_DSAT_TYP_PCI);
+ break;
+ case VME_DMA_VME:
+ vme_attr = src->private;
+
+ reg_split((unsigned long long)vme_attr->address, &address_high,
+ &address_low);
+ entry->descriptor.dsau = cpu_to_be32(address_high);
+ entry->descriptor.dsal = cpu_to_be32(address_low);
+ entry->descriptor.dsat = cpu_to_be32(TSI148_LCSR_DSAT_TYP_VME);
+
+ retval = tsi148_dma_set_vme_src_attributes(
+ tsi148_bridge->parent, &entry->descriptor.dsat,
+ vme_attr->aspace, vme_attr->cycle, vme_attr->dwidth);
+ if (retval < 0)
+ goto err_source;
+ break;
+ default:
+ dev_err(tsi148_bridge->parent, "Invalid source type\n");
+ retval = -EINVAL;
+ goto err_source;
+ }
+
+ /* Assume last link - this will be over-written by adding another */
+ entry->descriptor.dnlau = cpu_to_be32(0);
+ entry->descriptor.dnlal = cpu_to_be32(TSI148_LCSR_DNLAL_LLA);
+
+ /* Fill out destination part */
+ switch (dest->type) {
+ case VME_DMA_PCI:
+ pci_attr = dest->private;
+
+ reg_split((unsigned long long)pci_attr->address, &address_high,
+ &address_low);
+ entry->descriptor.ddau = cpu_to_be32(address_high);
+ entry->descriptor.ddal = cpu_to_be32(address_low);
+ entry->descriptor.ddat = cpu_to_be32(TSI148_LCSR_DDAT_TYP_PCI);
+ break;
+ case VME_DMA_VME:
+ vme_attr = dest->private;
+
+ reg_split((unsigned long long)vme_attr->address, &address_high,
+ &address_low);
+ entry->descriptor.ddau = cpu_to_be32(address_high);
+ entry->descriptor.ddal = cpu_to_be32(address_low);
+ entry->descriptor.ddat = cpu_to_be32(TSI148_LCSR_DDAT_TYP_VME);
+
+ retval = tsi148_dma_set_vme_dest_attributes(
+ tsi148_bridge->parent, &entry->descriptor.ddat,
+ vme_attr->aspace, vme_attr->cycle, vme_attr->dwidth);
+ if (retval < 0)
+ goto err_dest;
+ break;
+ default:
+ dev_err(tsi148_bridge->parent, "Invalid destination type\n");
+ retval = -EINVAL;
+ goto err_dest;
+ }
+
+ /* Fill out count */
+ entry->descriptor.dcnt = cpu_to_be32((u32)count);
+
+ /* Add to list */
+ list_add_tail(&entry->list, &list->entries);
+
+ entry->dma_handle = dma_map_single(tsi148_bridge->parent,
+ &entry->descriptor,
+ sizeof(entry->descriptor),
+ DMA_TO_DEVICE);
+ if (dma_mapping_error(tsi148_bridge->parent, entry->dma_handle)) {
+ dev_err(tsi148_bridge->parent, "DMA mapping error\n");
+ retval = -EINVAL;
+ goto err_dma;
+ }
+
+ /* Fill out previous descriptors "Next Address" */
+ if (entry->list.prev != &list->entries) {
+ reg_split((unsigned long long)entry->dma_handle, &address_high,
+ &address_low);
+ prev = list_entry(entry->list.prev, struct tsi148_dma_entry,
+ list);
+ prev->descriptor.dnlau = cpu_to_be32(address_high);
+ prev->descriptor.dnlal = cpu_to_be32(address_low);
+
+ }
+
+ return 0;
+
+err_dma:
+err_dest:
+err_source:
+err_align:
+ kfree(entry);
+err_mem:
+ return retval;
+}
+
+/*
+ * Check to see if the provided DMA channel is busy.
+ */
+static int tsi148_dma_busy(struct vme_bridge *tsi148_bridge, int channel)
+{
+ u32 tmp;
+ struct tsi148_driver *bridge;
+
+ bridge = tsi148_bridge->driver_priv;
+
+ tmp = ioread32be(bridge->base + TSI148_LCSR_DMA[channel] +
+ TSI148_LCSR_OFFSET_DSTA);
+
+ if (tmp & TSI148_LCSR_DSTA_BSY)
+ return 0;
+ else
+ return 1;
+
+}
+
+/*
+ * Execute a previously generated link list
+ *
+ * XXX Need to provide control register configuration.
+ */
+static int tsi148_dma_list_exec(struct vme_dma_list *list)
+{
+ struct vme_dma_resource *ctrlr;
+ int channel, retval;
+ struct tsi148_dma_entry *entry;
+ u32 bus_addr_high, bus_addr_low;
+ u32 val, dctlreg = 0;
+ struct vme_bridge *tsi148_bridge;
+ struct tsi148_driver *bridge;
+
+ ctrlr = list->parent;
+
+ tsi148_bridge = ctrlr->parent;
+
+ bridge = tsi148_bridge->driver_priv;
+
+ mutex_lock(&ctrlr->mtx);
+
+ channel = ctrlr->number;
+
+ if (!list_empty(&ctrlr->running)) {
+ /*
+ * XXX We have an active DMA transfer and currently haven't
+ * sorted out the mechanism for "pending" DMA transfers.
+ * Return busy.
+ */
+ /* Need to add to pending here */
+ mutex_unlock(&ctrlr->mtx);
+ return -EBUSY;
+ } else {
+ list_add(&list->list, &ctrlr->running);
+ }
+
+ /* Get first bus address and write into registers */
+ entry = list_first_entry(&list->entries, struct tsi148_dma_entry,
+ list);
+
+ mutex_unlock(&ctrlr->mtx);
+
+ reg_split(entry->dma_handle, &bus_addr_high, &bus_addr_low);
+
+ iowrite32be(bus_addr_high, bridge->base +
+ TSI148_LCSR_DMA[channel] + TSI148_LCSR_OFFSET_DNLAU);
+ iowrite32be(bus_addr_low, bridge->base +
+ TSI148_LCSR_DMA[channel] + TSI148_LCSR_OFFSET_DNLAL);
+
+ dctlreg = ioread32be(bridge->base + TSI148_LCSR_DMA[channel] +
+ TSI148_LCSR_OFFSET_DCTL);
+
+ /* Start the operation */
+ iowrite32be(dctlreg | TSI148_LCSR_DCTL_DGO, bridge->base +
+ TSI148_LCSR_DMA[channel] + TSI148_LCSR_OFFSET_DCTL);
+
+ retval = wait_event_interruptible(bridge->dma_queue[channel],
+ tsi148_dma_busy(ctrlr->parent, channel));
+
+ if (retval) {
+ iowrite32be(dctlreg | TSI148_LCSR_DCTL_ABT, bridge->base +
+ TSI148_LCSR_DMA[channel] + TSI148_LCSR_OFFSET_DCTL);
+ /* Wait for the operation to abort */
+ wait_event(bridge->dma_queue[channel],
+ tsi148_dma_busy(ctrlr->parent, channel));
+ retval = -EINTR;
+ goto exit;
+ }
+
+ /*
+ * Read status register, this register is valid until we kick off a
+ * new transfer.
+ */
+ val = ioread32be(bridge->base + TSI148_LCSR_DMA[channel] +
+ TSI148_LCSR_OFFSET_DSTA);
+
+ if (val & TSI148_LCSR_DSTA_VBE) {
+ dev_err(tsi148_bridge->parent, "DMA Error. DSTA=%08X\n", val);
+ retval = -EIO;
+ }
+
+exit:
+ /* Remove list from running list */
+ mutex_lock(&ctrlr->mtx);
+ list_del(&list->list);
+ mutex_unlock(&ctrlr->mtx);
+
+ return retval;
+}
+
+/*
+ * Clean up a previously generated link list
+ *
+ * We have a separate function, don't assume that the chain can't be reused.
+ */
+static int tsi148_dma_list_empty(struct vme_dma_list *list)
+{
+ struct list_head *pos, *temp;
+ struct tsi148_dma_entry *entry;
+
+ struct vme_bridge *tsi148_bridge = list->parent->parent;
+
+ /* detach and free each entry */
+ list_for_each_safe(pos, temp, &list->entries) {
+ list_del(pos);
+ entry = list_entry(pos, struct tsi148_dma_entry, list);
+
+ dma_unmap_single(tsi148_bridge->parent, entry->dma_handle,
+ sizeof(struct tsi148_dma_descriptor), DMA_TO_DEVICE);
+ kfree(entry);
+ }
+
+ return 0;
+}
+
+/*
+ * All 4 location monitors reside at the same base - this is therefore a
+ * system wide configuration.
+ *
+ * This does not enable the LM monitor - that should be done when the first
+ * callback is attached and disabled when the last callback is removed.
+ */
+static int tsi148_lm_set(struct vme_lm_resource *lm, unsigned long long lm_base,
+ u32 aspace, u32 cycle)
+{
+ u32 lm_base_high, lm_base_low, lm_ctl = 0;
+ int i;
+ struct vme_bridge *tsi148_bridge;
+ struct tsi148_driver *bridge;
+
+ tsi148_bridge = lm->parent;
+
+ bridge = tsi148_bridge->driver_priv;
+
+ mutex_lock(&lm->mtx);
+
+ /* If we already have a callback attached, we can't move it! */
+ for (i = 0; i < lm->monitors; i++) {
+ if (bridge->lm_callback[i]) {
+ mutex_unlock(&lm->mtx);
+ dev_err(tsi148_bridge->parent, "Location monitor "
+ "callback attached, can't reset\n");
+ return -EBUSY;
+ }
+ }
+
+ switch (aspace) {
+ case VME_A16:
+ lm_ctl |= TSI148_LCSR_LMAT_AS_A16;
+ break;
+ case VME_A24:
+ lm_ctl |= TSI148_LCSR_LMAT_AS_A24;
+ break;
+ case VME_A32:
+ lm_ctl |= TSI148_LCSR_LMAT_AS_A32;
+ break;
+ case VME_A64:
+ lm_ctl |= TSI148_LCSR_LMAT_AS_A64;
+ break;
+ default:
+ mutex_unlock(&lm->mtx);
+ dev_err(tsi148_bridge->parent, "Invalid address space\n");
+ return -EINVAL;
+ }
+
+ if (cycle & VME_SUPER)
+ lm_ctl |= TSI148_LCSR_LMAT_SUPR ;
+ if (cycle & VME_USER)
+ lm_ctl |= TSI148_LCSR_LMAT_NPRIV;
+ if (cycle & VME_PROG)
+ lm_ctl |= TSI148_LCSR_LMAT_PGM;
+ if (cycle & VME_DATA)
+ lm_ctl |= TSI148_LCSR_LMAT_DATA;
+
+ reg_split(lm_base, &lm_base_high, &lm_base_low);
+
+ iowrite32be(lm_base_high, bridge->base + TSI148_LCSR_LMBAU);
+ iowrite32be(lm_base_low, bridge->base + TSI148_LCSR_LMBAL);
+ iowrite32be(lm_ctl, bridge->base + TSI148_LCSR_LMAT);
+
+ mutex_unlock(&lm->mtx);
+
+ return 0;
+}
+
+/* Get configuration of the callback monitor and return whether it is enabled
+ * or disabled.
+ */
+static int tsi148_lm_get(struct vme_lm_resource *lm,
+ unsigned long long *lm_base, u32 *aspace, u32 *cycle)
+{
+ u32 lm_base_high, lm_base_low, lm_ctl, enabled = 0;
+ struct tsi148_driver *bridge;
+
+ bridge = lm->parent->driver_priv;
+
+ mutex_lock(&lm->mtx);
+
+ lm_base_high = ioread32be(bridge->base + TSI148_LCSR_LMBAU);
+ lm_base_low = ioread32be(bridge->base + TSI148_LCSR_LMBAL);
+ lm_ctl = ioread32be(bridge->base + TSI148_LCSR_LMAT);
+
+ reg_join(lm_base_high, lm_base_low, lm_base);
+
+ if (lm_ctl & TSI148_LCSR_LMAT_EN)
+ enabled = 1;
+
+ if ((lm_ctl & TSI148_LCSR_LMAT_AS_M) == TSI148_LCSR_LMAT_AS_A16)
+ *aspace |= VME_A16;
+
+ if ((lm_ctl & TSI148_LCSR_LMAT_AS_M) == TSI148_LCSR_LMAT_AS_A24)
+ *aspace |= VME_A24;
+
+ if ((lm_ctl & TSI148_LCSR_LMAT_AS_M) == TSI148_LCSR_LMAT_AS_A32)
+ *aspace |= VME_A32;
+
+ if ((lm_ctl & TSI148_LCSR_LMAT_AS_M) == TSI148_LCSR_LMAT_AS_A64)
+ *aspace |= VME_A64;
+
+
+ if (lm_ctl & TSI148_LCSR_LMAT_SUPR)
+ *cycle |= VME_SUPER;
+ if (lm_ctl & TSI148_LCSR_LMAT_NPRIV)
+ *cycle |= VME_USER;
+ if (lm_ctl & TSI148_LCSR_LMAT_PGM)
+ *cycle |= VME_PROG;
+ if (lm_ctl & TSI148_LCSR_LMAT_DATA)
+ *cycle |= VME_DATA;
+
+ mutex_unlock(&lm->mtx);
+
+ return enabled;
+}
+
+/*
+ * Attach a callback to a specific location monitor.
+ *
+ * Callback will be passed the monitor triggered.
+ */
+static int tsi148_lm_attach(struct vme_lm_resource *lm, int monitor,
+ void (*callback)(void *), void *data)
+{
+ u32 lm_ctl, tmp;
+ struct vme_bridge *tsi148_bridge;
+ struct tsi148_driver *bridge;
+
+ tsi148_bridge = lm->parent;
+
+ bridge = tsi148_bridge->driver_priv;
+
+ mutex_lock(&lm->mtx);
+
+ /* Ensure that the location monitor is configured - need PGM or DATA */
+ lm_ctl = ioread32be(bridge->base + TSI148_LCSR_LMAT);
+ if ((lm_ctl & (TSI148_LCSR_LMAT_PGM | TSI148_LCSR_LMAT_DATA)) == 0) {
+ mutex_unlock(&lm->mtx);
+ dev_err(tsi148_bridge->parent, "Location monitor not properly "
+ "configured\n");
+ return -EINVAL;
+ }
+
+ /* Check that a callback isn't already attached */
+ if (bridge->lm_callback[monitor]) {
+ mutex_unlock(&lm->mtx);
+ dev_err(tsi148_bridge->parent, "Existing callback attached\n");
+ return -EBUSY;
+ }
+
+ /* Attach callback */
+ bridge->lm_callback[monitor] = callback;
+ bridge->lm_data[monitor] = data;
+
+ /* Enable Location Monitor interrupt */
+ tmp = ioread32be(bridge->base + TSI148_LCSR_INTEN);
+ tmp |= TSI148_LCSR_INTEN_LMEN[monitor];
+ iowrite32be(tmp, bridge->base + TSI148_LCSR_INTEN);
+
+ tmp = ioread32be(bridge->base + TSI148_LCSR_INTEO);
+ tmp |= TSI148_LCSR_INTEO_LMEO[monitor];
+ iowrite32be(tmp, bridge->base + TSI148_LCSR_INTEO);
+
+ /* Ensure that global Location Monitor Enable set */
+ if ((lm_ctl & TSI148_LCSR_LMAT_EN) == 0) {
+ lm_ctl |= TSI148_LCSR_LMAT_EN;
+ iowrite32be(lm_ctl, bridge->base + TSI148_LCSR_LMAT);
+ }
+
+ mutex_unlock(&lm->mtx);
+
+ return 0;
+}
+
+/*
+ * Detach a callback function forn a specific location monitor.
+ */
+static int tsi148_lm_detach(struct vme_lm_resource *lm, int monitor)
+{
+ u32 lm_en, tmp;
+ struct tsi148_driver *bridge;
+
+ bridge = lm->parent->driver_priv;
+
+ mutex_lock(&lm->mtx);
+
+ /* Disable Location Monitor and ensure previous interrupts are clear */
+ lm_en = ioread32be(bridge->base + TSI148_LCSR_INTEN);
+ lm_en &= ~TSI148_LCSR_INTEN_LMEN[monitor];
+ iowrite32be(lm_en, bridge->base + TSI148_LCSR_INTEN);
+
+ tmp = ioread32be(bridge->base + TSI148_LCSR_INTEO);
+ tmp &= ~TSI148_LCSR_INTEO_LMEO[monitor];
+ iowrite32be(tmp, bridge->base + TSI148_LCSR_INTEO);
+
+ iowrite32be(TSI148_LCSR_INTC_LMC[monitor],
+ bridge->base + TSI148_LCSR_INTC);
+
+ /* Detach callback */
+ bridge->lm_callback[monitor] = NULL;
+ bridge->lm_data[monitor] = NULL;
+
+ /* If all location monitors disabled, disable global Location Monitor */
+ if ((lm_en & (TSI148_LCSR_INTS_LM0S | TSI148_LCSR_INTS_LM1S |
+ TSI148_LCSR_INTS_LM2S | TSI148_LCSR_INTS_LM3S)) == 0) {
+ tmp = ioread32be(bridge->base + TSI148_LCSR_LMAT);
+ tmp &= ~TSI148_LCSR_LMAT_EN;
+ iowrite32be(tmp, bridge->base + TSI148_LCSR_LMAT);
+ }
+
+ mutex_unlock(&lm->mtx);
+
+ return 0;
+}
+
+/*
+ * Determine Geographical Addressing
+ */
+static int tsi148_slot_get(struct vme_bridge *tsi148_bridge)
+{
+ u32 slot = 0;
+ struct tsi148_driver *bridge;
+
+ bridge = tsi148_bridge->driver_priv;
+
+ if (!geoid) {
+ slot = ioread32be(bridge->base + TSI148_LCSR_VSTAT);
+ slot = slot & TSI148_LCSR_VSTAT_GA_M;
+ } else
+ slot = geoid;
+
+ return (int)slot;
+}
+
+static void *tsi148_alloc_consistent(struct device *parent, size_t size,
+ dma_addr_t *dma)
+{
+ struct pci_dev *pdev;
+
+ /* Find pci_dev container of dev */
+ pdev = to_pci_dev(parent);
+
+ return dma_alloc_coherent(&pdev->dev, size, dma, GFP_KERNEL);
+}
+
+static void tsi148_free_consistent(struct device *parent, size_t size,
+ void *vaddr, dma_addr_t dma)
+{
+ struct pci_dev *pdev;
+
+ /* Find pci_dev container of dev */
+ pdev = to_pci_dev(parent);
+
+ dma_free_coherent(&pdev->dev, size, vaddr, dma);
+}
+
+/*
+ * Configure CR/CSR space
+ *
+ * Access to the CR/CSR can be configured at power-up. The location of the
+ * CR/CSR registers in the CR/CSR address space is determined by the boards
+ * Auto-ID or Geographic address. This function ensures that the window is
+ * enabled at an offset consistent with the boards geopgraphic address.
+ *
+ * Each board has a 512kB window, with the highest 4kB being used for the
+ * boards registers, this means there is a fix length 508kB window which must
+ * be mapped onto PCI memory.
+ */
+static int tsi148_crcsr_init(struct vme_bridge *tsi148_bridge,
+ struct pci_dev *pdev)
+{
+ u32 cbar, crat, vstat;
+ u32 crcsr_bus_high, crcsr_bus_low;
+ int retval;
+ struct tsi148_driver *bridge;
+
+ bridge = tsi148_bridge->driver_priv;
+
+ /* Allocate mem for CR/CSR image */
+ bridge->crcsr_kernel = dma_alloc_coherent(&pdev->dev,
+ VME_CRCSR_BUF_SIZE,
+ &bridge->crcsr_bus, GFP_KERNEL);
+ if (!bridge->crcsr_kernel) {
+ dev_err(tsi148_bridge->parent, "Failed to allocate memory for "
+ "CR/CSR image\n");
+ return -ENOMEM;
+ }
+
+ reg_split(bridge->crcsr_bus, &crcsr_bus_high, &crcsr_bus_low);
+
+ iowrite32be(crcsr_bus_high, bridge->base + TSI148_LCSR_CROU);
+ iowrite32be(crcsr_bus_low, bridge->base + TSI148_LCSR_CROL);
+
+ /* Ensure that the CR/CSR is configured at the correct offset */
+ cbar = ioread32be(bridge->base + TSI148_CBAR);
+ cbar = (cbar & TSI148_CRCSR_CBAR_M)>>3;
+
+ vstat = tsi148_slot_get(tsi148_bridge);
+
+ if (cbar != vstat) {
+ cbar = vstat;
+ dev_info(tsi148_bridge->parent, "Setting CR/CSR offset\n");
+ iowrite32be(cbar<<3, bridge->base + TSI148_CBAR);
+ }
+ dev_info(tsi148_bridge->parent, "CR/CSR Offset: %d\n", cbar);
+
+ crat = ioread32be(bridge->base + TSI148_LCSR_CRAT);
+ if (crat & TSI148_LCSR_CRAT_EN)
+ dev_info(tsi148_bridge->parent, "CR/CSR already enabled\n");
+ else {
+ dev_info(tsi148_bridge->parent, "Enabling CR/CSR space\n");
+ iowrite32be(crat | TSI148_LCSR_CRAT_EN,
+ bridge->base + TSI148_LCSR_CRAT);
+ }
+
+ /* If we want flushed, error-checked writes, set up a window
+ * over the CR/CSR registers. We read from here to safely flush
+ * through VME writes.
+ */
+ if (err_chk) {
+ retval = tsi148_master_set(bridge->flush_image, 1,
+ (vstat * 0x80000), 0x80000, VME_CRCSR, VME_SCT,
+ VME_D16);
+ if (retval)
+ dev_err(tsi148_bridge->parent, "Configuring flush image"
+ " failed\n");
+ }
+
+ return 0;
+
+}
+
+static void tsi148_crcsr_exit(struct vme_bridge *tsi148_bridge,
+ struct pci_dev *pdev)
+{
+ u32 crat;
+ struct tsi148_driver *bridge;
+
+ bridge = tsi148_bridge->driver_priv;
+
+ /* Turn off CR/CSR space */
+ crat = ioread32be(bridge->base + TSI148_LCSR_CRAT);
+ iowrite32be(crat & ~TSI148_LCSR_CRAT_EN,
+ bridge->base + TSI148_LCSR_CRAT);
+
+ /* Free image */
+ iowrite32be(0, bridge->base + TSI148_LCSR_CROU);
+ iowrite32be(0, bridge->base + TSI148_LCSR_CROL);
+
+ dma_free_coherent(&pdev->dev, VME_CRCSR_BUF_SIZE,
+ bridge->crcsr_kernel, bridge->crcsr_bus);
+}
+
+static int tsi148_probe(struct pci_dev *pdev, const struct pci_device_id *id)
+{
+ int retval, i, master_num;
+ u32 data;
+ struct list_head *pos = NULL, *n;
+ struct vme_bridge *tsi148_bridge;
+ struct tsi148_driver *tsi148_device;
+ struct vme_master_resource *master_image;
+ struct vme_slave_resource *slave_image;
+ struct vme_dma_resource *dma_ctrlr;
+ struct vme_lm_resource *lm;
+
+ /* If we want to support more than one of each bridge, we need to
+ * dynamically generate this so we get one per device
+ */
+ tsi148_bridge = kzalloc(sizeof(*tsi148_bridge), GFP_KERNEL);
+ if (!tsi148_bridge) {
+ retval = -ENOMEM;
+ goto err_struct;
+ }
+ vme_init_bridge(tsi148_bridge);
+
+ tsi148_device = kzalloc(sizeof(*tsi148_device), GFP_KERNEL);
+ if (!tsi148_device) {
+ retval = -ENOMEM;
+ goto err_driver;
+ }
+
+ tsi148_bridge->driver_priv = tsi148_device;
+
+ /* Enable the device */
+ retval = pci_enable_device(pdev);
+ if (retval) {
+ dev_err(&pdev->dev, "Unable to enable device\n");
+ goto err_enable;
+ }
+
+ /* Map Registers */
+ retval = pci_request_regions(pdev, driver_name);
+ if (retval) {
+ dev_err(&pdev->dev, "Unable to reserve resources\n");
+ goto err_resource;
+ }
+
+ /* map registers in BAR 0 */
+ tsi148_device->base = ioremap(pci_resource_start(pdev, 0),
+ 4096);
+ if (!tsi148_device->base) {
+ dev_err(&pdev->dev, "Unable to remap CRG region\n");
+ retval = -EIO;
+ goto err_remap;
+ }
+
+ /* Check to see if the mapping worked out */
+ data = ioread32(tsi148_device->base + TSI148_PCFS_ID) & 0x0000FFFF;
+ if (data != PCI_VENDOR_ID_TUNDRA) {
+ dev_err(&pdev->dev, "CRG region check failed\n");
+ retval = -EIO;
+ goto err_test;
+ }
+
+ /* Initialize wait queues & mutual exclusion flags */
+ init_waitqueue_head(&tsi148_device->dma_queue[0]);
+ init_waitqueue_head(&tsi148_device->dma_queue[1]);
+ init_waitqueue_head(&tsi148_device->iack_queue);
+ mutex_init(&tsi148_device->vme_int);
+ mutex_init(&tsi148_device->vme_rmw);
+
+ tsi148_bridge->parent = &pdev->dev;
+ strcpy(tsi148_bridge->name, driver_name);
+
+ /* Setup IRQ */
+ retval = tsi148_irq_init(tsi148_bridge);
+ if (retval != 0) {
+ dev_err(&pdev->dev, "Chip Initialization failed.\n");
+ goto err_irq;
+ }
+
+ /* If we are going to flush writes, we need to read from the VME bus.
+ * We need to do this safely, thus we read the devices own CR/CSR
+ * register. To do this we must set up a window in CR/CSR space and
+ * hence have one less master window resource available.
+ */
+ master_num = TSI148_MAX_MASTER;
+ if (err_chk) {
+ master_num--;
+
+ tsi148_device->flush_image =
+ kmalloc(sizeof(*tsi148_device->flush_image),
+ GFP_KERNEL);
+ if (!tsi148_device->flush_image) {
+ retval = -ENOMEM;
+ goto err_master;
+ }
+ tsi148_device->flush_image->parent = tsi148_bridge;
+ spin_lock_init(&tsi148_device->flush_image->lock);
+ tsi148_device->flush_image->locked = 1;
+ tsi148_device->flush_image->number = master_num;
+ memset(&tsi148_device->flush_image->bus_resource, 0,
+ sizeof(tsi148_device->flush_image->bus_resource));
+ tsi148_device->flush_image->kern_base = NULL;
+ }
+
+ /* Add master windows to list */
+ for (i = 0; i < master_num; i++) {
+ master_image = kmalloc(sizeof(*master_image), GFP_KERNEL);
+ if (!master_image) {
+ retval = -ENOMEM;
+ goto err_master;
+ }
+ master_image->parent = tsi148_bridge;
+ spin_lock_init(&master_image->lock);
+ master_image->locked = 0;
+ master_image->number = i;
+ master_image->address_attr = VME_A16 | VME_A24 | VME_A32 |
+ VME_A64 | VME_CRCSR | VME_USER1 | VME_USER2 |
+ VME_USER3 | VME_USER4;
+ master_image->cycle_attr = VME_SCT | VME_BLT | VME_MBLT |
+ VME_2eVME | VME_2eSST | VME_2eSSTB | VME_2eSST160 |
+ VME_2eSST267 | VME_2eSST320 | VME_SUPER | VME_USER |
+ VME_PROG | VME_DATA;
+ master_image->width_attr = VME_D16 | VME_D32;
+ memset(&master_image->bus_resource, 0,
+ sizeof(master_image->bus_resource));
+ master_image->kern_base = NULL;
+ list_add_tail(&master_image->list,
+ &tsi148_bridge->master_resources);
+ }
+
+ /* Add slave windows to list */
+ for (i = 0; i < TSI148_MAX_SLAVE; i++) {
+ slave_image = kmalloc(sizeof(*slave_image), GFP_KERNEL);
+ if (!slave_image) {
+ retval = -ENOMEM;
+ goto err_slave;
+ }
+ slave_image->parent = tsi148_bridge;
+ mutex_init(&slave_image->mtx);
+ slave_image->locked = 0;
+ slave_image->number = i;
+ slave_image->address_attr = VME_A16 | VME_A24 | VME_A32 |
+ VME_A64;
+ slave_image->cycle_attr = VME_SCT | VME_BLT | VME_MBLT |
+ VME_2eVME | VME_2eSST | VME_2eSSTB | VME_2eSST160 |
+ VME_2eSST267 | VME_2eSST320 | VME_SUPER | VME_USER |
+ VME_PROG | VME_DATA;
+ list_add_tail(&slave_image->list,
+ &tsi148_bridge->slave_resources);
+ }
+
+ /* Add dma engines to list */
+ for (i = 0; i < TSI148_MAX_DMA; i++) {
+ dma_ctrlr = kmalloc(sizeof(*dma_ctrlr), GFP_KERNEL);
+ if (!dma_ctrlr) {
+ retval = -ENOMEM;
+ goto err_dma;
+ }
+ dma_ctrlr->parent = tsi148_bridge;
+ mutex_init(&dma_ctrlr->mtx);
+ dma_ctrlr->locked = 0;
+ dma_ctrlr->number = i;
+ dma_ctrlr->route_attr = VME_DMA_VME_TO_MEM |
+ VME_DMA_MEM_TO_VME | VME_DMA_VME_TO_VME |
+ VME_DMA_MEM_TO_MEM | VME_DMA_PATTERN_TO_VME |
+ VME_DMA_PATTERN_TO_MEM;
+ INIT_LIST_HEAD(&dma_ctrlr->pending);
+ INIT_LIST_HEAD(&dma_ctrlr->running);
+ list_add_tail(&dma_ctrlr->list,
+ &tsi148_bridge->dma_resources);
+ }
+
+ /* Add location monitor to list */
+ lm = kmalloc(sizeof(*lm), GFP_KERNEL);
+ if (!lm) {
+ retval = -ENOMEM;
+ goto err_lm;
+ }
+ lm->parent = tsi148_bridge;
+ mutex_init(&lm->mtx);
+ lm->locked = 0;
+ lm->number = 1;
+ lm->monitors = 4;
+ list_add_tail(&lm->list, &tsi148_bridge->lm_resources);
+
+ tsi148_bridge->slave_get = tsi148_slave_get;
+ tsi148_bridge->slave_set = tsi148_slave_set;
+ tsi148_bridge->master_get = tsi148_master_get;
+ tsi148_bridge->master_set = tsi148_master_set;
+ tsi148_bridge->master_read = tsi148_master_read;
+ tsi148_bridge->master_write = tsi148_master_write;
+ tsi148_bridge->master_rmw = tsi148_master_rmw;
+ tsi148_bridge->dma_list_add = tsi148_dma_list_add;
+ tsi148_bridge->dma_list_exec = tsi148_dma_list_exec;
+ tsi148_bridge->dma_list_empty = tsi148_dma_list_empty;
+ tsi148_bridge->irq_set = tsi148_irq_set;
+ tsi148_bridge->irq_generate = tsi148_irq_generate;
+ tsi148_bridge->lm_set = tsi148_lm_set;
+ tsi148_bridge->lm_get = tsi148_lm_get;
+ tsi148_bridge->lm_attach = tsi148_lm_attach;
+ tsi148_bridge->lm_detach = tsi148_lm_detach;
+ tsi148_bridge->slot_get = tsi148_slot_get;
+ tsi148_bridge->alloc_consistent = tsi148_alloc_consistent;
+ tsi148_bridge->free_consistent = tsi148_free_consistent;
+
+ data = ioread32be(tsi148_device->base + TSI148_LCSR_VSTAT);
+ dev_info(&pdev->dev, "Board is%s the VME system controller\n",
+ (data & TSI148_LCSR_VSTAT_SCONS) ? "" : " not");
+ if (!geoid)
+ dev_info(&pdev->dev, "VME geographical address is %d\n",
+ data & TSI148_LCSR_VSTAT_GA_M);
+ else
+ dev_info(&pdev->dev, "VME geographical address is set to %d\n",
+ geoid);
+
+ dev_info(&pdev->dev, "VME Write and flush and error check is %s\n",
+ err_chk ? "enabled" : "disabled");
+
+ retval = tsi148_crcsr_init(tsi148_bridge, pdev);
+ if (retval) {
+ dev_err(&pdev->dev, "CR/CSR configuration failed.\n");
+ goto err_crcsr;
+ }
+
+ retval = vme_register_bridge(tsi148_bridge);
+ if (retval != 0) {
+ dev_err(&pdev->dev, "Chip Registration failed.\n");
+ goto err_reg;
+ }
+
+ pci_set_drvdata(pdev, tsi148_bridge);
+
+ /* Clear VME bus "board fail", and "power-up reset" lines */
+ data = ioread32be(tsi148_device->base + TSI148_LCSR_VSTAT);
+ data &= ~TSI148_LCSR_VSTAT_BRDFL;
+ data |= TSI148_LCSR_VSTAT_CPURST;
+ iowrite32be(data, tsi148_device->base + TSI148_LCSR_VSTAT);
+
+ return 0;
+
+err_reg:
+ tsi148_crcsr_exit(tsi148_bridge, pdev);
+err_crcsr:
+err_lm:
+ /* resources are stored in link list */
+ list_for_each_safe(pos, n, &tsi148_bridge->lm_resources) {
+ lm = list_entry(pos, struct vme_lm_resource, list);
+ list_del(pos);
+ kfree(lm);
+ }
+err_dma:
+ /* resources are stored in link list */
+ list_for_each_safe(pos, n, &tsi148_bridge->dma_resources) {
+ dma_ctrlr = list_entry(pos, struct vme_dma_resource, list);
+ list_del(pos);
+ kfree(dma_ctrlr);
+ }
+err_slave:
+ /* resources are stored in link list */
+ list_for_each_safe(pos, n, &tsi148_bridge->slave_resources) {
+ slave_image = list_entry(pos, struct vme_slave_resource, list);
+ list_del(pos);
+ kfree(slave_image);
+ }
+err_master:
+ /* resources are stored in link list */
+ list_for_each_safe(pos, n, &tsi148_bridge->master_resources) {
+ master_image = list_entry(pos, struct vme_master_resource,
+ list);
+ list_del(pos);
+ kfree(master_image);
+ }
+
+ tsi148_irq_exit(tsi148_bridge, pdev);
+err_irq:
+err_test:
+ iounmap(tsi148_device->base);
+err_remap:
+ pci_release_regions(pdev);
+err_resource:
+ pci_disable_device(pdev);
+err_enable:
+ kfree(tsi148_device);
+err_driver:
+ kfree(tsi148_bridge);
+err_struct:
+ return retval;
+
+}
+
+static void tsi148_remove(struct pci_dev *pdev)
+{
+ struct list_head *pos = NULL;
+ struct list_head *tmplist;
+ struct vme_master_resource *master_image;
+ struct vme_slave_resource *slave_image;
+ struct vme_dma_resource *dma_ctrlr;
+ int i;
+ struct tsi148_driver *bridge;
+ struct vme_bridge *tsi148_bridge = pci_get_drvdata(pdev);
+
+ bridge = tsi148_bridge->driver_priv;
+
+
+ dev_dbg(&pdev->dev, "Driver is being unloaded.\n");
+
+ /*
+ * Shutdown all inbound and outbound windows.
+ */
+ for (i = 0; i < 8; i++) {
+ iowrite32be(0, bridge->base + TSI148_LCSR_IT[i] +
+ TSI148_LCSR_OFFSET_ITAT);
+ iowrite32be(0, bridge->base + TSI148_LCSR_OT[i] +
+ TSI148_LCSR_OFFSET_OTAT);
+ }
+
+ /*
+ * Shutdown Location monitor.
+ */
+ iowrite32be(0, bridge->base + TSI148_LCSR_LMAT);
+
+ /*
+ * Shutdown CRG map.
+ */
+ iowrite32be(0, bridge->base + TSI148_LCSR_CSRAT);
+
+ /*
+ * Clear error status.
+ */
+ iowrite32be(0xFFFFFFFF, bridge->base + TSI148_LCSR_EDPAT);
+ iowrite32be(0xFFFFFFFF, bridge->base + TSI148_LCSR_VEAT);
+ iowrite32be(0x07000700, bridge->base + TSI148_LCSR_PSTAT);
+
+ /*
+ * Remove VIRQ interrupt (if any)
+ */
+ if (ioread32be(bridge->base + TSI148_LCSR_VICR) & 0x800)
+ iowrite32be(0x8000, bridge->base + TSI148_LCSR_VICR);
+
+ /*
+ * Map all Interrupts to PCI INTA
+ */
+ iowrite32be(0x0, bridge->base + TSI148_LCSR_INTM1);
+ iowrite32be(0x0, bridge->base + TSI148_LCSR_INTM2);
+
+ tsi148_irq_exit(tsi148_bridge, pdev);
+
+ vme_unregister_bridge(tsi148_bridge);
+
+ tsi148_crcsr_exit(tsi148_bridge, pdev);
+
+ /* resources are stored in link list */
+ list_for_each_safe(pos, tmplist, &tsi148_bridge->dma_resources) {
+ dma_ctrlr = list_entry(pos, struct vme_dma_resource, list);
+ list_del(pos);
+ kfree(dma_ctrlr);
+ }
+
+ /* resources are stored in link list */
+ list_for_each_safe(pos, tmplist, &tsi148_bridge->slave_resources) {
+ slave_image = list_entry(pos, struct vme_slave_resource, list);
+ list_del(pos);
+ kfree(slave_image);
+ }
+
+ /* resources are stored in link list */
+ list_for_each_safe(pos, tmplist, &tsi148_bridge->master_resources) {
+ master_image = list_entry(pos, struct vme_master_resource,
+ list);
+ list_del(pos);
+ kfree(master_image);
+ }
+
+ iounmap(bridge->base);
+
+ pci_release_regions(pdev);
+
+ pci_disable_device(pdev);
+
+ kfree(tsi148_bridge->driver_priv);
+
+ kfree(tsi148_bridge);
+}
+
+module_pci_driver(tsi148_driver);
+
+MODULE_PARM_DESC(err_chk, "Check for VME errors on reads and writes");
+module_param(err_chk, bool, 0);
+
+MODULE_PARM_DESC(geoid, "Override geographical addressing");
+module_param(geoid, int, 0);
+
+MODULE_DESCRIPTION("VME driver for the Tundra Tempe VME bridge");
+MODULE_LICENSE("GPL");
diff --git a/drivers/staging/vme_user/vme_tsi148.h b/drivers/staging/vme_user/vme_tsi148.h
new file mode 100644
index 000000000000..226fedc6f167
--- /dev/null
+++ b/drivers/staging/vme_user/vme_tsi148.h
@@ -0,0 +1,1407 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * tsi148.h
+ *
+ * Support for the Tundra TSI148 VME Bridge chip
+ *
+ * Author: Tom Armistead
+ * Updated and maintained by Ajit Prem
+ * Copyright 2004 Motorola Inc.
+ */
+
+#ifndef TSI148_H
+#define TSI148_H
+
+#ifndef PCI_VENDOR_ID_TUNDRA
+#define PCI_VENDOR_ID_TUNDRA 0x10e3
+#endif
+
+#ifndef PCI_DEVICE_ID_TUNDRA_TSI148
+#define PCI_DEVICE_ID_TUNDRA_TSI148 0x148
+#endif
+
+/*
+ * Define the number of each that the Tsi148 supports.
+ */
+#define TSI148_MAX_MASTER 8 /* Max Master Windows */
+#define TSI148_MAX_SLAVE 8 /* Max Slave Windows */
+#define TSI148_MAX_DMA 2 /* Max DMA Controllers */
+#define TSI148_MAX_MAILBOX 4 /* Max Mail Box registers */
+#define TSI148_MAX_SEMAPHORE 8 /* Max Semaphores */
+
+/* Structure used to hold driver specific information */
+struct tsi148_driver {
+ void __iomem *base; /* Base Address of device registers */
+ wait_queue_head_t dma_queue[2];
+ wait_queue_head_t iack_queue;
+ void (*lm_callback[4])(void *); /* Called in interrupt handler */
+ void *lm_data[4];
+ void *crcsr_kernel;
+ dma_addr_t crcsr_bus;
+ struct vme_master_resource *flush_image;
+ struct mutex vme_rmw; /* Only one RMW cycle at a time */
+ struct mutex vme_int; /*
+ * Only one VME interrupt can be
+ * generated at a time, provide locking
+ */
+};
+
+/*
+ * Layout of a DMAC Linked-List Descriptor
+ *
+ * Note: This structure is accessed via the chip and therefore must be
+ * correctly laid out - It must also be aligned on 64-bit boundaries.
+ */
+struct tsi148_dma_descriptor {
+ __be32 dsau; /* Source Address */
+ __be32 dsal;
+ __be32 ddau; /* Destination Address */
+ __be32 ddal;
+ __be32 dsat; /* Source attributes */
+ __be32 ddat; /* Destination attributes */
+ __be32 dnlau; /* Next link address */
+ __be32 dnlal;
+ __be32 dcnt; /* Byte count */
+ __be32 ddbs; /* 2eSST Broadcast select */
+};
+
+struct tsi148_dma_entry {
+ /*
+ * The descriptor needs to be aligned on a 64-bit boundary, we increase
+ * the chance of this by putting it first in the structure.
+ */
+ struct tsi148_dma_descriptor descriptor;
+ struct list_head list;
+ dma_addr_t dma_handle;
+};
+
+/*
+ * TSI148 ASIC register structure overlays and bit field definitions.
+ *
+ * Note: Tsi148 Register Group (CRG) consists of the following
+ * combination of registers:
+ * PCFS - PCI Configuration Space Registers
+ * LCSR - Local Control and Status Registers
+ * GCSR - Global Control and Status Registers
+ * CR/CSR - Subset of Configuration ROM /
+ * Control and Status Registers
+ */
+
+
+/*
+ * Command/Status Registers (CRG + $004)
+ */
+#define TSI148_PCFS_ID 0x0
+#define TSI148_PCFS_CSR 0x4
+#define TSI148_PCFS_CLASS 0x8
+#define TSI148_PCFS_MISC0 0xC
+#define TSI148_PCFS_MBARL 0x10
+#define TSI148_PCFS_MBARU 0x14
+
+#define TSI148_PCFS_SUBID 0x28
+
+#define TSI148_PCFS_CAPP 0x34
+
+#define TSI148_PCFS_MISC1 0x3C
+
+#define TSI148_PCFS_XCAPP 0x40
+#define TSI148_PCFS_XSTAT 0x44
+
+/*
+ * LCSR definitions
+ */
+
+/*
+ * Outbound Translations
+ */
+#define TSI148_LCSR_OT0_OTSAU 0x100
+#define TSI148_LCSR_OT0_OTSAL 0x104
+#define TSI148_LCSR_OT0_OTEAU 0x108
+#define TSI148_LCSR_OT0_OTEAL 0x10C
+#define TSI148_LCSR_OT0_OTOFU 0x110
+#define TSI148_LCSR_OT0_OTOFL 0x114
+#define TSI148_LCSR_OT0_OTBS 0x118
+#define TSI148_LCSR_OT0_OTAT 0x11C
+
+#define TSI148_LCSR_OT1_OTSAU 0x120
+#define TSI148_LCSR_OT1_OTSAL 0x124
+#define TSI148_LCSR_OT1_OTEAU 0x128
+#define TSI148_LCSR_OT1_OTEAL 0x12C
+#define TSI148_LCSR_OT1_OTOFU 0x130
+#define TSI148_LCSR_OT1_OTOFL 0x134
+#define TSI148_LCSR_OT1_OTBS 0x138
+#define TSI148_LCSR_OT1_OTAT 0x13C
+
+#define TSI148_LCSR_OT2_OTSAU 0x140
+#define TSI148_LCSR_OT2_OTSAL 0x144
+#define TSI148_LCSR_OT2_OTEAU 0x148
+#define TSI148_LCSR_OT2_OTEAL 0x14C
+#define TSI148_LCSR_OT2_OTOFU 0x150
+#define TSI148_LCSR_OT2_OTOFL 0x154
+#define TSI148_LCSR_OT2_OTBS 0x158
+#define TSI148_LCSR_OT2_OTAT 0x15C
+
+#define TSI148_LCSR_OT3_OTSAU 0x160
+#define TSI148_LCSR_OT3_OTSAL 0x164
+#define TSI148_LCSR_OT3_OTEAU 0x168
+#define TSI148_LCSR_OT3_OTEAL 0x16C
+#define TSI148_LCSR_OT3_OTOFU 0x170
+#define TSI148_LCSR_OT3_OTOFL 0x174
+#define TSI148_LCSR_OT3_OTBS 0x178
+#define TSI148_LCSR_OT3_OTAT 0x17C
+
+#define TSI148_LCSR_OT4_OTSAU 0x180
+#define TSI148_LCSR_OT4_OTSAL 0x184
+#define TSI148_LCSR_OT4_OTEAU 0x188
+#define TSI148_LCSR_OT4_OTEAL 0x18C
+#define TSI148_LCSR_OT4_OTOFU 0x190
+#define TSI148_LCSR_OT4_OTOFL 0x194
+#define TSI148_LCSR_OT4_OTBS 0x198
+#define TSI148_LCSR_OT4_OTAT 0x19C
+
+#define TSI148_LCSR_OT5_OTSAU 0x1A0
+#define TSI148_LCSR_OT5_OTSAL 0x1A4
+#define TSI148_LCSR_OT5_OTEAU 0x1A8
+#define TSI148_LCSR_OT5_OTEAL 0x1AC
+#define TSI148_LCSR_OT5_OTOFU 0x1B0
+#define TSI148_LCSR_OT5_OTOFL 0x1B4
+#define TSI148_LCSR_OT5_OTBS 0x1B8
+#define TSI148_LCSR_OT5_OTAT 0x1BC
+
+#define TSI148_LCSR_OT6_OTSAU 0x1C0
+#define TSI148_LCSR_OT6_OTSAL 0x1C4
+#define TSI148_LCSR_OT6_OTEAU 0x1C8
+#define TSI148_LCSR_OT6_OTEAL 0x1CC
+#define TSI148_LCSR_OT6_OTOFU 0x1D0
+#define TSI148_LCSR_OT6_OTOFL 0x1D4
+#define TSI148_LCSR_OT6_OTBS 0x1D8
+#define TSI148_LCSR_OT6_OTAT 0x1DC
+
+#define TSI148_LCSR_OT7_OTSAU 0x1E0
+#define TSI148_LCSR_OT7_OTSAL 0x1E4
+#define TSI148_LCSR_OT7_OTEAU 0x1E8
+#define TSI148_LCSR_OT7_OTEAL 0x1EC
+#define TSI148_LCSR_OT7_OTOFU 0x1F0
+#define TSI148_LCSR_OT7_OTOFL 0x1F4
+#define TSI148_LCSR_OT7_OTBS 0x1F8
+#define TSI148_LCSR_OT7_OTAT 0x1FC
+
+#define TSI148_LCSR_OT0 0x100
+#define TSI148_LCSR_OT1 0x120
+#define TSI148_LCSR_OT2 0x140
+#define TSI148_LCSR_OT3 0x160
+#define TSI148_LCSR_OT4 0x180
+#define TSI148_LCSR_OT5 0x1A0
+#define TSI148_LCSR_OT6 0x1C0
+#define TSI148_LCSR_OT7 0x1E0
+
+static const int TSI148_LCSR_OT[8] = { TSI148_LCSR_OT0, TSI148_LCSR_OT1,
+ TSI148_LCSR_OT2, TSI148_LCSR_OT3,
+ TSI148_LCSR_OT4, TSI148_LCSR_OT5,
+ TSI148_LCSR_OT6, TSI148_LCSR_OT7 };
+
+#define TSI148_LCSR_OFFSET_OTSAU 0x0
+#define TSI148_LCSR_OFFSET_OTSAL 0x4
+#define TSI148_LCSR_OFFSET_OTEAU 0x8
+#define TSI148_LCSR_OFFSET_OTEAL 0xC
+#define TSI148_LCSR_OFFSET_OTOFU 0x10
+#define TSI148_LCSR_OFFSET_OTOFL 0x14
+#define TSI148_LCSR_OFFSET_OTBS 0x18
+#define TSI148_LCSR_OFFSET_OTAT 0x1C
+
+/*
+ * VMEbus interrupt ack
+ * offset 200
+ */
+#define TSI148_LCSR_VIACK1 0x204
+#define TSI148_LCSR_VIACK2 0x208
+#define TSI148_LCSR_VIACK3 0x20C
+#define TSI148_LCSR_VIACK4 0x210
+#define TSI148_LCSR_VIACK5 0x214
+#define TSI148_LCSR_VIACK6 0x218
+#define TSI148_LCSR_VIACK7 0x21C
+
+static const int TSI148_LCSR_VIACK[8] = { 0, TSI148_LCSR_VIACK1,
+ TSI148_LCSR_VIACK2, TSI148_LCSR_VIACK3,
+ TSI148_LCSR_VIACK4, TSI148_LCSR_VIACK5,
+ TSI148_LCSR_VIACK6, TSI148_LCSR_VIACK7 };
+
+/*
+ * RMW
+ * offset 220
+ */
+#define TSI148_LCSR_RMWAU 0x220
+#define TSI148_LCSR_RMWAL 0x224
+#define TSI148_LCSR_RMWEN 0x228
+#define TSI148_LCSR_RMWC 0x22C
+#define TSI148_LCSR_RMWS 0x230
+
+/*
+ * VMEbus control
+ * offset 234
+ */
+#define TSI148_LCSR_VMCTRL 0x234
+#define TSI148_LCSR_VCTRL 0x238
+#define TSI148_LCSR_VSTAT 0x23C
+
+/*
+ * PCI status
+ * offset 240
+ */
+#define TSI148_LCSR_PSTAT 0x240
+
+/*
+ * VME filter.
+ * offset 250
+ */
+#define TSI148_LCSR_VMEFL 0x250
+
+ /*
+ * VME exception.
+ * offset 260
+ */
+#define TSI148_LCSR_VEAU 0x260
+#define TSI148_LCSR_VEAL 0x264
+#define TSI148_LCSR_VEAT 0x268
+
+ /*
+ * PCI error
+ * offset 270
+ */
+#define TSI148_LCSR_EDPAU 0x270
+#define TSI148_LCSR_EDPAL 0x274
+#define TSI148_LCSR_EDPXA 0x278
+#define TSI148_LCSR_EDPXS 0x27C
+#define TSI148_LCSR_EDPAT 0x280
+
+ /*
+ * Inbound Translations
+ * offset 300
+ */
+#define TSI148_LCSR_IT0_ITSAU 0x300
+#define TSI148_LCSR_IT0_ITSAL 0x304
+#define TSI148_LCSR_IT0_ITEAU 0x308
+#define TSI148_LCSR_IT0_ITEAL 0x30C
+#define TSI148_LCSR_IT0_ITOFU 0x310
+#define TSI148_LCSR_IT0_ITOFL 0x314
+#define TSI148_LCSR_IT0_ITAT 0x318
+
+#define TSI148_LCSR_IT1_ITSAU 0x320
+#define TSI148_LCSR_IT1_ITSAL 0x324
+#define TSI148_LCSR_IT1_ITEAU 0x328
+#define TSI148_LCSR_IT1_ITEAL 0x32C
+#define TSI148_LCSR_IT1_ITOFU 0x330
+#define TSI148_LCSR_IT1_ITOFL 0x334
+#define TSI148_LCSR_IT1_ITAT 0x338
+
+#define TSI148_LCSR_IT2_ITSAU 0x340
+#define TSI148_LCSR_IT2_ITSAL 0x344
+#define TSI148_LCSR_IT2_ITEAU 0x348
+#define TSI148_LCSR_IT2_ITEAL 0x34C
+#define TSI148_LCSR_IT2_ITOFU 0x350
+#define TSI148_LCSR_IT2_ITOFL 0x354
+#define TSI148_LCSR_IT2_ITAT 0x358
+
+#define TSI148_LCSR_IT3_ITSAU 0x360
+#define TSI148_LCSR_IT3_ITSAL 0x364
+#define TSI148_LCSR_IT3_ITEAU 0x368
+#define TSI148_LCSR_IT3_ITEAL 0x36C
+#define TSI148_LCSR_IT3_ITOFU 0x370
+#define TSI148_LCSR_IT3_ITOFL 0x374
+#define TSI148_LCSR_IT3_ITAT 0x378
+
+#define TSI148_LCSR_IT4_ITSAU 0x380
+#define TSI148_LCSR_IT4_ITSAL 0x384
+#define TSI148_LCSR_IT4_ITEAU 0x388
+#define TSI148_LCSR_IT4_ITEAL 0x38C
+#define TSI148_LCSR_IT4_ITOFU 0x390
+#define TSI148_LCSR_IT4_ITOFL 0x394
+#define TSI148_LCSR_IT4_ITAT 0x398
+
+#define TSI148_LCSR_IT5_ITSAU 0x3A0
+#define TSI148_LCSR_IT5_ITSAL 0x3A4
+#define TSI148_LCSR_IT5_ITEAU 0x3A8
+#define TSI148_LCSR_IT5_ITEAL 0x3AC
+#define TSI148_LCSR_IT5_ITOFU 0x3B0
+#define TSI148_LCSR_IT5_ITOFL 0x3B4
+#define TSI148_LCSR_IT5_ITAT 0x3B8
+
+#define TSI148_LCSR_IT6_ITSAU 0x3C0
+#define TSI148_LCSR_IT6_ITSAL 0x3C4
+#define TSI148_LCSR_IT6_ITEAU 0x3C8
+#define TSI148_LCSR_IT6_ITEAL 0x3CC
+#define TSI148_LCSR_IT6_ITOFU 0x3D0
+#define TSI148_LCSR_IT6_ITOFL 0x3D4
+#define TSI148_LCSR_IT6_ITAT 0x3D8
+
+#define TSI148_LCSR_IT7_ITSAU 0x3E0
+#define TSI148_LCSR_IT7_ITSAL 0x3E4
+#define TSI148_LCSR_IT7_ITEAU 0x3E8
+#define TSI148_LCSR_IT7_ITEAL 0x3EC
+#define TSI148_LCSR_IT7_ITOFU 0x3F0
+#define TSI148_LCSR_IT7_ITOFL 0x3F4
+#define TSI148_LCSR_IT7_ITAT 0x3F8
+
+
+#define TSI148_LCSR_IT0 0x300
+#define TSI148_LCSR_IT1 0x320
+#define TSI148_LCSR_IT2 0x340
+#define TSI148_LCSR_IT3 0x360
+#define TSI148_LCSR_IT4 0x380
+#define TSI148_LCSR_IT5 0x3A0
+#define TSI148_LCSR_IT6 0x3C0
+#define TSI148_LCSR_IT7 0x3E0
+
+static const int TSI148_LCSR_IT[8] = { TSI148_LCSR_IT0, TSI148_LCSR_IT1,
+ TSI148_LCSR_IT2, TSI148_LCSR_IT3,
+ TSI148_LCSR_IT4, TSI148_LCSR_IT5,
+ TSI148_LCSR_IT6, TSI148_LCSR_IT7 };
+
+#define TSI148_LCSR_OFFSET_ITSAU 0x0
+#define TSI148_LCSR_OFFSET_ITSAL 0x4
+#define TSI148_LCSR_OFFSET_ITEAU 0x8
+#define TSI148_LCSR_OFFSET_ITEAL 0xC
+#define TSI148_LCSR_OFFSET_ITOFU 0x10
+#define TSI148_LCSR_OFFSET_ITOFL 0x14
+#define TSI148_LCSR_OFFSET_ITAT 0x18
+
+ /*
+ * Inbound Translation GCSR
+ * offset 400
+ */
+#define TSI148_LCSR_GBAU 0x400
+#define TSI148_LCSR_GBAL 0x404
+#define TSI148_LCSR_GCSRAT 0x408
+
+ /*
+ * Inbound Translation CRG
+ * offset 40C
+ */
+#define TSI148_LCSR_CBAU 0x40C
+#define TSI148_LCSR_CBAL 0x410
+#define TSI148_LCSR_CSRAT 0x414
+
+ /*
+ * Inbound Translation CR/CSR
+ * CRG
+ * offset 418
+ */
+#define TSI148_LCSR_CROU 0x418
+#define TSI148_LCSR_CROL 0x41C
+#define TSI148_LCSR_CRAT 0x420
+
+ /*
+ * Inbound Translation Location Monitor
+ * offset 424
+ */
+#define TSI148_LCSR_LMBAU 0x424
+#define TSI148_LCSR_LMBAL 0x428
+#define TSI148_LCSR_LMAT 0x42C
+
+ /*
+ * VMEbus Interrupt Control.
+ * offset 430
+ */
+#define TSI148_LCSR_BCU 0x430
+#define TSI148_LCSR_BCL 0x434
+#define TSI148_LCSR_BPGTR 0x438
+#define TSI148_LCSR_BPCTR 0x43C
+#define TSI148_LCSR_VICR 0x440
+
+ /*
+ * Local Bus Interrupt Control.
+ * offset 448
+ */
+#define TSI148_LCSR_INTEN 0x448
+#define TSI148_LCSR_INTEO 0x44C
+#define TSI148_LCSR_INTS 0x450
+#define TSI148_LCSR_INTC 0x454
+#define TSI148_LCSR_INTM1 0x458
+#define TSI148_LCSR_INTM2 0x45C
+
+ /*
+ * DMA Controllers
+ * offset 500
+ */
+#define TSI148_LCSR_DCTL0 0x500
+#define TSI148_LCSR_DSTA0 0x504
+#define TSI148_LCSR_DCSAU0 0x508
+#define TSI148_LCSR_DCSAL0 0x50C
+#define TSI148_LCSR_DCDAU0 0x510
+#define TSI148_LCSR_DCDAL0 0x514
+#define TSI148_LCSR_DCLAU0 0x518
+#define TSI148_LCSR_DCLAL0 0x51C
+#define TSI148_LCSR_DSAU0 0x520
+#define TSI148_LCSR_DSAL0 0x524
+#define TSI148_LCSR_DDAU0 0x528
+#define TSI148_LCSR_DDAL0 0x52C
+#define TSI148_LCSR_DSAT0 0x530
+#define TSI148_LCSR_DDAT0 0x534
+#define TSI148_LCSR_DNLAU0 0x538
+#define TSI148_LCSR_DNLAL0 0x53C
+#define TSI148_LCSR_DCNT0 0x540
+#define TSI148_LCSR_DDBS0 0x544
+
+#define TSI148_LCSR_DCTL1 0x580
+#define TSI148_LCSR_DSTA1 0x584
+#define TSI148_LCSR_DCSAU1 0x588
+#define TSI148_LCSR_DCSAL1 0x58C
+#define TSI148_LCSR_DCDAU1 0x590
+#define TSI148_LCSR_DCDAL1 0x594
+#define TSI148_LCSR_DCLAU1 0x598
+#define TSI148_LCSR_DCLAL1 0x59C
+#define TSI148_LCSR_DSAU1 0x5A0
+#define TSI148_LCSR_DSAL1 0x5A4
+#define TSI148_LCSR_DDAU1 0x5A8
+#define TSI148_LCSR_DDAL1 0x5AC
+#define TSI148_LCSR_DSAT1 0x5B0
+#define TSI148_LCSR_DDAT1 0x5B4
+#define TSI148_LCSR_DNLAU1 0x5B8
+#define TSI148_LCSR_DNLAL1 0x5BC
+#define TSI148_LCSR_DCNT1 0x5C0
+#define TSI148_LCSR_DDBS1 0x5C4
+
+#define TSI148_LCSR_DMA0 0x500
+#define TSI148_LCSR_DMA1 0x580
+
+
+static const int TSI148_LCSR_DMA[TSI148_MAX_DMA] = { TSI148_LCSR_DMA0,
+ TSI148_LCSR_DMA1 };
+
+#define TSI148_LCSR_OFFSET_DCTL 0x0
+#define TSI148_LCSR_OFFSET_DSTA 0x4
+#define TSI148_LCSR_OFFSET_DCSAU 0x8
+#define TSI148_LCSR_OFFSET_DCSAL 0xC
+#define TSI148_LCSR_OFFSET_DCDAU 0x10
+#define TSI148_LCSR_OFFSET_DCDAL 0x14
+#define TSI148_LCSR_OFFSET_DCLAU 0x18
+#define TSI148_LCSR_OFFSET_DCLAL 0x1C
+#define TSI148_LCSR_OFFSET_DSAU 0x20
+#define TSI148_LCSR_OFFSET_DSAL 0x24
+#define TSI148_LCSR_OFFSET_DDAU 0x28
+#define TSI148_LCSR_OFFSET_DDAL 0x2C
+#define TSI148_LCSR_OFFSET_DSAT 0x30
+#define TSI148_LCSR_OFFSET_DDAT 0x34
+#define TSI148_LCSR_OFFSET_DNLAU 0x38
+#define TSI148_LCSR_OFFSET_DNLAL 0x3C
+#define TSI148_LCSR_OFFSET_DCNT 0x40
+#define TSI148_LCSR_OFFSET_DDBS 0x44
+
+ /*
+ * GCSR Register Group
+ */
+
+ /*
+ * GCSR CRG
+ * offset 00 600 - DEVI/VENI
+ * offset 04 604 - CTRL/GA/REVID
+ * offset 08 608 - Semaphore3/2/1/0
+ * offset 0C 60C - Seamphore7/6/5/4
+ */
+#define TSI148_GCSR_ID 0x600
+#define TSI148_GCSR_CSR 0x604
+#define TSI148_GCSR_SEMA0 0x608
+#define TSI148_GCSR_SEMA1 0x60C
+
+ /*
+ * Mail Box
+ * GCSR CRG
+ * offset 10 610 - Mailbox0
+ */
+#define TSI148_GCSR_MBOX0 0x610
+#define TSI148_GCSR_MBOX1 0x614
+#define TSI148_GCSR_MBOX2 0x618
+#define TSI148_GCSR_MBOX3 0x61C
+
+static const int TSI148_GCSR_MBOX[4] = { TSI148_GCSR_MBOX0,
+ TSI148_GCSR_MBOX1,
+ TSI148_GCSR_MBOX2,
+ TSI148_GCSR_MBOX3 };
+
+ /*
+ * CR/CSR
+ */
+
+ /*
+ * CR/CSR CRG
+ * offset 7FFF4 FF4 - CSRBCR
+ * offset 7FFF8 FF8 - CSRBSR
+ * offset 7FFFC FFC - CBAR
+ */
+#define TSI148_CSRBCR 0xFF4
+#define TSI148_CSRBSR 0xFF8
+#define TSI148_CBAR 0xFFC
+
+
+
+
+ /*
+ * TSI148 Register Bit Definitions
+ */
+
+ /*
+ * PFCS Register Set
+ */
+#define TSI148_PCFS_CMMD_SERR (1<<8) /* SERR_L out pin ssys err */
+#define TSI148_PCFS_CMMD_PERR (1<<6) /* PERR_L out pin parity */
+#define TSI148_PCFS_CMMD_MSTR (1<<2) /* PCI bus master */
+#define TSI148_PCFS_CMMD_MEMSP (1<<1) /* PCI mem space access */
+#define TSI148_PCFS_CMMD_IOSP (1<<0) /* PCI I/O space enable */
+
+#define TSI148_PCFS_STAT_RCPVE (1<<15) /* Detected Parity Error */
+#define TSI148_PCFS_STAT_SIGSE (1<<14) /* Signalled System Error */
+#define TSI148_PCFS_STAT_RCVMA (1<<13) /* Received Master Abort */
+#define TSI148_PCFS_STAT_RCVTA (1<<12) /* Received Target Abort */
+#define TSI148_PCFS_STAT_SIGTA (1<<11) /* Signalled Target Abort */
+#define TSI148_PCFS_STAT_SELTIM (3<<9) /* DELSEL Timing */
+#define TSI148_PCFS_STAT_DPAR (1<<8) /* Data Parity Err Reported */
+#define TSI148_PCFS_STAT_FAST (1<<7) /* Fast back-to-back Cap */
+#define TSI148_PCFS_STAT_P66M (1<<5) /* 66 MHz Capable */
+#define TSI148_PCFS_STAT_CAPL (1<<4) /* Capab List - address $34 */
+
+/*
+ * Revision ID/Class Code Registers (CRG +$008)
+ */
+#define TSI148_PCFS_CLAS_M (0xFF<<24) /* Class ID */
+#define TSI148_PCFS_SUBCLAS_M (0xFF<<16) /* Sub-Class ID */
+#define TSI148_PCFS_PROGIF_M (0xFF<<8) /* Sub-Class ID */
+#define TSI148_PCFS_REVID_M (0xFF<<0) /* Rev ID */
+
+/*
+ * Cache Line Size/ Master Latency Timer/ Header Type Registers (CRG + $00C)
+ */
+#define TSI148_PCFS_HEAD_M (0xFF<<16) /* Master Lat Timer */
+#define TSI148_PCFS_MLAT_M (0xFF<<8) /* Master Lat Timer */
+#define TSI148_PCFS_CLSZ_M (0xFF<<0) /* Cache Line Size */
+
+/*
+ * Memory Base Address Lower Reg (CRG + $010)
+ */
+#define TSI148_PCFS_MBARL_BASEL_M (0xFFFFF<<12) /* Base Addr Lower Mask */
+#define TSI148_PCFS_MBARL_PRE (1<<3) /* Prefetch */
+#define TSI148_PCFS_MBARL_MTYPE_M (3<<1) /* Memory Type Mask */
+#define TSI148_PCFS_MBARL_IOMEM (1<<0) /* I/O Space Indicator */
+
+/*
+ * Message Signaled Interrupt Capabilities Register (CRG + $040)
+ */
+#define TSI148_PCFS_MSICAP_64BAC (1<<7) /* 64-bit Address Capable */
+#define TSI148_PCFS_MSICAP_MME_M (7<<4) /* Multiple Msg Enable Mask */
+#define TSI148_PCFS_MSICAP_MMC_M (7<<1) /* Multiple Msg Capable Mask */
+#define TSI148_PCFS_MSICAP_MSIEN (1<<0) /* Msg signaled INT Enable */
+
+/*
+ * Message Address Lower Register (CRG +$044)
+ */
+#define TSI148_PCFS_MSIAL_M (0x3FFFFFFF<<2) /* Mask */
+
+/*
+ * Message Data Register (CRG + 4C)
+ */
+#define TSI148_PCFS_MSIMD_M (0xFFFF<<0) /* Mask */
+
+/*
+ * PCI-X Capabilities Register (CRG + $050)
+ */
+#define TSI148_PCFS_PCIXCAP_MOST_M (7<<4) /* Max outstanding Split Tran */
+#define TSI148_PCFS_PCIXCAP_MMRBC_M (3<<2) /* Max Mem Read byte cnt */
+#define TSI148_PCFS_PCIXCAP_ERO (1<<1) /* Enable Relaxed Ordering */
+#define TSI148_PCFS_PCIXCAP_DPERE (1<<0) /* Data Parity Recover Enable */
+
+/*
+ * PCI-X Status Register (CRG +$054)
+ */
+#define TSI148_PCFS_PCIXSTAT_RSCEM (1<<29) /* Received Split Comp Error */
+#define TSI148_PCFS_PCIXSTAT_DMCRS_M (7<<26) /* max Cumulative Read Size */
+#define TSI148_PCFS_PCIXSTAT_DMOST_M (7<<23) /* max outstanding Split Trans
+ */
+#define TSI148_PCFS_PCIXSTAT_DMMRC_M (3<<21) /* max mem read byte count */
+#define TSI148_PCFS_PCIXSTAT_DC (1<<20) /* Device Complexity */
+#define TSI148_PCFS_PCIXSTAT_USC (1<<19) /* Unexpected Split comp */
+#define TSI148_PCFS_PCIXSTAT_SCD (1<<18) /* Split completion discard */
+#define TSI148_PCFS_PCIXSTAT_133C (1<<17) /* 133MHz capable */
+#define TSI148_PCFS_PCIXSTAT_64D (1<<16) /* 64 bit device */
+#define TSI148_PCFS_PCIXSTAT_BN_M (0xFF<<8) /* Bus number */
+#define TSI148_PCFS_PCIXSTAT_DN_M (0x1F<<3) /* Device number */
+#define TSI148_PCFS_PCIXSTAT_FN_M (7<<0) /* Function Number */
+
+/*
+ * LCSR Registers
+ */
+
+/*
+ * Outbound Translation Starting Address Lower
+ */
+#define TSI148_LCSR_OTSAL_M (0xFFFF<<16) /* Mask */
+
+/*
+ * Outbound Translation Ending Address Lower
+ */
+#define TSI148_LCSR_OTEAL_M (0xFFFF<<16) /* Mask */
+
+/*
+ * Outbound Translation Offset Lower
+ */
+#define TSI148_LCSR_OTOFFL_M (0xFFFF<<16) /* Mask */
+
+/*
+ * Outbound Translation 2eSST Broadcast Select
+ */
+#define TSI148_LCSR_OTBS_M (0xFFFFF<<0) /* Mask */
+
+/*
+ * Outbound Translation Attribute
+ */
+#define TSI148_LCSR_OTAT_EN (1<<31) /* Window Enable */
+#define TSI148_LCSR_OTAT_MRPFD (1<<18) /* Prefetch Disable */
+
+#define TSI148_LCSR_OTAT_PFS_M (3<<16) /* Prefetch Size Mask */
+#define TSI148_LCSR_OTAT_PFS_2 (0<<16) /* 2 Cache Lines P Size */
+#define TSI148_LCSR_OTAT_PFS_4 (1<<16) /* 4 Cache Lines P Size */
+#define TSI148_LCSR_OTAT_PFS_8 (2<<16) /* 8 Cache Lines P Size */
+#define TSI148_LCSR_OTAT_PFS_16 (3<<16) /* 16 Cache Lines P Size */
+
+#define TSI148_LCSR_OTAT_2eSSTM_M (7<<11) /* 2eSST Xfer Rate Mask */
+#define TSI148_LCSR_OTAT_2eSSTM_160 (0<<11) /* 160MB/s 2eSST Xfer Rate */
+#define TSI148_LCSR_OTAT_2eSSTM_267 (1<<11) /* 267MB/s 2eSST Xfer Rate */
+#define TSI148_LCSR_OTAT_2eSSTM_320 (2<<11) /* 320MB/s 2eSST Xfer Rate */
+
+#define TSI148_LCSR_OTAT_TM_M (7<<8) /* Xfer Protocol Mask */
+#define TSI148_LCSR_OTAT_TM_SCT (0<<8) /* SCT Xfer Protocol */
+#define TSI148_LCSR_OTAT_TM_BLT (1<<8) /* BLT Xfer Protocol */
+#define TSI148_LCSR_OTAT_TM_MBLT (2<<8) /* MBLT Xfer Protocol */
+#define TSI148_LCSR_OTAT_TM_2eVME (3<<8) /* 2eVME Xfer Protocol */
+#define TSI148_LCSR_OTAT_TM_2eSST (4<<8) /* 2eSST Xfer Protocol */
+#define TSI148_LCSR_OTAT_TM_2eSSTB (5<<8) /* 2eSST Bcast Xfer Protocol */
+
+#define TSI148_LCSR_OTAT_DBW_M (3<<6) /* Max Data Width */
+#define TSI148_LCSR_OTAT_DBW_16 (0<<6) /* 16-bit Data Width */
+#define TSI148_LCSR_OTAT_DBW_32 (1<<6) /* 32-bit Data Width */
+
+#define TSI148_LCSR_OTAT_SUP (1<<5) /* Supervisory Access */
+#define TSI148_LCSR_OTAT_PGM (1<<4) /* Program Access */
+
+#define TSI148_LCSR_OTAT_AMODE_M (0xf<<0) /* Address Mode Mask */
+#define TSI148_LCSR_OTAT_AMODE_A16 (0<<0) /* A16 Address Space */
+#define TSI148_LCSR_OTAT_AMODE_A24 (1<<0) /* A24 Address Space */
+#define TSI148_LCSR_OTAT_AMODE_A32 (2<<0) /* A32 Address Space */
+#define TSI148_LCSR_OTAT_AMODE_A64 (4<<0) /* A32 Address Space */
+#define TSI148_LCSR_OTAT_AMODE_CRCSR (5<<0) /* CR/CSR Address Space */
+#define TSI148_LCSR_OTAT_AMODE_USER1 (8<<0) /* User1 Address Space */
+#define TSI148_LCSR_OTAT_AMODE_USER2 (9<<0) /* User2 Address Space */
+#define TSI148_LCSR_OTAT_AMODE_USER3 (10<<0) /* User3 Address Space */
+#define TSI148_LCSR_OTAT_AMODE_USER4 (11<<0) /* User4 Address Space */
+
+/*
+ * VME Master Control Register CRG+$234
+ */
+#define TSI148_LCSR_VMCTRL_VSA (1<<27) /* VMEbus Stop Ack */
+#define TSI148_LCSR_VMCTRL_VS (1<<26) /* VMEbus Stop */
+#define TSI148_LCSR_VMCTRL_DHB (1<<25) /* Device Has Bus */
+#define TSI148_LCSR_VMCTRL_DWB (1<<24) /* Device Wants Bus */
+
+#define TSI148_LCSR_VMCTRL_RMWEN (1<<20) /* RMW Enable */
+
+#define TSI148_LCSR_VMCTRL_ATO_M (7<<16) /* Master Access Time-out Mask
+ */
+#define TSI148_LCSR_VMCTRL_ATO_32 (0<<16) /* 32 us */
+#define TSI148_LCSR_VMCTRL_ATO_128 (1<<16) /* 128 us */
+#define TSI148_LCSR_VMCTRL_ATO_512 (2<<16) /* 512 us */
+#define TSI148_LCSR_VMCTRL_ATO_2M (3<<16) /* 2 ms */
+#define TSI148_LCSR_VMCTRL_ATO_8M (4<<16) /* 8 ms */
+#define TSI148_LCSR_VMCTRL_ATO_32M (5<<16) /* 32 ms */
+#define TSI148_LCSR_VMCTRL_ATO_128M (6<<16) /* 128 ms */
+#define TSI148_LCSR_VMCTRL_ATO_DIS (7<<16) /* Disabled */
+
+#define TSI148_LCSR_VMCTRL_VTOFF_M (7<<12) /* VMEbus Master Time off */
+#define TSI148_LCSR_VMCTRL_VTOFF_0 (0<<12) /* 0us */
+#define TSI148_LCSR_VMCTRL_VTOFF_1 (1<<12) /* 1us */
+#define TSI148_LCSR_VMCTRL_VTOFF_2 (2<<12) /* 2us */
+#define TSI148_LCSR_VMCTRL_VTOFF_4 (3<<12) /* 4us */
+#define TSI148_LCSR_VMCTRL_VTOFF_8 (4<<12) /* 8us */
+#define TSI148_LCSR_VMCTRL_VTOFF_16 (5<<12) /* 16us */
+#define TSI148_LCSR_VMCTRL_VTOFF_32 (6<<12) /* 32us */
+#define TSI148_LCSR_VMCTRL_VTOFF_64 (7<<12) /* 64us */
+
+#define TSI148_LCSR_VMCTRL_VTON_M (7<<8) /* VMEbus Master Time On */
+#define TSI148_LCSR_VMCTRL_VTON_4 (0<<8) /* 8us */
+#define TSI148_LCSR_VMCTRL_VTON_8 (1<<8) /* 8us */
+#define TSI148_LCSR_VMCTRL_VTON_16 (2<<8) /* 16us */
+#define TSI148_LCSR_VMCTRL_VTON_32 (3<<8) /* 32us */
+#define TSI148_LCSR_VMCTRL_VTON_64 (4<<8) /* 64us */
+#define TSI148_LCSR_VMCTRL_VTON_128 (5<<8) /* 128us */
+#define TSI148_LCSR_VMCTRL_VTON_256 (6<<8) /* 256us */
+#define TSI148_LCSR_VMCTRL_VTON_512 (7<<8) /* 512us */
+
+#define TSI148_LCSR_VMCTRL_VREL_M (3<<3) /* VMEbus Master Rel Mode Mask
+ */
+#define TSI148_LCSR_VMCTRL_VREL_T_D (0<<3) /* Time on or Done */
+#define TSI148_LCSR_VMCTRL_VREL_T_R_D (1<<3) /* Time on and REQ or Done */
+#define TSI148_LCSR_VMCTRL_VREL_T_B_D (2<<3) /* Time on and BCLR or Done */
+#define TSI148_LCSR_VMCTRL_VREL_T_D_R (3<<3) /* Time on or Done and REQ */
+
+#define TSI148_LCSR_VMCTRL_VFAIR (1<<2) /* VMEbus Master Fair Mode */
+#define TSI148_LCSR_VMCTRL_VREQL_M (3<<0) /* VMEbus Master Req Level Mask
+ */
+
+/*
+ * VMEbus Control Register CRG+$238
+ */
+#define TSI148_LCSR_VCTRL_LRE (1<<31) /* Late Retry Enable */
+
+#define TSI148_LCSR_VCTRL_DLT_M (0xF<<24) /* Deadlock Timer */
+#define TSI148_LCSR_VCTRL_DLT_OFF (0<<24) /* Deadlock Timer Off */
+#define TSI148_LCSR_VCTRL_DLT_16 (1<<24) /* 16 VCLKS */
+#define TSI148_LCSR_VCTRL_DLT_32 (2<<24) /* 32 VCLKS */
+#define TSI148_LCSR_VCTRL_DLT_64 (3<<24) /* 64 VCLKS */
+#define TSI148_LCSR_VCTRL_DLT_128 (4<<24) /* 128 VCLKS */
+#define TSI148_LCSR_VCTRL_DLT_256 (5<<24) /* 256 VCLKS */
+#define TSI148_LCSR_VCTRL_DLT_512 (6<<24) /* 512 VCLKS */
+#define TSI148_LCSR_VCTRL_DLT_1024 (7<<24) /* 1024 VCLKS */
+#define TSI148_LCSR_VCTRL_DLT_2048 (8<<24) /* 2048 VCLKS */
+#define TSI148_LCSR_VCTRL_DLT_4096 (9<<24) /* 4096 VCLKS */
+#define TSI148_LCSR_VCTRL_DLT_8192 (0xA<<24) /* 8192 VCLKS */
+#define TSI148_LCSR_VCTRL_DLT_16384 (0xB<<24) /* 16384 VCLKS */
+#define TSI148_LCSR_VCTRL_DLT_32768 (0xC<<24) /* 32768 VCLKS */
+
+#define TSI148_LCSR_VCTRL_NERBB (1<<20) /* No Early Release of Bus Busy
+ */
+
+#define TSI148_LCSR_VCTRL_SRESET (1<<17) /* System Reset */
+#define TSI148_LCSR_VCTRL_LRESET (1<<16) /* Local Reset */
+
+#define TSI148_LCSR_VCTRL_SFAILAI (1<<15) /* SYSFAIL Auto Slot ID */
+#define TSI148_LCSR_VCTRL_BID_M (0x1F<<8) /* Broadcast ID Mask */
+
+#define TSI148_LCSR_VCTRL_ATOEN (1<<7) /* Arbiter Time-out Enable */
+#define TSI148_LCSR_VCTRL_ROBIN (1<<6) /* VMEbus Round Robin */
+
+#define TSI148_LCSR_VCTRL_GTO_M (7<<0) /* VMEbus Global Time-out Mask
+ */
+#define TSI148_LCSR_VCTRL_GTO_8 (0<<0) /* 8 us */
+#define TSI148_LCSR_VCTRL_GTO_16 (1<<0) /* 16 us */
+#define TSI148_LCSR_VCTRL_GTO_32 (2<<0) /* 32 us */
+#define TSI148_LCSR_VCTRL_GTO_64 (3<<0) /* 64 us */
+#define TSI148_LCSR_VCTRL_GTO_128 (4<<0) /* 128 us */
+#define TSI148_LCSR_VCTRL_GTO_256 (5<<0) /* 256 us */
+#define TSI148_LCSR_VCTRL_GTO_512 (6<<0) /* 512 us */
+#define TSI148_LCSR_VCTRL_GTO_DIS (7<<0) /* Disabled */
+
+/*
+ * VMEbus Status Register CRG + $23C
+ */
+#define TSI148_LCSR_VSTAT_CPURST (1<<15) /* Clear power up reset */
+#define TSI148_LCSR_VSTAT_BRDFL (1<<14) /* Board fail */
+#define TSI148_LCSR_VSTAT_PURSTS (1<<12) /* Power up reset status */
+#define TSI148_LCSR_VSTAT_BDFAILS (1<<11) /* Board Fail Status */
+#define TSI148_LCSR_VSTAT_SYSFAILS (1<<10) /* System Fail Status */
+#define TSI148_LCSR_VSTAT_ACFAILS (1<<9) /* AC fail status */
+#define TSI148_LCSR_VSTAT_SCONS (1<<8) /* System Cont Status */
+#define TSI148_LCSR_VSTAT_GAP (1<<5) /* Geographic Addr Parity */
+#define TSI148_LCSR_VSTAT_GA_M (0x1F<<0) /* Geographic Addr Mask */
+
+/*
+ * PCI Configuration Status Register CRG+$240
+ */
+#define TSI148_LCSR_PSTAT_REQ64S (1<<6) /* Request 64 status set */
+#define TSI148_LCSR_PSTAT_M66ENS (1<<5) /* M66ENS 66Mhz enable */
+#define TSI148_LCSR_PSTAT_FRAMES (1<<4) /* Frame Status */
+#define TSI148_LCSR_PSTAT_IRDYS (1<<3) /* IRDY status */
+#define TSI148_LCSR_PSTAT_DEVSELS (1<<2) /* DEVL status */
+#define TSI148_LCSR_PSTAT_STOPS (1<<1) /* STOP status */
+#define TSI148_LCSR_PSTAT_TRDYS (1<<0) /* TRDY status */
+
+/*
+ * VMEbus Exception Attributes Register CRG + $268
+ */
+#define TSI148_LCSR_VEAT_VES (1<<31) /* Status */
+#define TSI148_LCSR_VEAT_VEOF (1<<30) /* Overflow */
+#define TSI148_LCSR_VEAT_VESCL (1<<29) /* Status Clear */
+#define TSI148_LCSR_VEAT_2EOT (1<<21) /* 2e Odd Termination */
+#define TSI148_LCSR_VEAT_2EST (1<<20) /* 2e Slave terminated */
+#define TSI148_LCSR_VEAT_BERR (1<<19) /* Bus Error */
+#define TSI148_LCSR_VEAT_LWORD (1<<18) /* LWORD_ signal state */
+#define TSI148_LCSR_VEAT_WRITE (1<<17) /* WRITE_ signal state */
+#define TSI148_LCSR_VEAT_IACK (1<<16) /* IACK_ signal state */
+#define TSI148_LCSR_VEAT_DS1 (1<<15) /* DS1_ signal state */
+#define TSI148_LCSR_VEAT_DS0 (1<<14) /* DS0_ signal state */
+#define TSI148_LCSR_VEAT_AM_M (0x3F<<8) /* Address Mode Mask */
+#define TSI148_LCSR_VEAT_XAM_M (0xFF<<0) /* Master AMode Mask */
+
+
+/*
+ * VMEbus PCI Error Diagnostics PCI/X Attributes Register CRG + $280
+ */
+#define TSI148_LCSR_EDPAT_EDPCL (1<<29)
+
+/*
+ * Inbound Translation Starting Address Lower
+ */
+#define TSI148_LCSR_ITSAL6432_M (0xFFFF<<16) /* Mask */
+#define TSI148_LCSR_ITSAL24_M (0x00FFF<<12) /* Mask */
+#define TSI148_LCSR_ITSAL16_M (0x0000FFF<<4) /* Mask */
+
+/*
+ * Inbound Translation Ending Address Lower
+ */
+#define TSI148_LCSR_ITEAL6432_M (0xFFFF<<16) /* Mask */
+#define TSI148_LCSR_ITEAL24_M (0x00FFF<<12) /* Mask */
+#define TSI148_LCSR_ITEAL16_M (0x0000FFF<<4) /* Mask */
+
+/*
+ * Inbound Translation Offset Lower
+ */
+#define TSI148_LCSR_ITOFFL6432_M (0xFFFF<<16) /* Mask */
+#define TSI148_LCSR_ITOFFL24_M (0xFFFFF<<12) /* Mask */
+#define TSI148_LCSR_ITOFFL16_M (0xFFFFFFF<<4) /* Mask */
+
+/*
+ * Inbound Translation Attribute
+ */
+#define TSI148_LCSR_ITAT_EN (1<<31) /* Window Enable */
+#define TSI148_LCSR_ITAT_TH (1<<18) /* Prefetch Threshold */
+
+#define TSI148_LCSR_ITAT_VFS_M (3<<16) /* Virtual FIFO Size Mask */
+#define TSI148_LCSR_ITAT_VFS_64 (0<<16) /* 64 bytes Virtual FIFO Size */
+#define TSI148_LCSR_ITAT_VFS_128 (1<<16) /* 128 bytes Virtual FIFO Sz */
+#define TSI148_LCSR_ITAT_VFS_256 (2<<16) /* 256 bytes Virtual FIFO Sz */
+#define TSI148_LCSR_ITAT_VFS_512 (3<<16) /* 512 bytes Virtual FIFO Sz */
+
+#define TSI148_LCSR_ITAT_2eSSTM_M (7<<12) /* 2eSST Xfer Rate Mask */
+#define TSI148_LCSR_ITAT_2eSSTM_160 (0<<12) /* 160MB/s 2eSST Xfer Rate */
+#define TSI148_LCSR_ITAT_2eSSTM_267 (1<<12) /* 267MB/s 2eSST Xfer Rate */
+#define TSI148_LCSR_ITAT_2eSSTM_320 (2<<12) /* 320MB/s 2eSST Xfer Rate */
+
+#define TSI148_LCSR_ITAT_2eSSTB (1<<11) /* 2eSST Bcast Xfer Protocol */
+#define TSI148_LCSR_ITAT_2eSST (1<<10) /* 2eSST Xfer Protocol */
+#define TSI148_LCSR_ITAT_2eVME (1<<9) /* 2eVME Xfer Protocol */
+#define TSI148_LCSR_ITAT_MBLT (1<<8) /* MBLT Xfer Protocol */
+#define TSI148_LCSR_ITAT_BLT (1<<7) /* BLT Xfer Protocol */
+
+#define TSI148_LCSR_ITAT_AS_M (7<<4) /* Address Space Mask */
+#define TSI148_LCSR_ITAT_AS_A16 (0<<4) /* A16 Address Space */
+#define TSI148_LCSR_ITAT_AS_A24 (1<<4) /* A24 Address Space */
+#define TSI148_LCSR_ITAT_AS_A32 (2<<4) /* A32 Address Space */
+#define TSI148_LCSR_ITAT_AS_A64 (4<<4) /* A64 Address Space */
+
+#define TSI148_LCSR_ITAT_SUPR (1<<3) /* Supervisor Access */
+#define TSI148_LCSR_ITAT_NPRIV (1<<2) /* Non-Priv (User) Access */
+#define TSI148_LCSR_ITAT_PGM (1<<1) /* Program Access */
+#define TSI148_LCSR_ITAT_DATA (1<<0) /* Data Access */
+
+/*
+ * GCSR Base Address Lower Address CRG +$404
+ */
+#define TSI148_LCSR_GBAL_M (0x7FFFFFF<<5) /* Mask */
+
+/*
+ * GCSR Attribute Register CRG + $408
+ */
+#define TSI148_LCSR_GCSRAT_EN (1<<7) /* Enable access to GCSR */
+
+#define TSI148_LCSR_GCSRAT_AS_M (7<<4) /* Address Space Mask */
+#define TSI148_LCSR_GCSRAT_AS_A16 (0<<4) /* Address Space 16 */
+#define TSI148_LCSR_GCSRAT_AS_A24 (1<<4) /* Address Space 24 */
+#define TSI148_LCSR_GCSRAT_AS_A32 (2<<4) /* Address Space 32 */
+#define TSI148_LCSR_GCSRAT_AS_A64 (4<<4) /* Address Space 64 */
+
+#define TSI148_LCSR_GCSRAT_SUPR (1<<3) /* Sup set -GCSR decoder */
+#define TSI148_LCSR_GCSRAT_NPRIV (1<<2) /* Non-Privliged set - CGSR */
+#define TSI148_LCSR_GCSRAT_PGM (1<<1) /* Program set - GCSR decoder */
+#define TSI148_LCSR_GCSRAT_DATA (1<<0) /* DATA set GCSR decoder */
+
+/*
+ * CRG Base Address Lower Address CRG + $410
+ */
+#define TSI148_LCSR_CBAL_M (0xFFFFF<<12)
+
+/*
+ * CRG Attribute Register CRG + $414
+ */
+#define TSI148_LCSR_CRGAT_EN (1<<7) /* Enable PRG Access */
+
+#define TSI148_LCSR_CRGAT_AS_M (7<<4) /* Address Space */
+#define TSI148_LCSR_CRGAT_AS_A16 (0<<4) /* Address Space 16 */
+#define TSI148_LCSR_CRGAT_AS_A24 (1<<4) /* Address Space 24 */
+#define TSI148_LCSR_CRGAT_AS_A32 (2<<4) /* Address Space 32 */
+#define TSI148_LCSR_CRGAT_AS_A64 (4<<4) /* Address Space 64 */
+
+#define TSI148_LCSR_CRGAT_SUPR (1<<3) /* Supervisor Access */
+#define TSI148_LCSR_CRGAT_NPRIV (1<<2) /* Non-Privliged(User) Access */
+#define TSI148_LCSR_CRGAT_PGM (1<<1) /* Program Access */
+#define TSI148_LCSR_CRGAT_DATA (1<<0) /* Data Access */
+
+/*
+ * CR/CSR Offset Lower Register CRG + $41C
+ */
+#define TSI148_LCSR_CROL_M (0x1FFF<<19) /* Mask */
+
+/*
+ * CR/CSR Attribute register CRG + $420
+ */
+#define TSI148_LCSR_CRAT_EN (1<<7) /* Enable access to CR/CSR */
+
+/*
+ * Location Monitor base address lower register CRG + $428
+ */
+#define TSI148_LCSR_LMBAL_M (0x7FFFFFF<<5) /* Mask */
+
+/*
+ * Location Monitor Attribute Register CRG + $42C
+ */
+#define TSI148_LCSR_LMAT_EN (1<<7) /* Enable Location Monitor */
+
+#define TSI148_LCSR_LMAT_AS_M (7<<4) /* Address Space MASK */
+#define TSI148_LCSR_LMAT_AS_A16 (0<<4) /* A16 */
+#define TSI148_LCSR_LMAT_AS_A24 (1<<4) /* A24 */
+#define TSI148_LCSR_LMAT_AS_A32 (2<<4) /* A32 */
+#define TSI148_LCSR_LMAT_AS_A64 (4<<4) /* A64 */
+
+#define TSI148_LCSR_LMAT_SUPR (1<<3) /* Supervisor Access */
+#define TSI148_LCSR_LMAT_NPRIV (1<<2) /* Non-Priv (User) Access */
+#define TSI148_LCSR_LMAT_PGM (1<<1) /* Program Access */
+#define TSI148_LCSR_LMAT_DATA (1<<0) /* Data Access */
+
+/*
+ * Broadcast Pulse Generator Timer Register CRG + $438
+ */
+#define TSI148_LCSR_BPGTR_BPGT_M (0xFFFF<<0) /* Mask */
+
+/*
+ * Broadcast Programmable Clock Timer Register CRG + $43C
+ */
+#define TSI148_LCSR_BPCTR_BPCT_M (0xFFFFFF<<0) /* Mask */
+
+/*
+ * VMEbus Interrupt Control Register CRG + $43C
+ */
+#define TSI148_LCSR_VICR_CNTS_M (3<<22) /* Cntr Source MASK */
+#define TSI148_LCSR_VICR_CNTS_DIS (1<<22) /* Cntr Disable */
+#define TSI148_LCSR_VICR_CNTS_IRQ1 (2<<22) /* IRQ1 to Cntr */
+#define TSI148_LCSR_VICR_CNTS_IRQ2 (3<<22) /* IRQ2 to Cntr */
+
+#define TSI148_LCSR_VICR_EDGIS_M (3<<20) /* Edge interrupt MASK */
+#define TSI148_LCSR_VICR_EDGIS_DIS (1<<20) /* Edge interrupt Disable */
+#define TSI148_LCSR_VICR_EDGIS_IRQ1 (2<<20) /* IRQ1 to Edge */
+#define TSI148_LCSR_VICR_EDGIS_IRQ2 (3<<20) /* IRQ2 to Edge */
+
+#define TSI148_LCSR_VICR_IRQIF_M (3<<18) /* IRQ1* Function MASK */
+#define TSI148_LCSR_VICR_IRQIF_NORM (1<<18) /* Normal */
+#define TSI148_LCSR_VICR_IRQIF_PULSE (2<<18) /* Pulse Generator */
+#define TSI148_LCSR_VICR_IRQIF_PROG (3<<18) /* Programmable Clock */
+#define TSI148_LCSR_VICR_IRQIF_1U (4<<18) /* 1us Clock */
+
+#define TSI148_LCSR_VICR_IRQ2F_M (3<<16) /* IRQ2* Function MASK */
+#define TSI148_LCSR_VICR_IRQ2F_NORM (1<<16) /* Normal */
+#define TSI148_LCSR_VICR_IRQ2F_PULSE (2<<16) /* Pulse Generator */
+#define TSI148_LCSR_VICR_IRQ2F_PROG (3<<16) /* Programmable Clock */
+#define TSI148_LCSR_VICR_IRQ2F_1U (4<<16) /* 1us Clock */
+
+#define TSI148_LCSR_VICR_BIP (1<<15) /* Broadcast Interrupt Pulse */
+
+#define TSI148_LCSR_VICR_IRQC (1<<12) /* VMEbus IRQ Clear */
+#define TSI148_LCSR_VICR_IRQS (1<<11) /* VMEbus IRQ Status */
+
+#define TSI148_LCSR_VICR_IRQL_M (7<<8) /* VMEbus SW IRQ Level Mask */
+#define TSI148_LCSR_VICR_IRQL_1 (1<<8) /* VMEbus SW IRQ Level 1 */
+#define TSI148_LCSR_VICR_IRQL_2 (2<<8) /* VMEbus SW IRQ Level 2 */
+#define TSI148_LCSR_VICR_IRQL_3 (3<<8) /* VMEbus SW IRQ Level 3 */
+#define TSI148_LCSR_VICR_IRQL_4 (4<<8) /* VMEbus SW IRQ Level 4 */
+#define TSI148_LCSR_VICR_IRQL_5 (5<<8) /* VMEbus SW IRQ Level 5 */
+#define TSI148_LCSR_VICR_IRQL_6 (6<<8) /* VMEbus SW IRQ Level 6 */
+#define TSI148_LCSR_VICR_IRQL_7 (7<<8) /* VMEbus SW IRQ Level 7 */
+
+static const int TSI148_LCSR_VICR_IRQL[8] = { 0, TSI148_LCSR_VICR_IRQL_1,
+ TSI148_LCSR_VICR_IRQL_2, TSI148_LCSR_VICR_IRQL_3,
+ TSI148_LCSR_VICR_IRQL_4, TSI148_LCSR_VICR_IRQL_5,
+ TSI148_LCSR_VICR_IRQL_6, TSI148_LCSR_VICR_IRQL_7 };
+
+#define TSI148_LCSR_VICR_STID_M (0xFF<<0) /* Status/ID Mask */
+
+/*
+ * Interrupt Enable Register CRG + $440
+ */
+#define TSI148_LCSR_INTEN_DMA1EN (1<<25) /* DMAC 1 */
+#define TSI148_LCSR_INTEN_DMA0EN (1<<24) /* DMAC 0 */
+#define TSI148_LCSR_INTEN_LM3EN (1<<23) /* Location Monitor 3 */
+#define TSI148_LCSR_INTEN_LM2EN (1<<22) /* Location Monitor 2 */
+#define TSI148_LCSR_INTEN_LM1EN (1<<21) /* Location Monitor 1 */
+#define TSI148_LCSR_INTEN_LM0EN (1<<20) /* Location Monitor 0 */
+#define TSI148_LCSR_INTEN_MB3EN (1<<19) /* Mail Box 3 */
+#define TSI148_LCSR_INTEN_MB2EN (1<<18) /* Mail Box 2 */
+#define TSI148_LCSR_INTEN_MB1EN (1<<17) /* Mail Box 1 */
+#define TSI148_LCSR_INTEN_MB0EN (1<<16) /* Mail Box 0 */
+#define TSI148_LCSR_INTEN_PERREN (1<<13) /* PCI/X Error */
+#define TSI148_LCSR_INTEN_VERREN (1<<12) /* VMEbus Error */
+#define TSI148_LCSR_INTEN_VIEEN (1<<11) /* VMEbus IRQ Edge */
+#define TSI148_LCSR_INTEN_IACKEN (1<<10) /* IACK */
+#define TSI148_LCSR_INTEN_SYSFLEN (1<<9) /* System Fail */
+#define TSI148_LCSR_INTEN_ACFLEN (1<<8) /* AC Fail */
+#define TSI148_LCSR_INTEN_IRQ7EN (1<<7) /* IRQ7 */
+#define TSI148_LCSR_INTEN_IRQ6EN (1<<6) /* IRQ6 */
+#define TSI148_LCSR_INTEN_IRQ5EN (1<<5) /* IRQ5 */
+#define TSI148_LCSR_INTEN_IRQ4EN (1<<4) /* IRQ4 */
+#define TSI148_LCSR_INTEN_IRQ3EN (1<<3) /* IRQ3 */
+#define TSI148_LCSR_INTEN_IRQ2EN (1<<2) /* IRQ2 */
+#define TSI148_LCSR_INTEN_IRQ1EN (1<<1) /* IRQ1 */
+
+static const int TSI148_LCSR_INTEN_LMEN[4] = { TSI148_LCSR_INTEN_LM0EN,
+ TSI148_LCSR_INTEN_LM1EN,
+ TSI148_LCSR_INTEN_LM2EN,
+ TSI148_LCSR_INTEN_LM3EN };
+
+static const int TSI148_LCSR_INTEN_IRQEN[7] = { TSI148_LCSR_INTEN_IRQ1EN,
+ TSI148_LCSR_INTEN_IRQ2EN,
+ TSI148_LCSR_INTEN_IRQ3EN,
+ TSI148_LCSR_INTEN_IRQ4EN,
+ TSI148_LCSR_INTEN_IRQ5EN,
+ TSI148_LCSR_INTEN_IRQ6EN,
+ TSI148_LCSR_INTEN_IRQ7EN };
+
+/*
+ * Interrupt Enable Out Register CRG + $444
+ */
+#define TSI148_LCSR_INTEO_DMA1EO (1<<25) /* DMAC 1 */
+#define TSI148_LCSR_INTEO_DMA0EO (1<<24) /* DMAC 0 */
+#define TSI148_LCSR_INTEO_LM3EO (1<<23) /* Loc Monitor 3 */
+#define TSI148_LCSR_INTEO_LM2EO (1<<22) /* Loc Monitor 2 */
+#define TSI148_LCSR_INTEO_LM1EO (1<<21) /* Loc Monitor 1 */
+#define TSI148_LCSR_INTEO_LM0EO (1<<20) /* Location Monitor 0 */
+#define TSI148_LCSR_INTEO_MB3EO (1<<19) /* Mail Box 3 */
+#define TSI148_LCSR_INTEO_MB2EO (1<<18) /* Mail Box 2 */
+#define TSI148_LCSR_INTEO_MB1EO (1<<17) /* Mail Box 1 */
+#define TSI148_LCSR_INTEO_MB0EO (1<<16) /* Mail Box 0 */
+#define TSI148_LCSR_INTEO_PERREO (1<<13) /* PCI/X Error */
+#define TSI148_LCSR_INTEO_VERREO (1<<12) /* VMEbus Error */
+#define TSI148_LCSR_INTEO_VIEEO (1<<11) /* VMEbus IRQ Edge */
+#define TSI148_LCSR_INTEO_IACKEO (1<<10) /* IACK */
+#define TSI148_LCSR_INTEO_SYSFLEO (1<<9) /* System Fail */
+#define TSI148_LCSR_INTEO_ACFLEO (1<<8) /* AC Fail */
+#define TSI148_LCSR_INTEO_IRQ7EO (1<<7) /* IRQ7 */
+#define TSI148_LCSR_INTEO_IRQ6EO (1<<6) /* IRQ6 */
+#define TSI148_LCSR_INTEO_IRQ5EO (1<<5) /* IRQ5 */
+#define TSI148_LCSR_INTEO_IRQ4EO (1<<4) /* IRQ4 */
+#define TSI148_LCSR_INTEO_IRQ3EO (1<<3) /* IRQ3 */
+#define TSI148_LCSR_INTEO_IRQ2EO (1<<2) /* IRQ2 */
+#define TSI148_LCSR_INTEO_IRQ1EO (1<<1) /* IRQ1 */
+
+static const int TSI148_LCSR_INTEO_LMEO[4] = { TSI148_LCSR_INTEO_LM0EO,
+ TSI148_LCSR_INTEO_LM1EO,
+ TSI148_LCSR_INTEO_LM2EO,
+ TSI148_LCSR_INTEO_LM3EO };
+
+static const int TSI148_LCSR_INTEO_IRQEO[7] = { TSI148_LCSR_INTEO_IRQ1EO,
+ TSI148_LCSR_INTEO_IRQ2EO,
+ TSI148_LCSR_INTEO_IRQ3EO,
+ TSI148_LCSR_INTEO_IRQ4EO,
+ TSI148_LCSR_INTEO_IRQ5EO,
+ TSI148_LCSR_INTEO_IRQ6EO,
+ TSI148_LCSR_INTEO_IRQ7EO };
+
+/*
+ * Interrupt Status Register CRG + $448
+ */
+#define TSI148_LCSR_INTS_DMA1S (1<<25) /* DMA 1 */
+#define TSI148_LCSR_INTS_DMA0S (1<<24) /* DMA 0 */
+#define TSI148_LCSR_INTS_LM3S (1<<23) /* Location Monitor 3 */
+#define TSI148_LCSR_INTS_LM2S (1<<22) /* Location Monitor 2 */
+#define TSI148_LCSR_INTS_LM1S (1<<21) /* Location Monitor 1 */
+#define TSI148_LCSR_INTS_LM0S (1<<20) /* Location Monitor 0 */
+#define TSI148_LCSR_INTS_MB3S (1<<19) /* Mail Box 3 */
+#define TSI148_LCSR_INTS_MB2S (1<<18) /* Mail Box 2 */
+#define TSI148_LCSR_INTS_MB1S (1<<17) /* Mail Box 1 */
+#define TSI148_LCSR_INTS_MB0S (1<<16) /* Mail Box 0 */
+#define TSI148_LCSR_INTS_PERRS (1<<13) /* PCI/X Error */
+#define TSI148_LCSR_INTS_VERRS (1<<12) /* VMEbus Error */
+#define TSI148_LCSR_INTS_VIES (1<<11) /* VMEbus IRQ Edge */
+#define TSI148_LCSR_INTS_IACKS (1<<10) /* IACK */
+#define TSI148_LCSR_INTS_SYSFLS (1<<9) /* System Fail */
+#define TSI148_LCSR_INTS_ACFLS (1<<8) /* AC Fail */
+#define TSI148_LCSR_INTS_IRQ7S (1<<7) /* IRQ7 */
+#define TSI148_LCSR_INTS_IRQ6S (1<<6) /* IRQ6 */
+#define TSI148_LCSR_INTS_IRQ5S (1<<5) /* IRQ5 */
+#define TSI148_LCSR_INTS_IRQ4S (1<<4) /* IRQ4 */
+#define TSI148_LCSR_INTS_IRQ3S (1<<3) /* IRQ3 */
+#define TSI148_LCSR_INTS_IRQ2S (1<<2) /* IRQ2 */
+#define TSI148_LCSR_INTS_IRQ1S (1<<1) /* IRQ1 */
+
+static const int TSI148_LCSR_INTS_LMS[4] = { TSI148_LCSR_INTS_LM0S,
+ TSI148_LCSR_INTS_LM1S,
+ TSI148_LCSR_INTS_LM2S,
+ TSI148_LCSR_INTS_LM3S };
+
+static const int TSI148_LCSR_INTS_MBS[4] = { TSI148_LCSR_INTS_MB0S,
+ TSI148_LCSR_INTS_MB1S,
+ TSI148_LCSR_INTS_MB2S,
+ TSI148_LCSR_INTS_MB3S };
+
+/*
+ * Interrupt Clear Register CRG + $44C
+ */
+#define TSI148_LCSR_INTC_DMA1C (1<<25) /* DMA 1 */
+#define TSI148_LCSR_INTC_DMA0C (1<<24) /* DMA 0 */
+#define TSI148_LCSR_INTC_LM3C (1<<23) /* Location Monitor 3 */
+#define TSI148_LCSR_INTC_LM2C (1<<22) /* Location Monitor 2 */
+#define TSI148_LCSR_INTC_LM1C (1<<21) /* Location Monitor 1 */
+#define TSI148_LCSR_INTC_LM0C (1<<20) /* Location Monitor 0 */
+#define TSI148_LCSR_INTC_MB3C (1<<19) /* Mail Box 3 */
+#define TSI148_LCSR_INTC_MB2C (1<<18) /* Mail Box 2 */
+#define TSI148_LCSR_INTC_MB1C (1<<17) /* Mail Box 1 */
+#define TSI148_LCSR_INTC_MB0C (1<<16) /* Mail Box 0 */
+#define TSI148_LCSR_INTC_PERRC (1<<13) /* VMEbus Error */
+#define TSI148_LCSR_INTC_VERRC (1<<12) /* VMEbus Access Time-out */
+#define TSI148_LCSR_INTC_VIEC (1<<11) /* VMEbus IRQ Edge */
+#define TSI148_LCSR_INTC_IACKC (1<<10) /* IACK */
+#define TSI148_LCSR_INTC_SYSFLC (1<<9) /* System Fail */
+#define TSI148_LCSR_INTC_ACFLC (1<<8) /* AC Fail */
+
+static const int TSI148_LCSR_INTC_LMC[4] = { TSI148_LCSR_INTC_LM0C,
+ TSI148_LCSR_INTC_LM1C,
+ TSI148_LCSR_INTC_LM2C,
+ TSI148_LCSR_INTC_LM3C };
+
+static const int TSI148_LCSR_INTC_MBC[4] = { TSI148_LCSR_INTC_MB0C,
+ TSI148_LCSR_INTC_MB1C,
+ TSI148_LCSR_INTC_MB2C,
+ TSI148_LCSR_INTC_MB3C };
+
+/*
+ * Interrupt Map Register 1 CRG + $458
+ */
+#define TSI148_LCSR_INTM1_DMA1M_M (3<<18) /* DMA 1 */
+#define TSI148_LCSR_INTM1_DMA0M_M (3<<16) /* DMA 0 */
+#define TSI148_LCSR_INTM1_LM3M_M (3<<14) /* Location Monitor 3 */
+#define TSI148_LCSR_INTM1_LM2M_M (3<<12) /* Location Monitor 2 */
+#define TSI148_LCSR_INTM1_LM1M_M (3<<10) /* Location Monitor 1 */
+#define TSI148_LCSR_INTM1_LM0M_M (3<<8) /* Location Monitor 0 */
+#define TSI148_LCSR_INTM1_MB3M_M (3<<6) /* Mail Box 3 */
+#define TSI148_LCSR_INTM1_MB2M_M (3<<4) /* Mail Box 2 */
+#define TSI148_LCSR_INTM1_MB1M_M (3<<2) /* Mail Box 1 */
+#define TSI148_LCSR_INTM1_MB0M_M (3<<0) /* Mail Box 0 */
+
+/*
+ * Interrupt Map Register 2 CRG + $45C
+ */
+#define TSI148_LCSR_INTM2_PERRM_M (3<<26) /* PCI Bus Error */
+#define TSI148_LCSR_INTM2_VERRM_M (3<<24) /* VMEbus Error */
+#define TSI148_LCSR_INTM2_VIEM_M (3<<22) /* VMEbus IRQ Edge */
+#define TSI148_LCSR_INTM2_IACKM_M (3<<20) /* IACK */
+#define TSI148_LCSR_INTM2_SYSFLM_M (3<<18) /* System Fail */
+#define TSI148_LCSR_INTM2_ACFLM_M (3<<16) /* AC Fail */
+#define TSI148_LCSR_INTM2_IRQ7M_M (3<<14) /* IRQ7 */
+#define TSI148_LCSR_INTM2_IRQ6M_M (3<<12) /* IRQ6 */
+#define TSI148_LCSR_INTM2_IRQ5M_M (3<<10) /* IRQ5 */
+#define TSI148_LCSR_INTM2_IRQ4M_M (3<<8) /* IRQ4 */
+#define TSI148_LCSR_INTM2_IRQ3M_M (3<<6) /* IRQ3 */
+#define TSI148_LCSR_INTM2_IRQ2M_M (3<<4) /* IRQ2 */
+#define TSI148_LCSR_INTM2_IRQ1M_M (3<<2) /* IRQ1 */
+
+/*
+ * DMA Control (0-1) Registers CRG + $500
+ */
+#define TSI148_LCSR_DCTL_ABT (1<<27) /* Abort */
+#define TSI148_LCSR_DCTL_PAU (1<<26) /* Pause */
+#define TSI148_LCSR_DCTL_DGO (1<<25) /* DMA Go */
+
+#define TSI148_LCSR_DCTL_MOD (1<<23) /* Mode */
+
+#define TSI148_LCSR_DCTL_VBKS_M (7<<12) /* VMEbus block Size MASK */
+#define TSI148_LCSR_DCTL_VBKS_32 (0<<12) /* VMEbus block Size 32 */
+#define TSI148_LCSR_DCTL_VBKS_64 (1<<12) /* VMEbus block Size 64 */
+#define TSI148_LCSR_DCTL_VBKS_128 (2<<12) /* VMEbus block Size 128 */
+#define TSI148_LCSR_DCTL_VBKS_256 (3<<12) /* VMEbus block Size 256 */
+#define TSI148_LCSR_DCTL_VBKS_512 (4<<12) /* VMEbus block Size 512 */
+#define TSI148_LCSR_DCTL_VBKS_1024 (5<<12) /* VMEbus block Size 1024 */
+#define TSI148_LCSR_DCTL_VBKS_2048 (6<<12) /* VMEbus block Size 2048 */
+#define TSI148_LCSR_DCTL_VBKS_4096 (7<<12) /* VMEbus block Size 4096 */
+
+#define TSI148_LCSR_DCTL_VBOT_M (7<<8) /* VMEbus back-off MASK */
+#define TSI148_LCSR_DCTL_VBOT_0 (0<<8) /* VMEbus back-off 0us */
+#define TSI148_LCSR_DCTL_VBOT_1 (1<<8) /* VMEbus back-off 1us */
+#define TSI148_LCSR_DCTL_VBOT_2 (2<<8) /* VMEbus back-off 2us */
+#define TSI148_LCSR_DCTL_VBOT_4 (3<<8) /* VMEbus back-off 4us */
+#define TSI148_LCSR_DCTL_VBOT_8 (4<<8) /* VMEbus back-off 8us */
+#define TSI148_LCSR_DCTL_VBOT_16 (5<<8) /* VMEbus back-off 16us */
+#define TSI148_LCSR_DCTL_VBOT_32 (6<<8) /* VMEbus back-off 32us */
+#define TSI148_LCSR_DCTL_VBOT_64 (7<<8) /* VMEbus back-off 64us */
+
+#define TSI148_LCSR_DCTL_PBKS_M (7<<4) /* PCI block size MASK */
+#define TSI148_LCSR_DCTL_PBKS_32 (0<<4) /* PCI block size 32 bytes */
+#define TSI148_LCSR_DCTL_PBKS_64 (1<<4) /* PCI block size 64 bytes */
+#define TSI148_LCSR_DCTL_PBKS_128 (2<<4) /* PCI block size 128 bytes */
+#define TSI148_LCSR_DCTL_PBKS_256 (3<<4) /* PCI block size 256 bytes */
+#define TSI148_LCSR_DCTL_PBKS_512 (4<<4) /* PCI block size 512 bytes */
+#define TSI148_LCSR_DCTL_PBKS_1024 (5<<4) /* PCI block size 1024 bytes */
+#define TSI148_LCSR_DCTL_PBKS_2048 (6<<4) /* PCI block size 2048 bytes */
+#define TSI148_LCSR_DCTL_PBKS_4096 (7<<4) /* PCI block size 4096 bytes */
+
+#define TSI148_LCSR_DCTL_PBOT_M (7<<0) /* PCI back off MASK */
+#define TSI148_LCSR_DCTL_PBOT_0 (0<<0) /* PCI back off 0us */
+#define TSI148_LCSR_DCTL_PBOT_1 (1<<0) /* PCI back off 1us */
+#define TSI148_LCSR_DCTL_PBOT_2 (2<<0) /* PCI back off 2us */
+#define TSI148_LCSR_DCTL_PBOT_4 (3<<0) /* PCI back off 3us */
+#define TSI148_LCSR_DCTL_PBOT_8 (4<<0) /* PCI back off 4us */
+#define TSI148_LCSR_DCTL_PBOT_16 (5<<0) /* PCI back off 8us */
+#define TSI148_LCSR_DCTL_PBOT_32 (6<<0) /* PCI back off 16us */
+#define TSI148_LCSR_DCTL_PBOT_64 (7<<0) /* PCI back off 32us */
+
+/*
+ * DMA Status Registers (0-1) CRG + $504
+ */
+#define TSI148_LCSR_DSTA_SMA (1<<31) /* PCI Signalled Master Abt */
+#define TSI148_LCSR_DSTA_RTA (1<<30) /* PCI Received Target Abt */
+#define TSI148_LCSR_DSTA_MRC (1<<29) /* PCI Max Retry Count */
+#define TSI148_LCSR_DSTA_VBE (1<<28) /* VMEbus error */
+#define TSI148_LCSR_DSTA_ABT (1<<27) /* Abort */
+#define TSI148_LCSR_DSTA_PAU (1<<26) /* Pause */
+#define TSI148_LCSR_DSTA_DON (1<<25) /* Done */
+#define TSI148_LCSR_DSTA_BSY (1<<24) /* Busy */
+
+/*
+ * DMA Current Link Address Lower (0-1)
+ */
+#define TSI148_LCSR_DCLAL_M (0x3FFFFFF<<6) /* Mask */
+
+/*
+ * DMA Source Attribute (0-1) Reg
+ */
+#define TSI148_LCSR_DSAT_TYP_M (3<<28) /* Source Bus Type */
+#define TSI148_LCSR_DSAT_TYP_PCI (0<<28) /* PCI Bus */
+#define TSI148_LCSR_DSAT_TYP_VME (1<<28) /* VMEbus */
+#define TSI148_LCSR_DSAT_TYP_PAT (2<<28) /* Data Pattern */
+
+#define TSI148_LCSR_DSAT_PSZ (1<<25) /* Pattern Size */
+#define TSI148_LCSR_DSAT_NIN (1<<24) /* No Increment */
+
+#define TSI148_LCSR_DSAT_2eSSTM_M (3<<11) /* 2eSST Trans Rate Mask */
+#define TSI148_LCSR_DSAT_2eSSTM_160 (0<<11) /* 160 MB/s */
+#define TSI148_LCSR_DSAT_2eSSTM_267 (1<<11) /* 267 MB/s */
+#define TSI148_LCSR_DSAT_2eSSTM_320 (2<<11) /* 320 MB/s */
+
+#define TSI148_LCSR_DSAT_TM_M (7<<8) /* Bus Transfer Protocol Mask */
+#define TSI148_LCSR_DSAT_TM_SCT (0<<8) /* SCT */
+#define TSI148_LCSR_DSAT_TM_BLT (1<<8) /* BLT */
+#define TSI148_LCSR_DSAT_TM_MBLT (2<<8) /* MBLT */
+#define TSI148_LCSR_DSAT_TM_2eVME (3<<8) /* 2eVME */
+#define TSI148_LCSR_DSAT_TM_2eSST (4<<8) /* 2eSST */
+#define TSI148_LCSR_DSAT_TM_2eSSTB (5<<8) /* 2eSST Broadcast */
+
+#define TSI148_LCSR_DSAT_DBW_M (3<<6) /* Max Data Width MASK */
+#define TSI148_LCSR_DSAT_DBW_16 (0<<6) /* 16 Bits */
+#define TSI148_LCSR_DSAT_DBW_32 (1<<6) /* 32 Bits */
+
+#define TSI148_LCSR_DSAT_SUP (1<<5) /* Supervisory Mode */
+#define TSI148_LCSR_DSAT_PGM (1<<4) /* Program Mode */
+
+#define TSI148_LCSR_DSAT_AMODE_M (0xf<<0) /* Address Space Mask */
+#define TSI148_LCSR_DSAT_AMODE_A16 (0<<0) /* A16 */
+#define TSI148_LCSR_DSAT_AMODE_A24 (1<<0) /* A24 */
+#define TSI148_LCSR_DSAT_AMODE_A32 (2<<0) /* A32 */
+#define TSI148_LCSR_DSAT_AMODE_A64 (4<<0) /* A64 */
+#define TSI148_LCSR_DSAT_AMODE_CRCSR (5<<0) /* CR/CSR */
+#define TSI148_LCSR_DSAT_AMODE_USER1 (8<<0) /* User1 */
+#define TSI148_LCSR_DSAT_AMODE_USER2 (9<<0) /* User2 */
+#define TSI148_LCSR_DSAT_AMODE_USER3 (0xa<<0) /* User3 */
+#define TSI148_LCSR_DSAT_AMODE_USER4 (0xb<<0) /* User4 */
+
+/*
+ * DMA Destination Attribute Registers (0-1)
+ */
+#define TSI148_LCSR_DDAT_TYP_PCI (0<<28) /* Destination PCI Bus */
+#define TSI148_LCSR_DDAT_TYP_VME (1<<28) /* Destination VMEbus */
+
+#define TSI148_LCSR_DDAT_2eSSTM_M (3<<11) /* 2eSST Transfer Rate Mask */
+#define TSI148_LCSR_DDAT_2eSSTM_160 (0<<11) /* 160 MB/s */
+#define TSI148_LCSR_DDAT_2eSSTM_267 (1<<11) /* 267 MB/s */
+#define TSI148_LCSR_DDAT_2eSSTM_320 (2<<11) /* 320 MB/s */
+
+#define TSI148_LCSR_DDAT_TM_M (7<<8) /* Bus Transfer Protocol Mask */
+#define TSI148_LCSR_DDAT_TM_SCT (0<<8) /* SCT */
+#define TSI148_LCSR_DDAT_TM_BLT (1<<8) /* BLT */
+#define TSI148_LCSR_DDAT_TM_MBLT (2<<8) /* MBLT */
+#define TSI148_LCSR_DDAT_TM_2eVME (3<<8) /* 2eVME */
+#define TSI148_LCSR_DDAT_TM_2eSST (4<<8) /* 2eSST */
+#define TSI148_LCSR_DDAT_TM_2eSSTB (5<<8) /* 2eSST Broadcast */
+
+#define TSI148_LCSR_DDAT_DBW_M (3<<6) /* Max Data Width MASK */
+#define TSI148_LCSR_DDAT_DBW_16 (0<<6) /* 16 Bits */
+#define TSI148_LCSR_DDAT_DBW_32 (1<<6) /* 32 Bits */
+
+#define TSI148_LCSR_DDAT_SUP (1<<5) /* Supervisory/User Access */
+#define TSI148_LCSR_DDAT_PGM (1<<4) /* Program/Data Access */
+
+#define TSI148_LCSR_DDAT_AMODE_M (0xf<<0) /* Address Space Mask */
+#define TSI148_LCSR_DDAT_AMODE_A16 (0<<0) /* A16 */
+#define TSI148_LCSR_DDAT_AMODE_A24 (1<<0) /* A24 */
+#define TSI148_LCSR_DDAT_AMODE_A32 (2<<0) /* A32 */
+#define TSI148_LCSR_DDAT_AMODE_A64 (4<<0) /* A64 */
+#define TSI148_LCSR_DDAT_AMODE_CRCSR (5<<0) /* CRC/SR */
+#define TSI148_LCSR_DDAT_AMODE_USER1 (8<<0) /* User1 */
+#define TSI148_LCSR_DDAT_AMODE_USER2 (9<<0) /* User2 */
+#define TSI148_LCSR_DDAT_AMODE_USER3 (0xa<<0) /* User3 */
+#define TSI148_LCSR_DDAT_AMODE_USER4 (0xb<<0) /* User4 */
+
+/*
+ * DMA Next Link Address Lower
+ */
+#define TSI148_LCSR_DNLAL_DNLAL_M (0x3FFFFFF<<6) /* Address Mask */
+#define TSI148_LCSR_DNLAL_LLA (1<<0) /* Last Link Address Indicator */
+
+/*
+ * DMA 2eSST Broadcast Select
+ */
+#define TSI148_LCSR_DBS_M (0x1FFFFF<<0) /* Mask */
+
+/*
+ * GCSR Register Group
+ */
+
+/*
+ * GCSR Control and Status Register CRG + $604
+ */
+#define TSI148_GCSR_GCTRL_LRST (1<<15) /* Local Reset */
+#define TSI148_GCSR_GCTRL_SFAILEN (1<<14) /* System Fail enable */
+#define TSI148_GCSR_GCTRL_BDFAILS (1<<13) /* Board Fail Status */
+#define TSI148_GCSR_GCTRL_SCON (1<<12) /* System Copntroller */
+#define TSI148_GCSR_GCTRL_MEN (1<<11) /* Module Enable (READY) */
+
+#define TSI148_GCSR_GCTRL_LMI3S (1<<7) /* Loc Monitor 3 Int Status */
+#define TSI148_GCSR_GCTRL_LMI2S (1<<6) /* Loc Monitor 2 Int Status */
+#define TSI148_GCSR_GCTRL_LMI1S (1<<5) /* Loc Monitor 1 Int Status */
+#define TSI148_GCSR_GCTRL_LMI0S (1<<4) /* Loc Monitor 0 Int Status */
+#define TSI148_GCSR_GCTRL_MBI3S (1<<3) /* Mail box 3 Int Status */
+#define TSI148_GCSR_GCTRL_MBI2S (1<<2) /* Mail box 2 Int Status */
+#define TSI148_GCSR_GCTRL_MBI1S (1<<1) /* Mail box 1 Int Status */
+#define TSI148_GCSR_GCTRL_MBI0S (1<<0) /* Mail box 0 Int Status */
+
+#define TSI148_GCSR_GAP (1<<5) /* Geographic Addr Parity */
+#define TSI148_GCSR_GA_M (0x1F<<0) /* Geographic Address Mask */
+
+/*
+ * CR/CSR Register Group
+ */
+
+/*
+ * CR/CSR Bit Clear Register CRG + $FF4
+ */
+#define TSI148_CRCSR_CSRBCR_LRSTC (1<<7) /* Local Reset Clear */
+#define TSI148_CRCSR_CSRBCR_SFAILC (1<<6) /* System Fail Enable Clear */
+#define TSI148_CRCSR_CSRBCR_BDFAILS (1<<5) /* Board Fail Status */
+#define TSI148_CRCSR_CSRBCR_MENC (1<<4) /* Module Enable Clear */
+#define TSI148_CRCSR_CSRBCR_BERRSC (1<<3) /* Bus Error Status Clear */
+
+/*
+ * CR/CSR Bit Set Register CRG+$FF8
+ */
+#define TSI148_CRCSR_CSRBSR_LISTS (1<<7) /* Local Reset Clear */
+#define TSI148_CRCSR_CSRBSR_SFAILS (1<<6) /* System Fail Enable Clear */
+#define TSI148_CRCSR_CSRBSR_BDFAILS (1<<5) /* Board Fail Status */
+#define TSI148_CRCSR_CSRBSR_MENS (1<<4) /* Module Enable Clear */
+#define TSI148_CRCSR_CSRBSR_BERRS (1<<3) /* Bus Error Status Clear */
+
+/*
+ * CR/CSR Base Address Register CRG + FFC
+ */
+#define TSI148_CRCSR_CBAR_M (0x1F<<3) /* Mask */
+
+#endif /* TSI148_H */
diff --git a/drivers/staging/vme_user/vme_user.c b/drivers/staging/vme_user/vme_user.c
index 859af797630c..4e533c0bfe6d 100644
--- a/drivers/staging/vme_user/vme_user.c
+++ b/drivers/staging/vme_user/vme_user.c
@@ -33,8 +33,8 @@
#include <linux/io.h>
#include <linux/uaccess.h>
-#include <linux/vme.h>
+#include "vme.h"
#include "vme_user.h"
static const char driver_name[] = "vme_user";
diff --git a/drivers/staging/vt6655/baseband.c b/drivers/staging/vt6655/baseband.c
index 577a38fae369..5de841cb776c 100644
--- a/drivers/staging/vt6655/baseband.c
+++ b/drivers/staging/vt6655/baseband.c
@@ -1912,7 +1912,7 @@ bool bb_read_embedded(struct vnt_private *priv, unsigned char by_bb_addr,
iowrite8(by_bb_addr, iobase + MAC_REG_BBREGADR);
/* turn on REGR */
- MACvRegBitsOn(iobase, MAC_REG_BBREGCTL, BBREGCTL_REGR);
+ vt6655_mac_reg_bits_on(iobase, MAC_REG_BBREGCTL, BBREGCTL_REGR);
/* W_MAX_TIMEOUT is the timeout period */
for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
by_value = ioread8(iobase + MAC_REG_BBREGCTL);
@@ -1957,7 +1957,7 @@ bool bb_write_embedded(struct vnt_private *priv, unsigned char by_bb_addr,
iowrite8(by_data, iobase + MAC_REG_BBREGDATA);
/* turn on BBREGCTL_REGW */
- MACvRegBitsOn(iobase, MAC_REG_BBREGCTL, BBREGCTL_REGW);
+ vt6655_mac_reg_bits_on(iobase, MAC_REG_BBREGCTL, BBREGCTL_REGW);
/* W_MAX_TIMEOUT is the timeout period */
for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
by_value = ioread8(iobase + MAC_REG_BBREGCTL);
@@ -2013,8 +2013,8 @@ bool bb_vt3253_init(struct vnt_private *priv)
byVT3253B0_AGC4_RFMD2959[ii][0],
byVT3253B0_AGC4_RFMD2959[ii][1]);
- VNSvOutPortD(iobase + MAC_REG_ITRTMSET, 0x23);
- MACvRegBitsOn(iobase, MAC_REG_PAPEDELAY, BIT(0));
+ iowrite32(0x23, iobase + MAC_REG_ITRTMSET);
+ vt6655_mac_reg_bits_on(iobase, MAC_REG_PAPEDELAY, BIT(0));
}
priv->abyBBVGA[0] = 0x18;
priv->abyBBVGA[1] = 0x0A;
@@ -2054,7 +2054,7 @@ bool bb_vt3253_init(struct vnt_private *priv)
byVT3253B0_AGC[ii][1]);
iowrite8(0x23, iobase + MAC_REG_ITRTMSET);
- MACvRegBitsOn(iobase, MAC_REG_PAPEDELAY, BIT(0));
+ vt6655_mac_reg_bits_on(iobase, MAC_REG_PAPEDELAY, BIT(0));
priv->abyBBVGA[0] = 0x14;
priv->abyBBVGA[1] = 0x0A;
diff --git a/drivers/staging/vt6655/card.c b/drivers/staging/vt6655/card.c
index 2cde0082fc03..846469cc06bb 100644
--- a/drivers/staging/vt6655/card.c
+++ b/drivers/staging/vt6655/card.c
@@ -293,12 +293,10 @@ bool CARDbUpdateTSF(struct vnt_private *priv, unsigned char byRxRate,
qwTSFOffset = CARDqGetTSFOffset(byRxRate, qwBSSTimestamp,
local_tsf);
/* adjust TSF, HW's TSF add TSF Offset reg */
- VNSvOutPortD(priv->port_offset + MAC_REG_TSFOFST,
- (u32)qwTSFOffset);
- VNSvOutPortD(priv->port_offset + MAC_REG_TSFOFST + 4,
- (u32)(qwTSFOffset >> 32));
- MACvRegBitsOn(priv->port_offset, MAC_REG_TFTCTL,
- TFTCTL_TSFSYNCEN);
+ qwTSFOffset = le64_to_cpu(qwTSFOffset);
+ iowrite32((u32)qwTSFOffset, priv->port_offset + MAC_REG_TSFOFST);
+ iowrite32((u32)(qwTSFOffset >> 32), priv->port_offset + MAC_REG_TSFOFST + 4);
+ vt6655_mac_reg_bits_on(priv->port_offset, MAC_REG_TFTCTL, TFTCTL_TSFSYNCEN);
}
return true;
}
@@ -326,13 +324,13 @@ bool CARDbSetBeaconPeriod(struct vnt_private *priv,
qwNextTBTT = CARDqGetNextTBTT(qwNextTBTT, wBeaconInterval);
/* set HW beacon interval */
- VNSvOutPortW(priv->port_offset + MAC_REG_BI, wBeaconInterval);
+ iowrite16(wBeaconInterval, priv->port_offset + MAC_REG_BI);
priv->wBeaconInterval = wBeaconInterval;
/* Set NextTBTT */
- VNSvOutPortD(priv->port_offset + MAC_REG_NEXTTBTT, (u32)qwNextTBTT);
- VNSvOutPortD(priv->port_offset + MAC_REG_NEXTTBTT + 4,
- (u32)(qwNextTBTT >> 32));
- MACvRegBitsOn(priv->port_offset, MAC_REG_TFTCTL, TFTCTL_TBTTSYNCEN);
+ qwNextTBTT = le64_to_cpu(qwNextTBTT);
+ iowrite32((u32)qwNextTBTT, priv->port_offset + MAC_REG_NEXTTBTT);
+ iowrite32((u32)(qwNextTBTT >> 32), priv->port_offset + MAC_REG_NEXTTBTT + 4);
+ vt6655_mac_reg_bits_on(priv->port_offset, MAC_REG_TFTCTL, TFTCTL_TBTTSYNCEN);
return true;
}
@@ -354,29 +352,28 @@ void CARDbRadioPowerOff(struct vnt_private *priv)
switch (priv->byRFType) {
case RF_RFMD2959:
- MACvWordRegBitsOff(priv->port_offset, MAC_REG_SOFTPWRCTL,
- SOFTPWRCTL_TXPEINV);
- MACvWordRegBitsOn(priv->port_offset, MAC_REG_SOFTPWRCTL,
- SOFTPWRCTL_SWPE1);
+ vt6655_mac_word_reg_bits_off(priv->port_offset, MAC_REG_SOFTPWRCTL,
+ SOFTPWRCTL_TXPEINV);
+ vt6655_mac_word_reg_bits_on(priv->port_offset, MAC_REG_SOFTPWRCTL,
+ SOFTPWRCTL_SWPE1);
break;
case RF_AIROHA:
case RF_AL2230S:
- MACvWordRegBitsOff(priv->port_offset, MAC_REG_SOFTPWRCTL,
- SOFTPWRCTL_SWPE2);
- MACvWordRegBitsOff(priv->port_offset, MAC_REG_SOFTPWRCTL,
- SOFTPWRCTL_SWPE3);
+ vt6655_mac_word_reg_bits_off(priv->port_offset, MAC_REG_SOFTPWRCTL,
+ SOFTPWRCTL_SWPE2);
+ vt6655_mac_word_reg_bits_off(priv->port_offset, MAC_REG_SOFTPWRCTL,
+ SOFTPWRCTL_SWPE3);
break;
}
- MACvRegBitsOff(priv->port_offset, MAC_REG_HOSTCR, HOSTCR_RXON);
+ vt6655_mac_reg_bits_off(priv->port_offset, MAC_REG_HOSTCR, HOSTCR_RXON);
bb_set_deep_sleep(priv, priv->local_id);
priv->radio_off = true;
pr_debug("chester power off\n");
- MACvRegBitsOn(priv->port_offset, MAC_REG_GPIOCTL0,
- LED_ACTSET); /* LED issue */
+ vt6655_mac_reg_bits_on(priv->port_offset, MAC_REG_GPIOCTL0, LED_ACTSET); /* LED issue */
}
void CARDvSafeResetTx(struct vnt_private *priv)
@@ -411,8 +408,7 @@ void CARDvSafeResetTx(struct vnt_private *priv)
MACvSetCurrTXDescAddr(TYPE_AC0DMA, priv, priv->td1_pool_dma);
/* set MAC Beacon TX pointer */
- MACvSetCurrBCNTxDescAddr(priv->port_offset,
- (priv->tx_beacon_dma));
+ iowrite32((u32)priv->tx_beacon_dma, priv->port_offset + MAC_REG_BCNDMAPTR);
}
/*
@@ -453,8 +449,8 @@ void CARDvSafeResetRx(struct vnt_private *priv)
}
/* set perPkt mode */
- MACvRx0PerPktMode(priv->port_offset);
- MACvRx1PerPktMode(priv->port_offset);
+ iowrite32(RX_PERPKT, priv->port_offset + MAC_REG_RXDMACTL0);
+ iowrite32(RX_PERPKT, priv->port_offset + MAC_REG_RXDMACTL1);
/* set MAC RD pointer */
MACvSetCurrRx0DescAddr(priv, priv->rd0_pool_dma);
@@ -553,7 +549,7 @@ void CARDvSetRSPINF(struct vnt_private *priv, u8 bb_type)
/* swap over to get correct write order */
swap(phy.swap[0], phy.swap[1]);
- VNSvOutPortD(priv->port_offset + MAC_REG_RSPINF_B_1, phy.field_write);
+ iowrite32(phy.field_write, priv->port_offset + MAC_REG_RSPINF_B_1);
/* RSPINF_b_2 */
vnt_get_phy_field(priv, 14,
@@ -562,7 +558,7 @@ void CARDvSetRSPINF(struct vnt_private *priv, u8 bb_type)
swap(phy.swap[0], phy.swap[1]);
- VNSvOutPortD(priv->port_offset + MAC_REG_RSPINF_B_2, phy.field_write);
+ iowrite32(phy.field_write, priv->port_offset + MAC_REG_RSPINF_B_2);
/* RSPINF_b_5 */
vnt_get_phy_field(priv, 14,
@@ -571,7 +567,7 @@ void CARDvSetRSPINF(struct vnt_private *priv, u8 bb_type)
swap(phy.swap[0], phy.swap[1]);
- VNSvOutPortD(priv->port_offset + MAC_REG_RSPINF_B_5, phy.field_write);
+ iowrite32(phy.field_write, priv->port_offset + MAC_REG_RSPINF_B_5);
/* RSPINF_b_11 */
vnt_get_phy_field(priv, 14,
@@ -580,75 +576,66 @@ void CARDvSetRSPINF(struct vnt_private *priv, u8 bb_type)
swap(phy.swap[0], phy.swap[1]);
- VNSvOutPortD(priv->port_offset + MAC_REG_RSPINF_B_11, phy.field_write);
+ iowrite32(phy.field_write, priv->port_offset + MAC_REG_RSPINF_B_11);
/* RSPINF_a_6 */
s_vCalculateOFDMRParameter(RATE_6M,
bb_type,
&byTxRate,
&byRsvTime);
- VNSvOutPortW(priv->port_offset + MAC_REG_RSPINF_A_6,
- MAKEWORD(byTxRate, byRsvTime));
+ iowrite16(MAKEWORD(byTxRate, byRsvTime), priv->port_offset + MAC_REG_RSPINF_A_6);
/* RSPINF_a_9 */
s_vCalculateOFDMRParameter(RATE_9M,
bb_type,
&byTxRate,
&byRsvTime);
- VNSvOutPortW(priv->port_offset + MAC_REG_RSPINF_A_9,
- MAKEWORD(byTxRate, byRsvTime));
+ iowrite16(MAKEWORD(byTxRate, byRsvTime), priv->port_offset + MAC_REG_RSPINF_A_9);
/* RSPINF_a_12 */
s_vCalculateOFDMRParameter(RATE_12M,
bb_type,
&byTxRate,
&byRsvTime);
- VNSvOutPortW(priv->port_offset + MAC_REG_RSPINF_A_12,
- MAKEWORD(byTxRate, byRsvTime));
+ iowrite16(MAKEWORD(byTxRate, byRsvTime), priv->port_offset + MAC_REG_RSPINF_A_12);
/* RSPINF_a_18 */
s_vCalculateOFDMRParameter(RATE_18M,
bb_type,
&byTxRate,
&byRsvTime);
- VNSvOutPortW(priv->port_offset + MAC_REG_RSPINF_A_18,
- MAKEWORD(byTxRate, byRsvTime));
+ iowrite16(MAKEWORD(byTxRate, byRsvTime), priv->port_offset + MAC_REG_RSPINF_A_18);
/* RSPINF_a_24 */
s_vCalculateOFDMRParameter(RATE_24M,
bb_type,
&byTxRate,
&byRsvTime);
- VNSvOutPortW(priv->port_offset + MAC_REG_RSPINF_A_24,
- MAKEWORD(byTxRate, byRsvTime));
+ iowrite16(MAKEWORD(byTxRate, byRsvTime), priv->port_offset + MAC_REG_RSPINF_A_24);
/* RSPINF_a_36 */
s_vCalculateOFDMRParameter(CARDwGetOFDMControlRate((void *)priv,
RATE_36M),
bb_type,
&byTxRate,
&byRsvTime);
- VNSvOutPortW(priv->port_offset + MAC_REG_RSPINF_A_36,
- MAKEWORD(byTxRate, byRsvTime));
+ iowrite16(MAKEWORD(byTxRate, byRsvTime), priv->port_offset + MAC_REG_RSPINF_A_36);
/* RSPINF_a_48 */
s_vCalculateOFDMRParameter(CARDwGetOFDMControlRate((void *)priv,
RATE_48M),
bb_type,
&byTxRate,
&byRsvTime);
- VNSvOutPortW(priv->port_offset + MAC_REG_RSPINF_A_48,
- MAKEWORD(byTxRate, byRsvTime));
+ iowrite16(MAKEWORD(byTxRate, byRsvTime), priv->port_offset + MAC_REG_RSPINF_A_48);
/* RSPINF_a_54 */
s_vCalculateOFDMRParameter(CARDwGetOFDMControlRate((void *)priv,
RATE_54M),
bb_type,
&byTxRate,
&byRsvTime);
- VNSvOutPortW(priv->port_offset + MAC_REG_RSPINF_A_54,
- MAKEWORD(byTxRate, byRsvTime));
+ iowrite16(MAKEWORD(byTxRate, byRsvTime), priv->port_offset + MAC_REG_RSPINF_A_54);
/* RSPINF_a_72 */
s_vCalculateOFDMRParameter(CARDwGetOFDMControlRate((void *)priv,
RATE_54M),
bb_type,
&byTxRate,
&byRsvTime);
- VNSvOutPortW(priv->port_offset + MAC_REG_RSPINF_A_72,
- MAKEWORD(byTxRate, byRsvTime));
+ iowrite16(MAKEWORD(byTxRate, byRsvTime), priv->port_offset + MAC_REG_RSPINF_A_72);
/* Set to Page0 */
MACvSelectPage0(priv->port_offset);
@@ -734,9 +721,9 @@ u64 CARDqGetTSFOffset(unsigned char byRxRate, u64 qwTSF1, u64 qwTSF2)
* In:
* priv - The adapter to be read
* Out:
- * qwCurrTSF - Current TSF counter
+ * none
*
- * Return Value: true if success; otherwise false
+ * Return Value: Current TSF counter
*/
u64 vt6655_get_current_tsf(struct vnt_private *priv)
{
@@ -745,7 +732,7 @@ u64 vt6655_get_current_tsf(struct vnt_private *priv)
unsigned char data;
u32 low, high;
- MACvRegBitsOn(iobase, MAC_REG_TFTCTL, TFTCTL_TSFCNTRRD);
+ vt6655_mac_reg_bits_on(iobase, MAC_REG_TFTCTL, TFTCTL_TSFCNTRRD);
for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
data = ioread8(iobase + MAC_REG_TFTCTL);
if (!(data & TFTCTL_TSFCNTRRD))
@@ -808,9 +795,10 @@ void CARDvSetFirstNextTBTT(struct vnt_private *priv,
qwNextTBTT = CARDqGetNextTBTT(qwNextTBTT, wBeaconInterval);
/* Set NextTBTT */
- VNSvOutPortD(iobase + MAC_REG_NEXTTBTT, (u32)qwNextTBTT);
- VNSvOutPortD(iobase + MAC_REG_NEXTTBTT + 4, (u32)(qwNextTBTT >> 32));
- MACvRegBitsOn(iobase, MAC_REG_TFTCTL, TFTCTL_TBTTSYNCEN);
+ qwNextTBTT = le64_to_cpu(qwNextTBTT);
+ iowrite32((u32)qwNextTBTT, iobase + MAC_REG_NEXTTBTT);
+ iowrite32((u32)(qwNextTBTT >> 32), iobase + MAC_REG_NEXTTBTT + 4);
+ vt6655_mac_reg_bits_on(iobase, MAC_REG_TFTCTL, TFTCTL_TBTTSYNCEN);
}
/*
@@ -834,8 +822,9 @@ void CARDvUpdateNextTBTT(struct vnt_private *priv, u64 qwTSF,
qwTSF = CARDqGetNextTBTT(qwTSF, wBeaconInterval);
/* Set NextTBTT */
- VNSvOutPortD(iobase + MAC_REG_NEXTTBTT, (u32)qwTSF);
- VNSvOutPortD(iobase + MAC_REG_NEXTTBTT + 4, (u32)(qwTSF >> 32));
- MACvRegBitsOn(iobase, MAC_REG_TFTCTL, TFTCTL_TBTTSYNCEN);
+ qwTSF = le64_to_cpu(qwTSF);
+ iowrite32((u32)qwTSF, iobase + MAC_REG_NEXTTBTT);
+ iowrite32((u32)(qwTSF >> 32), iobase + MAC_REG_NEXTTBTT + 4);
+ vt6655_mac_reg_bits_on(iobase, MAC_REG_TFTCTL, TFTCTL_TBTTSYNCEN);
pr_debug("Card:Update Next TBTT[%8llx]\n", qwTSF);
}
diff --git a/drivers/staging/vt6655/channel.c b/drivers/staging/vt6655/channel.c
index 652dcaf61169..e926f9829a15 100644
--- a/drivers/staging/vt6655/channel.c
+++ b/drivers/staging/vt6655/channel.c
@@ -94,7 +94,7 @@ bool set_channel(struct vnt_private *priv, struct ieee80211_channel *ch)
}
/* clear NAV */
- MACvRegBitsOn(priv->port_offset, MAC_REG_MACCR, MACCR_CLRNAV);
+ vt6655_mac_reg_bits_on(priv->port_offset, MAC_REG_MACCR, MACCR_CLRNAV);
/* TX_PE will reserve 3 us for MAX2829 A mode only,
* it is for better TX throughput
diff --git a/drivers/staging/vt6655/device_main.c b/drivers/staging/vt6655/device_main.c
index e8ac7b93b58c..bab08a40fe66 100644
--- a/drivers/staging/vt6655/device_main.c
+++ b/drivers/staging/vt6655/device_main.c
@@ -122,6 +122,9 @@ static int vt6655_probe(struct pci_dev *pcid, const struct pci_device_id *ent);
static void device_free_info(struct vnt_private *priv);
static void device_print_info(struct vnt_private *priv);
+static void vt6655_mac_write_bssid_addr(void __iomem *iobase, const u8 *mac_addr);
+static void vt6655_mac_read_ether_addr(void __iomem *iobase, u8 *mac_addr);
+
static int device_init_rd0_ring(struct vnt_private *priv);
static int device_init_rd1_ring(struct vnt_private *priv);
static int device_init_td0_ring(struct vnt_private *priv);
@@ -186,6 +189,22 @@ device_set_options(struct vnt_private *priv)
pr_debug(" byBBType= %d\n", (int)priv->byBBType);
}
+static void vt6655_mac_write_bssid_addr(void __iomem *iobase, const u8 *mac_addr)
+{
+ iowrite8(1, iobase + MAC_REG_PAGE1SEL);
+ for (int i = 0; i < 6; i++)
+ iowrite8(mac_addr[i], iobase + MAC_REG_BSSID0 + i);
+ iowrite8(0, iobase + MAC_REG_PAGE1SEL);
+}
+
+static void vt6655_mac_read_ether_addr(void __iomem *iobase, u8 *mac_addr)
+{
+ iowrite8(1, iobase + MAC_REG_PAGE1SEL);
+ for (int i = 0; i < 6; i++)
+ mac_addr[i] = ioread8(iobase + MAC_REG_PAR0 + i);
+ iowrite8(0, iobase + MAC_REG_PAGE1SEL);
+}
+
/*
* Initialisation of MAC & BBP registers
*/
@@ -340,8 +359,8 @@ static void device_init_registers(struct vnt_private *priv)
}
/* use relative tx timeout and 802.11i D4 */
- MACvWordRegBitsOn(priv->port_offset,
- MAC_REG_CFG, (CFG_TKIPOPT | CFG_NOTXTIMEOUT));
+ vt6655_mac_word_reg_bits_on(priv->port_offset, MAC_REG_CFG,
+ (CFG_TKIPOPT | CFG_NOTXTIMEOUT));
/* set performance parameter by registry */
MACvSetShortRetryLimit(priv, priv->byShortRetryLimit);
@@ -398,7 +417,7 @@ static void device_init_registers(struct vnt_private *priv)
CARDvSafeResetTx(priv);
if (priv->local_id <= REV_ID_VT3253_A1)
- MACvRegBitsOn(priv->port_offset, MAC_REG_RCR, RCR_WPAERR);
+ vt6655_mac_reg_bits_on(priv->port_offset, MAC_REG_RCR, RCR_WPAERR);
/* Turn On Rx DMA */
MACvReceive0(priv->port_offset);
@@ -1055,13 +1074,12 @@ static void vnt_interrupt_process(struct vnt_private *priv)
* update ISR counter
*/
while (isr && priv->vif) {
- MACvWriteISR(priv->port_offset, isr);
+ iowrite32(isr, priv->port_offset + MAC_REG_ISR);
if (isr & ISR_FETALERR) {
pr_debug(" ISR_FETALERR\n");
iowrite8(0, priv->port_offset + MAC_REG_SOFTPWRCTL);
- VNSvOutPortW(priv->port_offset +
- MAC_REG_SOFTPWRCTL, SOFTPWRCTL_SWPECTI);
+ iowrite16(SOFTPWRCTL_SWPECTI, priv->port_offset + MAC_REG_SOFTPWRCTL);
device_error(priv, isr);
}
@@ -1135,7 +1153,7 @@ static void vnt_interrupt_work(struct work_struct *work)
if (priv->vif)
vnt_interrupt_process(priv);
- MACvIntEnable(priv->port_offset, IMR_MASK_VALUE);
+ iowrite32(IMR_MASK_VALUE, priv->port_offset + MAC_REG_IMR);
}
static irqreturn_t vnt_interrupt(int irq, void *arg)
@@ -1144,7 +1162,7 @@ static irqreturn_t vnt_interrupt(int irq, void *arg)
schedule_work(&priv->interrupt_work);
- MACvIntDisable(priv->port_offset);
+ iowrite32(0, priv->port_offset + MAC_REG_IMR);
return IRQ_HANDLED;
}
@@ -1253,8 +1271,8 @@ static int vnt_start(struct ieee80211_hw *hw)
device_init_registers(priv);
- dev_dbg(&priv->pcid->dev, "call MACvIntEnable\n");
- MACvIntEnable(priv->port_offset, IMR_MASK_VALUE);
+ dev_dbg(&priv->pcid->dev, "enable MAC interrupt\n");
+ iowrite32(IMR_MASK_VALUE, priv->port_offset + MAC_REG_IMR);
ieee80211_wake_queues(hw);
@@ -1304,15 +1322,15 @@ static int vnt_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
case NL80211_IFTYPE_STATION:
break;
case NL80211_IFTYPE_ADHOC:
- MACvRegBitsOff(priv->port_offset, MAC_REG_RCR, RCR_UNICAST);
+ vt6655_mac_reg_bits_off(priv->port_offset, MAC_REG_RCR, RCR_UNICAST);
- MACvRegBitsOn(priv->port_offset, MAC_REG_HOSTCR, HOSTCR_ADHOC);
+ vt6655_mac_reg_bits_on(priv->port_offset, MAC_REG_HOSTCR, HOSTCR_ADHOC);
break;
case NL80211_IFTYPE_AP:
- MACvRegBitsOff(priv->port_offset, MAC_REG_RCR, RCR_UNICAST);
+ vt6655_mac_reg_bits_off(priv->port_offset, MAC_REG_RCR, RCR_UNICAST);
- MACvRegBitsOn(priv->port_offset, MAC_REG_HOSTCR, HOSTCR_AP);
+ vt6655_mac_reg_bits_on(priv->port_offset, MAC_REG_HOSTCR, HOSTCR_AP);
break;
default:
@@ -1333,16 +1351,16 @@ static void vnt_remove_interface(struct ieee80211_hw *hw,
case NL80211_IFTYPE_STATION:
break;
case NL80211_IFTYPE_ADHOC:
- MACvRegBitsOff(priv->port_offset, MAC_REG_TCR, TCR_AUTOBCNTX);
- MACvRegBitsOff(priv->port_offset,
- MAC_REG_TFTCTL, TFTCTL_TSFCNTREN);
- MACvRegBitsOff(priv->port_offset, MAC_REG_HOSTCR, HOSTCR_ADHOC);
+ vt6655_mac_reg_bits_off(priv->port_offset, MAC_REG_TCR, TCR_AUTOBCNTX);
+ vt6655_mac_reg_bits_off(priv->port_offset,
+ MAC_REG_TFTCTL, TFTCTL_TSFCNTREN);
+ vt6655_mac_reg_bits_off(priv->port_offset, MAC_REG_HOSTCR, HOSTCR_ADHOC);
break;
case NL80211_IFTYPE_AP:
- MACvRegBitsOff(priv->port_offset, MAC_REG_TCR, TCR_AUTOBCNTX);
- MACvRegBitsOff(priv->port_offset,
- MAC_REG_TFTCTL, TFTCTL_TSFCNTREN);
- MACvRegBitsOff(priv->port_offset, MAC_REG_HOSTCR, HOSTCR_AP);
+ vt6655_mac_reg_bits_off(priv->port_offset, MAC_REG_TCR, TCR_AUTOBCNTX);
+ vt6655_mac_reg_bits_off(priv->port_offset,
+ MAC_REG_TFTCTL, TFTCTL_TSFCNTREN);
+ vt6655_mac_reg_bits_off(priv->port_offset, MAC_REG_HOSTCR, HOSTCR_AP);
break;
default:
break;
@@ -1406,7 +1424,7 @@ static void vnt_bss_info_changed(struct ieee80211_hw *hw,
spin_lock_irqsave(&priv->lock, flags);
- MACvWriteBSSIDAddress(priv->port_offset, conf->bssid);
+ vt6655_mac_write_bssid_addr(priv->port_offset, conf->bssid);
spin_unlock_irqrestore(&priv->lock, flags);
}
@@ -1458,11 +1476,10 @@ static void vnt_bss_info_changed(struct ieee80211_hw *hw,
if (conf->enable_beacon) {
vnt_beacon_enable(priv, vif, conf);
- MACvRegBitsOn(priv->port_offset, MAC_REG_TCR,
- TCR_AUTOBCNTX);
+ vt6655_mac_reg_bits_on(priv->port_offset, MAC_REG_TCR, TCR_AUTOBCNTX);
} else {
- MACvRegBitsOff(priv->port_offset, MAC_REG_TCR,
- TCR_AUTOBCNTX);
+ vt6655_mac_reg_bits_off(priv->port_offset, MAC_REG_TCR,
+ TCR_AUTOBCNTX);
}
}
@@ -1523,20 +1540,17 @@ static void vnt_configure(struct ieee80211_hw *hw,
if (priv->mc_list_count > 2) {
MACvSelectPage1(priv->port_offset);
- VNSvOutPortD(priv->port_offset +
- MAC_REG_MAR0, 0xffffffff);
- VNSvOutPortD(priv->port_offset +
- MAC_REG_MAR0 + 4, 0xffffffff);
+ iowrite32(0xffffffff, priv->port_offset + MAC_REG_MAR0);
+ iowrite32(0xffffffff, priv->port_offset + MAC_REG_MAR0 + 4);
MACvSelectPage0(priv->port_offset);
} else {
MACvSelectPage1(priv->port_offset);
- VNSvOutPortD(priv->port_offset +
- MAC_REG_MAR0, (u32)multicast);
- VNSvOutPortD(priv->port_offset +
- MAC_REG_MAR0 + 4,
- (u32)(multicast >> 32));
+ multicast = le64_to_cpu(multicast);
+ iowrite32((u32)multicast, priv->port_offset + MAC_REG_MAR0);
+ iowrite32((u32)(multicast >> 32),
+ priv->port_offset + MAC_REG_MAR0 + 4);
MACvSelectPage0(priv->port_offset);
}
@@ -1726,7 +1740,7 @@ vt6655_probe(struct pci_dev *pcid, const struct pci_device_id *ent)
}
/* initial to reload eeprom */
MACvInitialize(priv);
- MACvReadEtherAddress(priv->port_offset, priv->abyCurrentNetAddr);
+ vt6655_mac_read_ether_addr(priv->port_offset, priv->abyCurrentNetAddr);
/* Get RFType */
priv->byRFType = SROMbyReadEmbedded(priv->port_offset, EEP_OFS_RFTYPE);
diff --git a/drivers/staging/vt6655/mac.c b/drivers/staging/vt6655/mac.c
index 88ddd0676463..dcc649532737 100644
--- a/drivers/staging/vt6655/mac.c
+++ b/drivers/staging/vt6655/mac.c
@@ -38,6 +38,47 @@
#include "mac.h"
+void vt6655_mac_reg_bits_on(void __iomem *iobase, const u8 reg_offset, const u8 bit_mask)
+{
+ unsigned char reg_value;
+
+ reg_value = ioread8(iobase + reg_offset);
+ iowrite8(reg_value | bit_mask, iobase + reg_offset);
+}
+
+void vt6655_mac_word_reg_bits_on(void __iomem *iobase, const u8 reg_offset, const u16 bit_mask)
+{
+ unsigned short reg_value;
+
+ reg_value = ioread16(iobase + reg_offset);
+ iowrite16(reg_value | (bit_mask), iobase + reg_offset);
+}
+
+void vt6655_mac_reg_bits_off(void __iomem *iobase, const u8 reg_offset, const u8 bit_mask)
+{
+ unsigned char reg_value;
+
+ reg_value = ioread8(iobase + reg_offset);
+ iowrite8(reg_value & ~(bit_mask), iobase + reg_offset);
+}
+
+void vt6655_mac_word_reg_bits_off(void __iomem *iobase, const u8 reg_offset, const u16 bit_mask)
+{
+ unsigned short reg_value;
+
+ reg_value = ioread16(iobase + reg_offset);
+ iowrite16(reg_value & ~(bit_mask), iobase + reg_offset);
+}
+
+static void vt6655_mac_clear_stck_ds(void __iomem *iobase)
+{
+ u8 reg_value;
+
+ reg_value = ioread8(iobase + MAC_REG_STICKHW);
+ reg_value = reg_value & 0xFC;
+ iowrite8(reg_value, iobase + MAC_REG_STICKHW);
+}
+
/*
* Description:
* Test if all test bits off
@@ -337,7 +378,7 @@ bool MACbSafeRxOff(struct vnt_private *priv)
}
/* try to safe shutdown RX */
- MACvRegBitsOff(io_base, MAC_REG_HOSTCR, HOSTCR_RXON);
+ vt6655_mac_reg_bits_off(io_base, MAC_REG_HOSTCR, HOSTCR_RXON);
/* W_MAX_TIMEOUT is the timeout period */
for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
if (!(ioread8(io_base + MAC_REG_HOSTCR) & HOSTCR_RXONST))
@@ -392,7 +433,7 @@ bool MACbSafeTxOff(struct vnt_private *priv)
}
/* try to safe shutdown TX */
- MACvRegBitsOff(io_base, MAC_REG_HOSTCR, HOSTCR_TXON);
+ vt6655_mac_reg_bits_off(io_base, MAC_REG_HOSTCR, HOSTCR_TXON);
/* W_MAX_TIMEOUT is the timeout period */
for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
@@ -423,7 +464,7 @@ bool MACbSafeStop(struct vnt_private *priv)
{
void __iomem *io_base = priv->port_offset;
- MACvRegBitsOff(io_base, MAC_REG_TCR, TCR_AUTOBCNTX);
+ vt6655_mac_reg_bits_off(io_base, MAC_REG_TCR, TCR_AUTOBCNTX);
if (!MACbSafeRxOff(priv)) {
pr_debug(" MACbSafeRxOff == false)\n");
@@ -436,7 +477,7 @@ bool MACbSafeStop(struct vnt_private *priv)
return false;
}
- MACvRegBitsOff(io_base, MAC_REG_HOSTCR, HOSTCR_MACEN);
+ vt6655_mac_reg_bits_off(io_base, MAC_REG_HOSTCR, HOSTCR_MACEN);
return true;
}
@@ -458,7 +499,7 @@ bool MACbShutdown(struct vnt_private *priv)
{
void __iomem *io_base = priv->port_offset;
/* disable MAC IMR */
- MACvIntDisable(io_base);
+ iowrite32(0, io_base + MAC_REG_IMR);
MACvSetLoopbackMode(priv, MAC_LB_INTERNAL);
/* stop the adapter */
if (!MACbSafeStop(priv)) {
@@ -486,7 +527,7 @@ void MACvInitialize(struct vnt_private *priv)
{
void __iomem *io_base = priv->port_offset;
/* clear sticky bits */
- MACvClearStckDS(io_base);
+ vt6655_mac_clear_stck_ds(io_base);
/* disable force PME-enable */
iowrite8(PME_OVR, io_base + MAC_REG_PMC1);
/* only 3253 A */
@@ -730,7 +771,7 @@ bool MACbPSWakeup(struct vnt_private *priv)
return true;
/* Disable PS */
- MACvRegBitsOff(io_base, MAC_REG_PSCTL, PSCTL_PSEN);
+ vt6655_mac_reg_bits_off(io_base, MAC_REG_PSCTL, PSCTL_PSEN);
/* Check if SyncFlushOK */
for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
diff --git a/drivers/staging/vt6655/mac.h b/drivers/staging/vt6655/mac.h
index 57ae3bdbdb2d..0122c4603c66 100644
--- a/drivers/staging/vt6655/mac.h
+++ b/drivers/staging/vt6655/mac.h
@@ -18,7 +18,7 @@
#ifndef __MAC_H__
#define __MAC_H__
-#include "upc.h"
+#include "device.h"
/*--------------------- Export Definitions -------------------------*/
/* Registers in the MAC */
@@ -537,82 +537,14 @@
/*--------------------- Export Macros ------------------------------*/
-#define MACvRegBitsOn(iobase, byRegOfs, byBits) \
-do { \
- unsigned char byData; \
- byData = ioread8(iobase + byRegOfs); \
- iowrite8(byData | (byBits), iobase + byRegOfs); \
-} while (0)
-
-#define MACvWordRegBitsOn(iobase, byRegOfs, wBits) \
-do { \
- unsigned short wData; \
- wData = ioread16(iobase + byRegOfs); \
- VNSvOutPortW(iobase + byRegOfs, wData | (wBits)); \
-} while (0)
-
-#define MACvRegBitsOff(iobase, byRegOfs, byBits) \
-do { \
- unsigned char byData; \
- byData = ioread8(iobase + byRegOfs); \
- iowrite8(byData & ~(byBits), iobase + byRegOfs); \
-} while (0)
-
-#define MACvWordRegBitsOff(iobase, byRegOfs, wBits) \
-do { \
- unsigned short wData; \
- wData = ioread16(iobase + byRegOfs); \
- VNSvOutPortW(iobase + byRegOfs, wData & ~(wBits)); \
-} while (0)
-
-/* set the chip with current BCN tx descriptor address */
-#define MACvSetCurrBCNTxDescAddr(iobase, dwCurrDescAddr) \
- VNSvOutPortD(iobase + MAC_REG_BCNDMAPTR, \
- dwCurrDescAddr)
-
-/* set the chip with current BCN length */
-#define MACvSetCurrBCNLength(iobase, wCurrBCNLength) \
- VNSvOutPortW(iobase + MAC_REG_BCNDMACTL + 2, \
- wCurrBCNLength)
-
-#define MACvWriteBSSIDAddress(iobase, pbyEtherAddr) \
-do { \
- iowrite8(1, iobase + MAC_REG_PAGE1SEL); \
- iowrite8(pbyEtherAddr[0], iobase + MAC_REG_BSSID0); \
- iowrite8(pbyEtherAddr[1], iobase + MAC_REG_BSSID0 + 1); \
- iowrite8(pbyEtherAddr[2], iobase + MAC_REG_BSSID0 + 2); \
- iowrite8(pbyEtherAddr[3], iobase + MAC_REG_BSSID0 + 3); \
- iowrite8(pbyEtherAddr[4], iobase + MAC_REG_BSSID0 + 4); \
- iowrite8(pbyEtherAddr[5], iobase + MAC_REG_BSSID0 + 5); \
- iowrite8(0, iobase + MAC_REG_PAGE1SEL); \
-} while (0)
-
-#define MACvReadEtherAddress(iobase, pbyEtherAddr) \
-do { \
- iowrite8(1, iobase + MAC_REG_PAGE1SEL); \
- pbyEtherAddr[0] = ioread8(iobase + MAC_REG_PAR0); \
- pbyEtherAddr[1] = ioread8(iobase + MAC_REG_PAR0 + 1); \
- pbyEtherAddr[2] = ioread8(iobase + MAC_REG_PAR0 + 2); \
- pbyEtherAddr[3] = ioread8(iobase + MAC_REG_PAR0 + 3); \
- pbyEtherAddr[4] = ioread8(iobase + MAC_REG_PAR0 + 4); \
- pbyEtherAddr[5] = ioread8(iobase + MAC_REG_PAR0 + 5); \
- iowrite8(0, iobase + MAC_REG_PAGE1SEL); \
-} while (0)
-
-#define MACvRx0PerPktMode(iobase) \
- VNSvOutPortD(iobase + MAC_REG_RXDMACTL0, RX_PERPKT)
-
-#define MACvRx1PerPktMode(iobase) \
- VNSvOutPortD(iobase + MAC_REG_RXDMACTL1, RX_PERPKT)
-
#define MACvReceive0(iobase) \
do { \
unsigned long dwData; \
dwData = ioread32(iobase + MAC_REG_RXDMACTL0); \
if (dwData & DMACTL_RUN) \
- VNSvOutPortD(iobase + MAC_REG_RXDMACTL0, DMACTL_WAKE); \
+ iowrite32(DMACTL_WAKE, iobase + MAC_REG_RXDMACTL0); \
else \
- VNSvOutPortD(iobase + MAC_REG_RXDMACTL0, DMACTL_RUN); \
+ iowrite32(DMACTL_RUN, iobase + MAC_REG_RXDMACTL0); \
} while (0)
#define MACvReceive1(iobase) \
@@ -620,9 +552,9 @@ do { \
unsigned long dwData; \
dwData = ioread32(iobase + MAC_REG_RXDMACTL1); \
if (dwData & DMACTL_RUN) \
- VNSvOutPortD(iobase + MAC_REG_RXDMACTL1, DMACTL_WAKE); \
+ iowrite32(DMACTL_WAKE, iobase + MAC_REG_RXDMACTL1); \
else \
- VNSvOutPortD(iobase + MAC_REG_RXDMACTL1, DMACTL_RUN); \
+ iowrite32(DMACTL_RUN, iobase + MAC_REG_RXDMACTL1); \
} while (0)
#define MACvTransmit0(iobase) \
@@ -630,9 +562,9 @@ do { \
unsigned long dwData; \
dwData = ioread32(iobase + MAC_REG_TXDMACTL0); \
if (dwData & DMACTL_RUN) \
- VNSvOutPortD(iobase + MAC_REG_TXDMACTL0, DMACTL_WAKE); \
+ iowrite32(DMACTL_WAKE, iobase + MAC_REG_TXDMACTL0); \
else \
- VNSvOutPortD(iobase + MAC_REG_TXDMACTL0, DMACTL_RUN); \
+ iowrite32(DMACTL_RUN, iobase + MAC_REG_TXDMACTL0); \
} while (0)
#define MACvTransmitAC0(iobase) \
@@ -640,28 +572,11 @@ do { \
unsigned long dwData; \
dwData = ioread32(iobase + MAC_REG_AC0DMACTL); \
if (dwData & DMACTL_RUN) \
- VNSvOutPortD(iobase + MAC_REG_AC0DMACTL, DMACTL_WAKE); \
+ iowrite32(DMACTL_WAKE, iobase + MAC_REG_AC0DMACTL); \
else \
- VNSvOutPortD(iobase + MAC_REG_AC0DMACTL, DMACTL_RUN); \
-} while (0)
-
-#define MACvClearStckDS(iobase) \
-do { \
- unsigned char byOrgValue; \
- byOrgValue = ioread8(iobase + MAC_REG_STICKHW); \
- byOrgValue = byOrgValue & 0xFC; \
- iowrite8(byOrgValue, iobase + MAC_REG_STICKHW); \
+ iowrite32(DMACTL_RUN, iobase + MAC_REG_AC0DMACTL); \
} while (0)
-#define MACvWriteISR(iobase, dwValue) \
- VNSvOutPortD(iobase + MAC_REG_ISR, dwValue)
-
-#define MACvIntEnable(iobase, dwMask) \
- VNSvOutPortD(iobase + MAC_REG_IMR, dwMask)
-
-#define MACvIntDisable(iobase) \
- VNSvOutPortD(iobase + MAC_REG_IMR, 0)
-
#define MACvSelectPage0(iobase) \
iowrite8(0, iobase + MAC_REG_PAGE1SEL)
@@ -673,7 +588,7 @@ do { \
unsigned long dwOrgValue; \
dwOrgValue = ioread32(iobase + MAC_REG_ENCFG); \
dwOrgValue = dwOrgValue | ENCFG_PROTECTMD; \
- VNSvOutPortD(iobase + MAC_REG_ENCFG, dwOrgValue); \
+ iowrite32((u32)dwOrgValue, iobase + MAC_REG_ENCFG); \
} while (0)
#define MACvDisableProtectMD(iobase) \
@@ -681,7 +596,7 @@ do { \
unsigned long dwOrgValue; \
dwOrgValue = ioread32(iobase + MAC_REG_ENCFG); \
dwOrgValue = dwOrgValue & ~ENCFG_PROTECTMD; \
- VNSvOutPortD(iobase + MAC_REG_ENCFG, dwOrgValue); \
+ iowrite32((u32)dwOrgValue, iobase + MAC_REG_ENCFG); \
} while (0)
#define MACvEnableBarkerPreambleMd(iobase) \
@@ -689,7 +604,7 @@ do { \
unsigned long dwOrgValue; \
dwOrgValue = ioread32(iobase + MAC_REG_ENCFG); \
dwOrgValue = dwOrgValue | ENCFG_BARKERPREAM; \
- VNSvOutPortD(iobase + MAC_REG_ENCFG, dwOrgValue); \
+ iowrite32((u32)dwOrgValue, iobase + MAC_REG_ENCFG); \
} while (0)
#define MACvDisableBarkerPreambleMd(iobase) \
@@ -697,7 +612,7 @@ do { \
unsigned long dwOrgValue; \
dwOrgValue = ioread32(iobase + MAC_REG_ENCFG); \
dwOrgValue = dwOrgValue & ~ENCFG_BARKERPREAM; \
- VNSvOutPortD(iobase + MAC_REG_ENCFG, dwOrgValue); \
+ iowrite32((u32)dwOrgValue, iobase + MAC_REG_ENCFG); \
} while (0)
#define MACvSetBBType(iobase, byTyp) \
@@ -706,15 +621,20 @@ do { \
dwOrgValue = ioread32(iobase + MAC_REG_ENCFG); \
dwOrgValue = dwOrgValue & ~ENCFG_BBTYPE_MASK; \
dwOrgValue = dwOrgValue | (unsigned long)byTyp; \
- VNSvOutPortD(iobase + MAC_REG_ENCFG, dwOrgValue); \
+ iowrite32((u32)dwOrgValue, iobase + MAC_REG_ENCFG); \
} while (0)
#define MACvSetRFLE_LatchBase(iobase) \
- MACvWordRegBitsOn(iobase, MAC_REG_SOFTPWRCTL, SOFTPWRCTL_RFLEOPT)
+ vt6655_mac_word_reg_bits_on(iobase, MAC_REG_SOFTPWRCTL, SOFTPWRCTL_RFLEOPT)
#define MAKEWORD(lb, hb) \
((unsigned short)(((unsigned char)(lb)) | (((unsigned short)((unsigned char)(hb))) << 8)))
+void vt6655_mac_reg_bits_on(void __iomem *iobase, const u8 reg_offset, const u8 bit_mask);
+void vt6655_mac_word_reg_bits_on(void __iomem *iobase, const u8 reg_offset, const u16 bit_mask);
+void vt6655_mac_reg_bits_off(void __iomem *iobase, const u8 reg_offset, const u8 bit_mask);
+void vt6655_mac_word_reg_bits_off(void __iomem *iobase, const u8 reg_offset, const u16 bit_mask);
+
bool MACbIsRegBitsOff(struct vnt_private *priv, unsigned char byRegOfs,
unsigned char byTestBits);
diff --git a/drivers/staging/vt6655/power.c b/drivers/staging/vt6655/power.c
index 06066fa56dd5..8527ad3eff48 100644
--- a/drivers/staging/vt6655/power.c
+++ b/drivers/staging/vt6655/power.c
@@ -52,30 +52,30 @@ void PSvEnablePowerSaving(struct vnt_private *priv,
u16 wAID = priv->current_aid | BIT(14) | BIT(15);
/* set period of power up before TBTT */
- VNSvOutPortW(priv->port_offset + MAC_REG_PWBT, C_PWBT);
+ iowrite16(C_PWBT, priv->port_offset + MAC_REG_PWBT);
if (priv->op_mode != NL80211_IFTYPE_ADHOC) {
/* set AID */
- VNSvOutPortW(priv->port_offset + MAC_REG_AIDATIM, wAID);
+ iowrite16(wAID, priv->port_offset + MAC_REG_AIDATIM);
}
/* Set AutoSleep */
- MACvRegBitsOn(priv->port_offset, MAC_REG_PSCFG, PSCFG_AUTOSLEEP);
+ vt6655_mac_reg_bits_on(priv->port_offset, MAC_REG_PSCFG, PSCFG_AUTOSLEEP);
/* Set HWUTSF */
- MACvRegBitsOn(priv->port_offset, MAC_REG_TFTCTL, TFTCTL_HWUTSF);
+ vt6655_mac_reg_bits_on(priv->port_offset, MAC_REG_TFTCTL, TFTCTL_HWUTSF);
if (wListenInterval >= 2) {
/* clear always listen beacon */
- MACvRegBitsOff(priv->port_offset, MAC_REG_PSCTL, PSCTL_ALBCN);
+ vt6655_mac_reg_bits_off(priv->port_offset, MAC_REG_PSCTL, PSCTL_ALBCN);
/* first time set listen next beacon */
- MACvRegBitsOn(priv->port_offset, MAC_REG_PSCTL, PSCTL_LNBCN);
+ vt6655_mac_reg_bits_on(priv->port_offset, MAC_REG_PSCTL, PSCTL_LNBCN);
} else {
/* always listen beacon */
- MACvRegBitsOn(priv->port_offset, MAC_REG_PSCTL, PSCTL_ALBCN);
+ vt6655_mac_reg_bits_on(priv->port_offset, MAC_REG_PSCTL, PSCTL_ALBCN);
}
/* enable power saving hw function */
- MACvRegBitsOn(priv->port_offset, MAC_REG_PSCTL, PSCTL_PSEN);
+ vt6655_mac_reg_bits_on(priv->port_offset, MAC_REG_PSCTL, PSCTL_PSEN);
priv->bEnablePSMode = true;
priv->bPWBitOn = true;
@@ -98,13 +98,13 @@ void PSvDisablePowerSaving(struct vnt_private *priv)
MACbPSWakeup(priv);
/* clear AutoSleep */
- MACvRegBitsOff(priv->port_offset, MAC_REG_PSCFG, PSCFG_AUTOSLEEP);
+ vt6655_mac_reg_bits_off(priv->port_offset, MAC_REG_PSCFG, PSCFG_AUTOSLEEP);
/* clear HWUTSF */
- MACvRegBitsOff(priv->port_offset, MAC_REG_TFTCTL, TFTCTL_HWUTSF);
+ vt6655_mac_reg_bits_off(priv->port_offset, MAC_REG_TFTCTL, TFTCTL_HWUTSF);
/* set always listen beacon */
- MACvRegBitsOn(priv->port_offset, MAC_REG_PSCTL, PSCTL_ALBCN);
+ vt6655_mac_reg_bits_on(priv->port_offset, MAC_REG_PSCTL, PSCTL_ALBCN);
priv->bEnablePSMode = false;
@@ -135,8 +135,7 @@ bool PSbIsNextTBTTWakeUp(struct vnt_private *priv)
if (priv->wake_up_count == 1) {
/* Turn on wake up to listen next beacon */
- MACvRegBitsOn(priv->port_offset,
- MAC_REG_PSCTL, PSCTL_LNBCN);
+ vt6655_mac_reg_bits_on(priv->port_offset, MAC_REG_PSCTL, PSCTL_LNBCN);
wake_up = true;
}
}
diff --git a/drivers/staging/vt6655/rf.c b/drivers/staging/vt6655/rf.c
index ee5e2e0d9a8c..1fadc2fc4412 100644
--- a/drivers/staging/vt6655/rf.c
+++ b/drivers/staging/vt6655/rf.c
@@ -171,7 +171,7 @@ bool IFRFbWriteEmbedded(struct vnt_private *priv, unsigned long dwData)
unsigned short ww;
unsigned long dwValue;
- VNSvOutPortD(iobase + MAC_REG_IFREGCTL, dwData);
+ iowrite32((u32)dwData, iobase + MAC_REG_IFREGCTL);
/* W_MAX_TIMEOUT is the timeout period */
for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
@@ -209,10 +209,10 @@ static bool RFbAL2230Init(struct vnt_private *priv)
/* 3-wire control for normal mode */
iowrite8(0, iobase + MAC_REG_SOFTPWRCTL);
- MACvWordRegBitsOn(iobase, MAC_REG_SOFTPWRCTL, (SOFTPWRCTL_SWPECTI |
- SOFTPWRCTL_TXPEINV));
+ vt6655_mac_word_reg_bits_on(iobase, MAC_REG_SOFTPWRCTL,
+ (SOFTPWRCTL_SWPECTI | SOFTPWRCTL_TXPEINV));
/* PLL Off */
- MACvWordRegBitsOff(iobase, MAC_REG_SOFTPWRCTL, SOFTPWRCTL_SWPE3);
+ vt6655_mac_word_reg_bits_off(iobase, MAC_REG_SOFTPWRCTL, SOFTPWRCTL_SWPE3);
/* patch abnormal AL2230 frequency output */
IFRFbWriteEmbedded(priv, (0x07168700 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW));
@@ -222,7 +222,7 @@ static bool RFbAL2230Init(struct vnt_private *priv)
MACvTimer0MicroSDelay(priv, 30); /* delay 30 us */
/* PLL On */
- MACvWordRegBitsOn(iobase, MAC_REG_SOFTPWRCTL, SOFTPWRCTL_SWPE3);
+ vt6655_mac_word_reg_bits_on(iobase, MAC_REG_SOFTPWRCTL, SOFTPWRCTL_SWPE3);
MACvTimer0MicroSDelay(priv, 150);/* 150us */
ret &= IFRFbWriteEmbedded(priv, (0x00d80f00 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW));
@@ -232,10 +232,10 @@ static bool RFbAL2230Init(struct vnt_private *priv)
ret &= IFRFbWriteEmbedded(priv,
al2230_init_table[CB_AL2230_INIT_SEQ - 1]);
- MACvWordRegBitsOn(iobase, MAC_REG_SOFTPWRCTL, (SOFTPWRCTL_SWPE3 |
- SOFTPWRCTL_SWPE2 |
- SOFTPWRCTL_SWPECTI |
- SOFTPWRCTL_TXPEINV));
+ vt6655_mac_word_reg_bits_on(iobase, MAC_REG_SOFTPWRCTL, (SOFTPWRCTL_SWPE3 |
+ SOFTPWRCTL_SWPE2 |
+ SOFTPWRCTL_SWPECTI |
+ SOFTPWRCTL_TXPEINV));
/* 3-wire control for power saving mode */
iowrite8(PSSIG_WPE3 | PSSIG_WPE2, iobase + MAC_REG_PSPWRSIG);
@@ -350,7 +350,7 @@ bool rf_write_wake_prog_syn(struct vnt_private *priv, unsigned char rf_type,
unsigned char sleep_count = 0;
unsigned short idx = MISCFIFO_SYNDATA_IDX;
- VNSvOutPortW(iobase + MAC_REG_MISCFFNDEX, 0);
+ iowrite16(0, iobase + MAC_REG_MISCFFNDEX);
switch (rf_type) {
case RF_AIROHA:
case RF_AL2230S:
diff --git a/drivers/staging/vt6655/rxtx.c b/drivers/staging/vt6655/rxtx.c
index 85cd01c463e8..5bdb5176772c 100644
--- a/drivers/staging/vt6655/rxtx.c
+++ b/drivers/staging/vt6655/rxtx.c
@@ -1420,11 +1420,11 @@ static int vnt_beacon_xmit(struct vnt_private *priv,
priv->wBCNBufLen = sizeof(*short_head) + skb->len;
- MACvSetCurrBCNTxDescAddr(priv->port_offset, priv->tx_beacon_dma);
+ iowrite32((u32)priv->tx_beacon_dma, priv->port_offset + MAC_REG_BCNDMAPTR);
- MACvSetCurrBCNLength(priv->port_offset, priv->wBCNBufLen);
+ iowrite16(priv->wBCNBufLen, priv->port_offset + MAC_REG_BCNDMACTL + 2);
/* Set auto Transmit on */
- MACvRegBitsOn(priv->port_offset, MAC_REG_TCR, TCR_AUTOBCNTX);
+ vt6655_mac_reg_bits_on(priv->port_offset, MAC_REG_TCR, TCR_AUTOBCNTX);
/* Poll Transmit the adapter */
iowrite8(BEACON_READY, priv->port_offset + MAC_REG_BCNDMACTL);
diff --git a/drivers/staging/vt6655/srom.c b/drivers/staging/vt6655/srom.c
index 722a2cc9a473..ee5ca4db74dc 100644
--- a/drivers/staging/vt6655/srom.c
+++ b/drivers/staging/vt6655/srom.c
@@ -27,7 +27,7 @@
*
*/
-#include "upc.h"
+#include "device.h"
#include "mac.h"
#include "srom.h"
diff --git a/drivers/staging/vt6655/upc.h b/drivers/staging/vt6655/upc.h
deleted file mode 100644
index 2a47f5782b71..000000000000
--- a/drivers/staging/vt6655/upc.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0+ */
-/*
- * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
- * All rights reserved.
- *
- * Purpose: Macros to access device
- *
- * Author: Tevin Chen
- *
- * Date: Mar 17, 1997
- *
- */
-
-#ifndef __UPC_H__
-#define __UPC_H__
-
-#include "device.h"
-
-/*--------------------- Export Definitions -------------------------*/
-
-/* For memory mapped IO */
-
-#define VNSvOutPortW(dwIOAddress, wData) \
- iowrite16((u16)(wData), dwIOAddress)
-
-#define VNSvOutPortD(dwIOAddress, dwData) \
- iowrite32((u32)(dwData), dwIOAddress)
-
-/*--------------------- Export Classes ----------------------------*/
-
-/*--------------------- Export Variables --------------------------*/
-
-/*--------------------- Export Functions --------------------------*/
-
-#endif /* __UPC_H__ */