// SPDX-License-Identifier: GPL-2.0
/******************************************************************************
 *
 * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved.
 *
 ******************************************************************************/
#define _RTW_DEBUG_C_

#include <rtw_debug.h>
#include <usb_ops_linux.h>

int proc_get_drv_version(char *page, char **start,
			  off_t offset, int count,
			  int *eof, void *data)
{
	int len = 0;

	len += snprintf(page + len, count - len, "%s\n", DRIVERVERSION);

	*eof = 1;
	return len;
}

int proc_get_write_reg(char *page, char **start,
			  off_t offset, int count,
			  int *eof, void *data)
{
	*eof = 1;
	return 0;
}

int proc_set_write_reg(struct file *file, const char __user *buffer,
		unsigned long count, void *data)
{
	struct net_device *dev = data;
	struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
	char tmp[32];
	u32 addr, val, len;

	if (count < 3) {
		DBG_88E("argument size is less than 3\n");
		return -EFAULT;
	}

	if (buffer && !copy_from_user(tmp, buffer, sizeof(tmp))) {
		int num = sscanf(tmp, "%x %x %x", &addr, &val, &len);

		if (num !=  3) {
			DBG_88E("invalid write_reg parameter!\n");
			return count;
		}
		switch (len) {
		case 1:
			usb_write8(padapter, addr, (u8)val);
			break;
		case 2:
			usb_write16(padapter, addr, (u16)val);
			break;
		case 4:
			usb_write32(padapter, addr, val);
			break;
		default:
			DBG_88E("error write length =%d", len);
			break;
		}
	}
	return count;
}

static u32 proc_get_read_addr = 0xeeeeeeee;
static u32 proc_get_read_len = 0x4;

int proc_get_read_reg(char *page, char **start,
			  off_t offset, int count,
			  int *eof, void *data)
{
	struct net_device *dev = data;
	struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);

	int len = 0;

	if (proc_get_read_addr == 0xeeeeeeee) {
		*eof = 1;
		return len;
	}

	switch (proc_get_read_len) {
	case 1:
		len += snprintf(page + len, count - len, "usb_read8(0x%x)=0x%x\n", proc_get_read_addr, usb_read8(padapter, proc_get_read_addr));
		break;
	case 2:
		len += snprintf(page + len, count - len, "usb_read16(0x%x)=0x%x\n", proc_get_read_addr, usb_read16(padapter, proc_get_read_addr));
		break;
	case 4:
		len += snprintf(page + len, count - len, "usb_read32(0x%x)=0x%x\n", proc_get_read_addr, usb_read32(padapter, proc_get_read_addr));
		break;
	default:
		len += snprintf(page + len, count - len, "error read length=%d\n", proc_get_read_len);
		break;
	}

	*eof = 1;
	return len;
}

int proc_set_read_reg(struct file *file, const char __user *buffer,
		unsigned long count, void *data)
{
	char tmp[16];
	u32 addr, len;

	if (count < 2) {
		DBG_88E("argument size is less than 2\n");
		return -EFAULT;
	}

	if (buffer && !copy_from_user(tmp, buffer, sizeof(tmp))) {
		int num = sscanf(tmp, "%x %x", &addr, &len);

		if (num !=  2) {
			DBG_88E("invalid read_reg parameter!\n");
			return count;
		}

		proc_get_read_addr = addr;

		proc_get_read_len = len;
	}

	return count;
}

int proc_get_adapter_state(char *page, char **start,
			  off_t offset, int count,
			  int *eof, void *data)
{
	struct net_device *dev = data;
	struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
	int len = 0;

	len += snprintf(page + len, count - len, "bSurpriseRemoved=%d, bDriverStopped=%d\n",
						padapter->bSurpriseRemoved, padapter->bDriverStopped);

	*eof = 1;
	return len;
}

int proc_get_best_channel(char *page, char **start,
			  off_t offset, int count,
			  int *eof, void *data)
{
	struct net_device *dev = data;
	struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
	struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
	int len = 0;
	u32 i, best_channel_24G = 1, index_24G = 0;

	for (i = 0; pmlmeext->channel_set[i].ChannelNum != 0; i++) {
		if (pmlmeext->channel_set[i].ChannelNum == 1)
			index_24G = i;
	}

	for (i = 0; pmlmeext->channel_set[i].ChannelNum != 0; i++) {
		/*  2.4G */
		if (pmlmeext->channel_set[i].ChannelNum == 6) {
			if (pmlmeext->channel_set[i].rx_count < pmlmeext->channel_set[index_24G].rx_count) {
				index_24G = i;
				best_channel_24G = pmlmeext->channel_set[i].ChannelNum;
			}
		}

		/*  debug */
		len += snprintf(page + len, count - len, "The rx cnt of channel %3d = %d\n",
					pmlmeext->channel_set[i].ChannelNum, pmlmeext->channel_set[i].rx_count);
	}

	len += snprintf(page + len, count - len, "best_channel_24G = %d\n", best_channel_24G);

	*eof = 1;
	return len;
}
