linux/drivers/net/wireless/atmel/at76c50x-usb.c

// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * at76c503/at76c505 USB driver
 *
 * Copyright (c) 2002 - 2003 Oliver Kurth
 * Copyright (c) 2004 Joerg Albert <[email protected]>
 * Copyright (c) 2004 Nick Jones
 * Copyright (c) 2004 Balint Seeber <[email protected]>
 * Copyright (c) 2007 Guido Guenther <[email protected]>
 * Copyright (c) 2007 Kalle Valo <[email protected]>
 * Copyright (c) 2010 Sebastian Smolorz <[email protected]>
 *
 * This file is part of the Berlios driver for USB WLAN devices based on the
 * Atmel AT76C503A/505/505A.
 *
 * Some iw_handler code was taken from airo.c, (C) 1999 Benjamin Reed
 *
 * TODO list is at the wiki:
 *
 * https://wireless.wiki.kernel.org/en/users/Drivers/at76c50x-usb#TODO
 */

#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/errno.h>
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/spinlock.h>
#include <linux/list.h>
#include <linux/usb.h>
#include <linux/netdevice.h>
#include <linux/if_arp.h>
#include <linux/etherdevice.h>
#include <linux/ethtool.h>
#include <linux/wireless.h>
#include <net/iw_handler.h>
#include <net/ieee80211_radiotap.h>
#include <linux/firmware.h>
#include <linux/leds.h>
#include <net/mac80211.h>

#include "at76c50x-usb.h"

/* Version information */
#define DRIVER_NAME
#define DRIVER_VERSION
#define DRIVER_DESC

/* at76_debug bits */
#define DBG_PROGRESS
#define DBG_BSS_TABLE
#define DBG_IOCTL
#define DBG_MAC_STATE
#define DBG_TX_DATA
#define DBG_TX_DATA_CONTENT
#define DBG_TX_MGMT
#define DBG_RX_DATA
#define DBG_RX_DATA_CONTENT
#define DBG_RX_MGMT
#define DBG_RX_BEACON
#define DBG_RX_CTRL
#define DBG_RX_MGMT_CONTENT
#define DBG_RX_FRAGS
#define DBG_DEVSTART
#define DBG_URB
#define DBG_RX_ATMEL_HDR
#define DBG_PROC_ENTRY
#define DBG_PM
#define DBG_BSS_MATCH
#define DBG_PARAMS
#define DBG_WAIT_COMPLETE
#define DBG_RX_FRAGS_SKB
#define DBG_BSS_TABLE_RM
#define DBG_MONITOR_MODE
#define DBG_MIB
#define DBG_MGMT_TIMER
#define DBG_WE_EVENTS
#define DBG_FW
#define DBG_DFU
#define DBG_CMD
#define DBG_MAC80211

#define DBG_DEFAULTS

/* Use our own dbg macro */
#define at76_dbg(bits, format, arg...)

#define at76_dbg_dump(bits, buf, len, format, arg...)

static uint at76_debug =;

/* Protect against concurrent firmware loading and parsing */
static DEFINE_MUTEX(fw_mutex);

static struct fwentry firmwares[] =;
MODULE_FIRMWARE();
MODULE_FIRMWARE();
MODULE_FIRMWARE();
MODULE_FIRMWARE();
MODULE_FIRMWARE();
MODULE_FIRMWARE();
MODULE_FIRMWARE();
MODULE_FIRMWARE();

#define USB_DEVICE_DATA(__ops)

static const struct usb_device_id dev_table[] =;

MODULE_DEVICE_TABLE(usb, dev_table);

/* Supported rates of this hardware, bit 7 marks basic rates */
static const u8 hw_rates[] =;

static const char *const preambles[] =;

/* Firmware download */
/* DFU states */
#define STATE_IDLE
#define STATE_DETACH
#define STATE_DFU_IDLE
#define STATE_DFU_DOWNLOAD_SYNC
#define STATE_DFU_DOWNLOAD_BUSY
#define STATE_DFU_DOWNLOAD_IDLE
#define STATE_DFU_MANIFEST_SYNC
#define STATE_DFU_MANIFEST
#define STATE_DFU_MANIFEST_WAIT_RESET
#define STATE_DFU_UPLOAD_IDLE
#define STATE_DFU_ERROR

/* DFU commands */
#define DFU_DETACH
#define DFU_DNLOAD
#define DFU_UPLOAD
#define DFU_GETSTATUS
#define DFU_CLRSTATUS
#define DFU_GETSTATE
#define DFU_ABORT

#define FW_BLOCK_SIZE

struct dfu_status {} __packed;

static inline int at76_is_intersil(enum board_type board)
{}

static inline int at76_is_503rfmd(enum board_type board)
{}

static inline int at76_is_505a(enum board_type board)
{}

/* Load a block of the first (internal) part of the firmware */
static int at76_load_int_fw_block(struct usb_device *udev, int blockno,
				  void *block, int size)
{}

static int at76_dfu_get_status(struct usb_device *udev,
			       struct dfu_status *status)
{}

static int at76_dfu_get_state(struct usb_device *udev, u8 *state)
{}

/* Convert timeout from the DFU status to jiffies */
static inline unsigned long at76_get_timeout(struct dfu_status *s)
{}

/* Load internal firmware from the buffer.  If manifest_sync_timeout > 0, use
 * its value in jiffies in the MANIFEST_SYNC state.  */
static int at76_usbdfu_download(struct usb_device *udev, u8 *buf, u32 size,
				int manifest_sync_timeout)
{}

/* LED trigger */
static int tx_activity;
static void at76_ledtrig_tx_timerfunc(struct timer_list *unused);
static DEFINE_TIMER(ledtrig_tx_timer, at76_ledtrig_tx_timerfunc);
DEFINE_LED_TRIGGER(ledtrig_tx);

static void at76_ledtrig_tx_timerfunc(struct timer_list *unused)
{}

static void at76_ledtrig_tx_activity(void)
{}

static int at76_remap(struct usb_device *udev)
{}

static int at76_get_op_mode(struct usb_device *udev)
{}

/* Load a block of the second ("external") part of the firmware */
static inline int at76_load_ext_fw_block(struct usb_device *udev, int blockno,
					 void *block, int size)
{}

static inline int at76_get_hw_cfg(struct usb_device *udev,
				  union at76_hwcfg *buf, int buf_size)
{}

/* Intersil boards use a different "value" for GetHWConfig requests */
static inline int at76_get_hw_cfg_intersil(struct usb_device *udev,
					   union at76_hwcfg *buf, int buf_size)
{}

/* Get the hardware configuration for the adapter and put it to the appropriate
 * fields of 'priv' (the GetHWConfig request and interpretation of the result
 * depends on the board type) */
static int at76_get_hw_config(struct at76_priv *priv)
{}

static struct reg_domain const *at76_get_reg_domain(u16 code)
{}

static inline int at76_get_mib(struct usb_device *udev, u16 mib, void *buf,
			       int buf_size)
{}

/* Return positive number for status, negative for an error */
static inline int at76_get_cmd_status(struct usb_device *udev, u8 cmd)
{}

#define MAKE_CMD_CASE(c)
static const char *at76_get_cmd_string(u8 cmd_status)
{}

static int at76_set_card_command(struct usb_device *udev, u8 cmd, void *buf,
				 int buf_size)
{}

#define MAKE_CMD_STATUS_CASE(c)
static const char *at76_get_cmd_status_string(u8 cmd_status)
{}

/* Wait until the command is completed */
static int at76_wait_completion(struct at76_priv *priv, int cmd)
{}

static int at76_set_mib(struct at76_priv *priv, struct set_mib_buffer *buf)
{}

/* Return < 0 on error, == 0 if no command sent, == 1 if cmd sent */
static int at76_set_radio(struct at76_priv *priv, int enable)
{}

/* Set current power save mode (AT76_PM_OFF/AT76_PM_ON/AT76_PM_SMART) */
static int at76_set_pm_mode(struct at76_priv *priv)
{}

static int at76_set_preamble(struct at76_priv *priv, u8 type)
{}

static int at76_set_frag(struct at76_priv *priv, u16 size)
{}

static int at76_set_rts(struct at76_priv *priv, u16 size)
{}

static int at76_set_autorate_fallback(struct at76_priv *priv, int onoff)
{}

static void at76_dump_mib_mac_addr(struct at76_priv *priv)
{}

static void at76_dump_mib_mac_wep(struct at76_priv *priv)
{}

static void at76_dump_mib_mac_mgmt(struct at76_priv *priv)
{}

static void at76_dump_mib_mac(struct at76_priv *priv)
{}

static void at76_dump_mib_phy(struct at76_priv *priv)
{}

static void at76_dump_mib_local(struct at76_priv *priv)
{}

static void at76_dump_mib_mdomain(struct at76_priv *priv)
{}

/* Enable monitor mode */
static int at76_start_monitor(struct at76_priv *priv)
{}

/* Calculate padding from txbuf->wlength (which excludes the USB TX header),
   likely to compensate a flaw in the AT76C503A USB part ... */
static inline int at76_calc_padding(int wlen)
{}

