⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rfkill.c

📁 linux内核源码
💻 C
字号:
/*  Broadcom B43 wireless driver  RFKILL support  Copyright (c) 2007 Michael Buesch <mb@bu3sch.de>  This program is free software; you can redistribute it and/or modify  it under the terms of the GNU General Public License as published by  the Free Software Foundation; either version 2 of the License, or  (at your option) any later version.  This program is distributed in the hope that it will be useful,  but WITHOUT ANY WARRANTY; without even the implied warranty of  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  GNU General Public License for more details.  You should have received a copy of the GNU General Public License  along with this program; see the file COPYING.  If not, write to  the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor,  Boston, MA 02110-1301, USA.*/#include "rfkill.h"#include "b43.h"#include <linux/kmod.h>/* Returns TRUE, if the radio is enabled in hardware. */static bool b43_is_hw_radio_enabled(struct b43_wldev *dev){	if (dev->phy.rev >= 3) {		if (!(b43_read32(dev, B43_MMIO_RADIO_HWENABLED_HI)		      & B43_MMIO_RADIO_HWENABLED_HI_MASK))			return 1;	} else {		if (b43_read16(dev, B43_MMIO_RADIO_HWENABLED_LO)		    & B43_MMIO_RADIO_HWENABLED_LO_MASK)			return 1;	}	return 0;}/* The poll callback for the hardware button. */static void b43_rfkill_poll(struct input_polled_dev *poll_dev){	struct b43_wldev *dev = poll_dev->private;	struct b43_wl *wl = dev->wl;	bool enabled;	bool report_change = 0;	mutex_lock(&wl->mutex);	if (unlikely(b43_status(dev) < B43_STAT_INITIALIZED)) {		mutex_unlock(&wl->mutex);		return;	}	enabled = b43_is_hw_radio_enabled(dev);	if (unlikely(enabled != dev->radio_hw_enable)) {		dev->radio_hw_enable = enabled;		report_change = 1;		b43info(wl, "Radio hardware status changed to %s\n",			enabled ? "ENABLED" : "DISABLED");	}	mutex_unlock(&wl->mutex);	/* send the radio switch event to the system - note both a key press	 * and a release are required */	if (unlikely(report_change)) {		input_report_key(poll_dev->input, KEY_WLAN, 1);		input_report_key(poll_dev->input, KEY_WLAN, 0);	}}/* Called when the RFKILL toggled in software. */static int b43_rfkill_soft_toggle(void *data, enum rfkill_state state){	struct b43_wldev *dev = data;	struct b43_wl *wl = dev->wl;	int err = -EBUSY;	if (!wl->rfkill.registered)		return 0;	mutex_lock(&wl->mutex);	if (b43_status(dev) < B43_STAT_INITIALIZED)		goto out_unlock;	err = 0;	switch (state) {	case RFKILL_STATE_ON:		if (!dev->radio_hw_enable) {			/* No luck. We can't toggle the hardware RF-kill			 * button from software. */			err = -EBUSY;			goto out_unlock;		}		if (!dev->phy.radio_on)			b43_radio_turn_on(dev);		break;	case RFKILL_STATE_OFF:		if (dev->phy.radio_on)			b43_radio_turn_off(dev, 0);		break;	}out_unlock:	mutex_unlock(&wl->mutex);	return err;}char * b43_rfkill_led_name(struct b43_wldev *dev){	struct b43_rfkill *rfk = &(dev->wl->rfkill);	if (!rfk->registered)		return NULL;	return rfkill_get_led_name(rfk->rfkill);}void b43_rfkill_init(struct b43_wldev *dev){	struct b43_wl *wl = dev->wl;	struct b43_rfkill *rfk = &(wl->rfkill);	int err;	rfk->registered = 0;	rfk->rfkill = rfkill_allocate(dev->dev->dev, RFKILL_TYPE_WLAN);	if (!rfk->rfkill)		goto out_error;	snprintf(rfk->name, sizeof(rfk->name),		 "b43-%s", wiphy_name(wl->hw->wiphy));	rfk->rfkill->name = rfk->name;	rfk->rfkill->state = RFKILL_STATE_ON;	rfk->rfkill->data = dev;	rfk->rfkill->toggle_radio = b43_rfkill_soft_toggle;	rfk->rfkill->user_claim_unsupported = 1;	rfk->poll_dev = input_allocate_polled_device();	if (!rfk->poll_dev) {		rfkill_free(rfk->rfkill);		goto err_freed_rfk;	}	rfk->poll_dev->private = dev;	rfk->poll_dev->poll = b43_rfkill_poll;	rfk->poll_dev->poll_interval = 1000; /* msecs */	rfk->poll_dev->input->name = rfk->name;	rfk->poll_dev->input->id.bustype = BUS_HOST;	rfk->poll_dev->input->id.vendor = dev->dev->bus->boardinfo.vendor;	rfk->poll_dev->input->evbit[0] = BIT(EV_KEY);	set_bit(KEY_WLAN, rfk->poll_dev->input->keybit);	err = rfkill_register(rfk->rfkill);	if (err)		goto err_free_polldev;#ifdef CONFIG_RFKILL_INPUT_MODULE	/* B43 RF-kill isn't useful without the rfkill-input subsystem.	 * Try to load the module. */	err = request_module("rfkill-input");	if (err)		b43warn(wl, "Failed to load the rfkill-input module. "			"The built-in radio LED will not work.\n");#endif /* CONFIG_RFKILL_INPUT */	err = input_register_polled_device(rfk->poll_dev);	if (err)		goto err_unreg_rfk;	rfk->registered = 1;	return;err_unreg_rfk:	rfkill_unregister(rfk->rfkill);err_free_polldev:	input_free_polled_device(rfk->poll_dev);	rfk->poll_dev = NULL;err_freed_rfk:	rfk->rfkill = NULL;out_error:	rfk->registered = 0;	b43warn(wl, "RF-kill button init failed\n");}void b43_rfkill_exit(struct b43_wldev *dev){	struct b43_rfkill *rfk = &(dev->wl->rfkill);	if (!rfk->registered)		return;	rfk->registered = 0;	input_unregister_polled_device(rfk->poll_dev);	rfkill_unregister(rfk->rfkill);	input_free_polled_device(rfk->poll_dev);	rfk->poll_dev = NULL;	rfk->rfkill = NULL;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -