11ccea77eSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later
26948300cSKalle Valo /* ZD1211 USB-WLAN driver for Linux
36948300cSKalle Valo  *
46948300cSKalle Valo  * Copyright (C) 2005-2007 Ulrich Kunitz <kune@deine-taler.de>
56948300cSKalle Valo  * Copyright (C) 2006-2007 Daniel Drake <dsd@gentoo.org>
66948300cSKalle Valo  */
76948300cSKalle Valo 
86948300cSKalle Valo #include <linux/errno.h>
96948300cSKalle Valo #include <linux/string.h>
106948300cSKalle Valo 
116948300cSKalle Valo #include "zd_def.h"
126948300cSKalle Valo #include "zd_rf.h"
136948300cSKalle Valo #include "zd_mac.h"
146948300cSKalle Valo #include "zd_chip.h"
156948300cSKalle Valo 
166948300cSKalle Valo static const char * const rfs[] = {
176948300cSKalle Valo 	[0]		= "unknown RF0",
186948300cSKalle Valo 	[1]		= "unknown RF1",
196948300cSKalle Valo 	[UW2451_RF]	= "UW2451_RF",
206948300cSKalle Valo 	[UCHIP_RF]	= "UCHIP_RF",
216948300cSKalle Valo 	[AL2230_RF]	= "AL2230_RF",
226948300cSKalle Valo 	[AL7230B_RF]	= "AL7230B_RF",
236948300cSKalle Valo 	[THETA_RF]	= "THETA_RF",
246948300cSKalle Valo 	[AL2210_RF]	= "AL2210_RF",
256948300cSKalle Valo 	[MAXIM_NEW_RF]	= "MAXIM_NEW_RF",
266948300cSKalle Valo 	[UW2453_RF]	= "UW2453_RF",
276948300cSKalle Valo 	[AL2230S_RF]	= "AL2230S_RF",
286948300cSKalle Valo 	[RALINK_RF]	= "RALINK_RF",
296948300cSKalle Valo 	[INTERSIL_RF]	= "INTERSIL_RF",
306948300cSKalle Valo 	[RF2959_RF]	= "RF2959_RF",
316948300cSKalle Valo 	[MAXIM_NEW2_RF]	= "MAXIM_NEW2_RF",
326948300cSKalle Valo 	[PHILIPS_RF]	= "PHILIPS_RF",
336948300cSKalle Valo };
346948300cSKalle Valo 
zd_rf_name(u8 type)356948300cSKalle Valo const char *zd_rf_name(u8 type)
366948300cSKalle Valo {
376948300cSKalle Valo 	if (type & 0xf0)
386948300cSKalle Valo 		type = 0;
396948300cSKalle Valo 	return rfs[type];
406948300cSKalle Valo }
416948300cSKalle Valo 
zd_rf_init(struct zd_rf * rf)426948300cSKalle Valo void zd_rf_init(struct zd_rf *rf)
436948300cSKalle Valo {
446948300cSKalle Valo 	memset(rf, 0, sizeof(*rf));
456948300cSKalle Valo 
466948300cSKalle Valo 	/* default to update channel integration, as almost all RF's do want
476948300cSKalle Valo 	 * this */
486948300cSKalle Valo 	rf->update_channel_int = 1;
496948300cSKalle Valo }
506948300cSKalle Valo 
zd_rf_clear(struct zd_rf * rf)516948300cSKalle Valo void zd_rf_clear(struct zd_rf *rf)
526948300cSKalle Valo {
536948300cSKalle Valo 	if (rf->clear)
546948300cSKalle Valo 		rf->clear(rf);
556948300cSKalle Valo 	ZD_MEMCLEAR(rf, sizeof(*rf));
566948300cSKalle Valo }
576948300cSKalle Valo 
zd_rf_init_hw(struct zd_rf * rf,u8 type)586948300cSKalle Valo int zd_rf_init_hw(struct zd_rf *rf, u8 type)
596948300cSKalle Valo {
606948300cSKalle Valo 	int r = 0;
616948300cSKalle Valo 	int t;
626948300cSKalle Valo 	struct zd_chip *chip = zd_rf_to_chip(rf);
636948300cSKalle Valo 
646948300cSKalle Valo 	ZD_ASSERT(mutex_is_locked(&chip->mutex));
656948300cSKalle Valo 	switch (type) {
666948300cSKalle Valo 	case RF2959_RF:
676948300cSKalle Valo 		r = zd_rf_init_rf2959(rf);
686948300cSKalle Valo 		break;
696948300cSKalle Valo 	case AL2230_RF:
706948300cSKalle Valo 	case AL2230S_RF:
716948300cSKalle Valo 		r = zd_rf_init_al2230(rf);
726948300cSKalle Valo 		break;
736948300cSKalle Valo 	case AL7230B_RF:
746948300cSKalle Valo 		r = zd_rf_init_al7230b(rf);
756948300cSKalle Valo 		break;
766948300cSKalle Valo 	case MAXIM_NEW_RF:
776948300cSKalle Valo 	case UW2453_RF:
786948300cSKalle Valo 		r = zd_rf_init_uw2453(rf);
796948300cSKalle Valo 		break;
806948300cSKalle Valo 	default:
816948300cSKalle Valo 		dev_err(zd_chip_dev(chip),
826948300cSKalle Valo 			"RF %s %#x is not supported\n", zd_rf_name(type), type);
836948300cSKalle Valo 		rf->type = 0;
846948300cSKalle Valo 		return -ENODEV;
856948300cSKalle Valo 	}
866948300cSKalle Valo 
876948300cSKalle Valo 	if (r)
886948300cSKalle Valo 		return r;
896948300cSKalle Valo 
906948300cSKalle Valo 	rf->type = type;
916948300cSKalle Valo 
926948300cSKalle Valo 	r = zd_chip_lock_phy_regs(chip);
936948300cSKalle Valo 	if (r)
946948300cSKalle Valo 		return r;
956948300cSKalle Valo 	t = rf->init_hw(rf);
966948300cSKalle Valo 	r = zd_chip_unlock_phy_regs(chip);
976948300cSKalle Valo 	if (t)
986948300cSKalle Valo 		r = t;
996948300cSKalle Valo 	return r;
1006948300cSKalle Valo }
1016948300cSKalle Valo 
zd_rf_scnprint_id(struct zd_rf * rf,char * buffer,size_t size)1026948300cSKalle Valo int zd_rf_scnprint_id(struct zd_rf *rf, char *buffer, size_t size)
1036948300cSKalle Valo {
1046948300cSKalle Valo 	return scnprintf(buffer, size, "%s", zd_rf_name(rf->type));
1056948300cSKalle Valo }
1066948300cSKalle Valo 
zd_rf_set_channel(struct zd_rf * rf,u8 channel)1076948300cSKalle Valo int zd_rf_set_channel(struct zd_rf *rf, u8 channel)
1086948300cSKalle Valo {
1096948300cSKalle Valo 	int r;
1106948300cSKalle Valo 
1116948300cSKalle Valo 	ZD_ASSERT(mutex_is_locked(&zd_rf_to_chip(rf)->mutex));
1126948300cSKalle Valo 	if (channel < MIN_CHANNEL24)
1136948300cSKalle Valo 		return -EINVAL;
1146948300cSKalle Valo 	if (channel > MAX_CHANNEL24)
1156948300cSKalle Valo 		return -EINVAL;
1166948300cSKalle Valo 	dev_dbg_f(zd_chip_dev(zd_rf_to_chip(rf)), "channel: %d\n", channel);
1176948300cSKalle Valo 
1186948300cSKalle Valo 	r = rf->set_channel(rf, channel);
1196948300cSKalle Valo 	if (r >= 0)
1206948300cSKalle Valo 		rf->channel = channel;
1216948300cSKalle Valo 	return r;
1226948300cSKalle Valo }
1236948300cSKalle Valo 
zd_switch_radio_on(struct zd_rf * rf)1246948300cSKalle Valo int zd_switch_radio_on(struct zd_rf *rf)
1256948300cSKalle Valo {
1266948300cSKalle Valo 	int r, t;
1276948300cSKalle Valo 	struct zd_chip *chip = zd_rf_to_chip(rf);
1286948300cSKalle Valo 
1296948300cSKalle Valo 	ZD_ASSERT(mutex_is_locked(&chip->mutex));
1306948300cSKalle Valo 	r = zd_chip_lock_phy_regs(chip);
1316948300cSKalle Valo 	if (r)
1326948300cSKalle Valo 		return r;
1336948300cSKalle Valo 	t = rf->switch_radio_on(rf);
1346948300cSKalle Valo 	r = zd_chip_unlock_phy_regs(chip);
1356948300cSKalle Valo 	if (t)
1366948300cSKalle Valo 		r = t;
1376948300cSKalle Valo 	return r;
1386948300cSKalle Valo }
1396948300cSKalle Valo 
zd_switch_radio_off(struct zd_rf * rf)1406948300cSKalle Valo int zd_switch_radio_off(struct zd_rf *rf)
1416948300cSKalle Valo {
1426948300cSKalle Valo 	int r, t;
1436948300cSKalle Valo 	struct zd_chip *chip = zd_rf_to_chip(rf);
1446948300cSKalle Valo 
1456948300cSKalle Valo 	/* TODO: move phy regs handling to zd_chip */
1466948300cSKalle Valo 	ZD_ASSERT(mutex_is_locked(&chip->mutex));
1476948300cSKalle Valo 	r = zd_chip_lock_phy_regs(chip);
1486948300cSKalle Valo 	if (r)
1496948300cSKalle Valo 		return r;
1506948300cSKalle Valo 	t = rf->switch_radio_off(rf);
1516948300cSKalle Valo 	r = zd_chip_unlock_phy_regs(chip);
1526948300cSKalle Valo 	if (t)
1536948300cSKalle Valo 		r = t;
1546948300cSKalle Valo 	return r;
1556948300cSKalle Valo }
1566948300cSKalle Valo 
zd_rf_patch_6m_band_edge(struct zd_rf * rf,u8 channel)1576948300cSKalle Valo int zd_rf_patch_6m_band_edge(struct zd_rf *rf, u8 channel)
1586948300cSKalle Valo {
1596948300cSKalle Valo 	if (!rf->patch_6m_band_edge)
1606948300cSKalle Valo 		return 0;
1616948300cSKalle Valo 
1626948300cSKalle Valo 	return rf->patch_6m_band_edge(rf, channel);
1636948300cSKalle Valo }
1646948300cSKalle Valo 
zd_rf_generic_patch_6m(struct zd_rf * rf,u8 channel)1656948300cSKalle Valo int zd_rf_generic_patch_6m(struct zd_rf *rf, u8 channel)
1666948300cSKalle Valo {
1676948300cSKalle Valo 	return zd_chip_generic_patch_6m_band(zd_rf_to_chip(rf), channel);
1686948300cSKalle Valo }
1696948300cSKalle Valo 
170