static void at76_rx_callback(struct urb *urb)
{}

static int at76_submit_rx_urb(struct at76_priv *priv)
{}

/* Download external firmware */
static int at76_load_external_fw(struct usb_device *udev, struct fwentry *fwe)
{}

/* Download internal firmware */
static int at76_load_internal_fw(struct usb_device *udev, struct fwentry *fwe)
{}

static int at76_startup_device(struct at76_priv *priv)
{}

/* Enable or disable promiscuous mode */
static void at76_work_set_promisc(struct work_struct *work)
{}

/* Submit Rx urb back to the device */
static void at76_work_submit_rx(struct work_struct *work)
{}

/* This is a workaround to make scan working:
 * currently mac80211 does not process frames with no frequency
 * information.
 * However during scan the HW performs a sweep by itself, and we
 * are unable to know where the radio is actually tuned.
 * This function tries to do its best to guess this information..
 * During scan, If the current frame is a beacon or a probe response,
 * the channel information is extracted from it.
 * When not scanning, for other frames, or if it happens that for
 * whatever reason we fail to parse beacons and probe responses, this
 * function returns the priv->channel information, that should be correct
 * at least when we are not scanning.
 */
static inline int at76_guess_freq(struct at76_priv *priv)
{}

static void at76_rx_tasklet(struct tasklet_struct *t)
{}

/* Load firmware into kernel memory and parse it */
static struct fwentry *at76_load_firmware(struct usb_device *udev,
					  enum board_type board_type)
{}

static int at76_join(struct at76_priv *priv)
{}

static void at76_work_join_bssid(struct work_struct *work)
{}

static void at76_mac80211_tx_callback(struct urb *urb)
{}

static void at76_mac80211_tx(struct ieee80211_hw *hw,
			     struct ieee80211_tx_control *control,
			     struct sk_buff *skb)
{}

static int at76_mac80211_start(struct ieee80211_hw *hw)
{}

static void at76_mac80211_stop(struct ieee80211_hw *hw, bool suspend)
{}

static int at76_add_interface(struct ieee80211_hw *hw,
			      struct ieee80211_vif *vif)
{}

static void at76_remove_interface(struct ieee80211_hw *hw,
				  struct ieee80211_vif *vif)
{}

static void at76_dwork_hw_scan(struct work_struct *work)
{}

static int at76_hw_scan(struct ieee80211_hw *hw,
			struct ieee80211_vif *vif,
			struct ieee80211_scan_request *hw_req)
{}

static int at76_config(struct ieee80211_hw *hw, u32 changed)
{}

static void at76_bss_info_changed(struct ieee80211_hw *hw,
				  struct ieee80211_vif *vif,
				  struct ieee80211_bss_conf *conf,
				  u64 changed)
{}

/* must be atomic */
static void at76_configure_filter(struct ieee80211_hw *hw,
				  unsigned int changed_flags,
				  unsigned int *total_flags, u64 multicast)
{}

static int at76_set_wep(struct at76_priv *priv)
{}

static int at76_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
			struct ieee80211_vif *vif, struct ieee80211_sta *sta,
			struct ieee80211_key_conf *key)
{}

static const struct ieee80211_ops at76_ops =;

/* Allocate network device and initialize private data */
static struct at76_priv *at76_alloc_new_device(struct usb_device *udev)
{}

static int at76_alloc_urbs(struct at76_priv *priv,
			   struct usb_interface *interface)
{}

static struct ieee80211_rate at76_rates[] =;

static struct ieee80211_channel at76_channels[] =;

static struct ieee80211_supported_band at76_supported_band =;

/* Register network device and initialize the hardware */
static int at76_init_new_device(struct at76_priv *priv,
				struct usb_interface *interface)
{}

static void at76_delete_device(struct at76_priv *priv)
{}

static int at76_probe(struct usb_interface *interface,
		      const struct usb_device_id *id)
{}

static void at76_disconnect(struct usb_interface *interface)
{}

/* Structure for registering this driver with the USB subsystem */
static struct usb_driver at76_driver =;

static int __init at76_mod_init(void)
{}

static void __exit at76_mod_exit(void)
{}

module_param_named(debug, at76_debug, uint, 0600);
MODULE_PARM_DESC();

module_init();
module_exit(at76_mod_exit);

MODULE_AUTHOR();
MODULE_AUTHOR();
MODULE_AUTHOR();
MODULE_AUTHOR();
MODULE_AUTHOR();
MODULE_AUTHOR();
MODULE_AUTHOR();
MODULE_AUTHOR();
MODULE_AUTHOR();
MODULE_DESCRIPTION();
MODULE_LICENSE();