/* * TX/RX related routines. */ static int rt2x00_start_xmit(struct rtskb *rtskb, struct rtnet_device *rtnet_dev) { struct rtwlan_device * rtwlan_dev = rtnetdev_priv(rtnet_dev); struct _rt2x00_core * core = rtwlan_priv(rtwlan_dev); u16 xmit_flags = 0x0000; u8 rate = 0x00; if (unlikely(rtskb)) { rate = core->config.bitrate; if(ieee80211_is_ofdm_rate(rate)) xmit_flags |= XMIT_OFDM; /* Check if the packet should be acknowledged */ if(core->rtwlan_dev->mode == RTWLAN_TXMODE_ACK) xmit_flags |= XMIT_ACK; if(core->handler->dev_xmit_packet(core, rtskb, rate, xmit_flags)) ERROR("Packet dropped !"); dev_kfree_rtskb(rtskb); } return 0; }
/*** * rt2x00_close * @rtdev */ static int rt2x00_close (struct rtnet_device *rtnet_dev) { struct rtwlan_device * rtwlan_dev = rtnetdev_priv(rtnet_dev); struct _rt2x00_core * core = rtwlan_priv(rtwlan_dev); DEBUG("Start.\n"); if(!test_and_clear_bit(DEVICE_ENABLED, &core->flags)){ ERROR("device already disabled.\n"); return -EBUSY; } rt2x00_radio_off(core); rtnetif_stop_queue(rtnet_dev); rt_stack_disconnect(rtnet_dev); RTNET_MOD_DEC_USE_COUNT; return 0; }
int rt2x00_interrupt(rtdm_irq_t *irq_handle) { nanosecs_t time_stamp = rtdm_clock_read(); struct rtnet_device * rtnet_dev = rtdm_irq_get_arg(irq_handle, struct rtnet_device); struct _rt2x00_device * device = rtwlan_priv(rtnet_dev); struct _rt2x00_pci * rt2x00pci = rt2x00_priv(device); struct rtwlan_device * rtwlan = rtnetdev_priv(rtnet_dev); unsigned int old_packet_cnt = rtwlan->stats.rx_packets; u32 reg = 0x00000000; rtdm_lockctx_t context; rtdm_lock_get_irqsave(&rtwlan->lock, context); rt2x00_register_read(rt2x00pci, CSR7, ®); rt2x00_register_write(rt2x00pci, CSR7, reg); if(!reg) return RTDM_IRQ_NONE; if(rt2x00_get_field32(reg, CSR7_TBCN_EXPIRE)) /* Beacon timer expired interrupt. */ DEBUG("Beacon timer expired.\n"); if(rt2x00_get_field32(reg, CSR7_RXDONE)) /* Rx ring done interrupt. */ rt2x00_interrupt_rxdone(&rt2x00pci->rx, &time_stamp); if(rt2x00_get_field32(reg, CSR7_TXDONE_ATIMRING)) /* Atim ring transmit done interrupt. */ DEBUG("AtimTxDone.\n"); if(rt2x00_get_field32(reg, CSR7_TXDONE_PRIORING)) /* Priority ring transmit done interrupt. */ DEBUG("PrioTxDone.\n"); if(rt2x00_get_field32(reg, CSR7_TXDONE_TXRING)) /* Tx ring transmit done interrupt. */ rt2x00_interrupt_txdone(&rt2x00pci->tx); if (old_packet_cnt != rtwlan->stats.rx_packets) rt_mark_stack_mgr(rtnet_dev); rtdm_lock_put_irqrestore(&rtwlan->lock, context); return RTDM_IRQ_HANDLED; }
/*** * rt2x00_open * @rtdev */ static int rt2x00_open (struct rtnet_device *rtnet_dev) { struct rtwlan_device * rtwlan_dev = rtnetdev_priv(rtnet_dev); struct _rt2x00_core * core = rtwlan_priv(rtwlan_dev); int status = 0x00000000; DEBUG("Start.\n"); if(test_and_set_bit(DEVICE_ENABLED, &core->flags)){ ERROR("device already enabled.\n"); return -EBUSY; } /* * Start rtnet interface. */ rt_stack_connect(rtnet_dev, &STACK_manager); status = rt2x00_radio_on(core); if(status){ clear_bit(DEVICE_ENABLED, &core->flags); ERROR("Couldn't activate radio.\n"); return status; } core->config.led_status = 1; core->config.update_flags |= UPDATE_LED_STATUS; rt2x00_update_config(core); rtnetif_start_queue(rtnet_dev); RTNET_MOD_INC_USE_COUNT; DEBUG("Exit success.\n"); return 0; }
struct rtnet_device * rt2x00_core_probe(struct _rt2x00_dev_handler * handler, void * priv, u32 sizeof_dev) { struct rtnet_device * rtnet_dev = NULL; struct _rt2x00_core * core = NULL; struct rtwlan_device * rtwlan_dev = NULL; static int cards_found = -1; int err; DEBUG("Start.\n"); cards_found++; if (cards[cards_found] == 0) goto exit; rtnet_dev = rtwlan_alloc_dev(sizeof_dev + sizeof(*core)); if(!rtnet_dev) goto exit; rt_rtdev_connect(rtnet_dev, &RTDEV_manager); RTNET_SET_MODULE_OWNER(rtnet_dev); rtnet_dev->vers = RTDEV_VERS_2_0; rtwlan_dev = rtnetdev_priv(rtnet_dev); memset(rtwlan_dev, 0x00, sizeof(*rtwlan_dev)); core = rtwlan_priv(rtwlan_dev); memset(core, 0x00, sizeof(*core)); core->rtwlan_dev = rtwlan_dev; core->handler = handler; core->priv = (void*)core + sizeof(*core); core->rtnet_dev = rtnet_dev; if (rtskb_pool_init(&core->rtwlan_dev->skb_pool, RX_ENTRIES*2) < RX_ENTRIES*2) { rtskb_pool_release(&core->rtwlan_dev->skb_pool); ERROR("rtskb_pool_init failed.\n"); goto exit; } /* Set configuration default values. */ rt2x00_init_config(core); if(core->handler->dev_probe && core->handler->dev_probe(core, priv)){ ERROR("device probe failed.\n"); goto exit; } INFO("Device " MAC_FMT " detected.\n", MAC_ARG(rtnet_dev->dev_addr)); rtwlan_dev->hard_start_xmit = rt2x00_start_xmit; rtnet_dev->open = &rt2x00_open; rtnet_dev->stop = &rt2x00_close; rtnet_dev->do_ioctl = &rt2x00_ioctl; rtnet_dev->hard_header = &rt_eth_header; if ((err = rt_register_rtnetdev(rtnet_dev)) != 0) { rtdev_free(rtnet_dev); ERROR("rtnet_device registration failed.\n"); printk("err=%d\n", err); goto exit_dev_remove; } set_bit(DEVICE_AWAKE, &core->flags); return rtnet_dev; exit_dev_remove: if(core->handler->dev_remove) core->handler->dev_remove(core); exit: return NULL; }
/* * user space io handler */ static int rt2x00_ioctl(struct rtnet_device * rtnet_dev, unsigned int request, void * arg) { struct rtwlan_device * rtwlan_dev = rtnetdev_priv(rtnet_dev); struct _rt2x00_core * core = rtwlan_priv(rtwlan_dev); struct rtwlan_cmd * cmd; u8 rate, dsss_rate, ofdm_rate; u32 address, value; cmd = (struct rtwlan_cmd *)arg; switch(request) { case IOC_RTWLAN_IFINFO: cmd->args.info.bitrate = core->config.bitrate; cmd->args.info.channel = core->config.channel; cmd->args.info.retry = core->config.short_retry; cmd->args.info.txpower = core->config.txpower; cmd->args.info.bbpsens = core->config.bbpsens; cmd->args.info.mode = core->rtwlan_dev->mode; cmd->args.info.rx_packets = core->rtwlan_dev->stats.rx_packets; cmd->args.info.tx_packets = core->rtwlan_dev->stats.tx_packets; cmd->args.info.tx_retry = core->rtwlan_dev->stats.tx_retry; cmd->args.info.autoresponder = core->config.config_flags & CONFIG_AUTORESP ? 1 : 0; cmd->args.info.dropbcast = core->config.config_flags & CONFIG_DROP_BCAST ? 1 : 0; cmd->args.info.dropmcast = core->config.config_flags & CONFIG_DROP_MCAST ? 1 : 0; DEBUG("rtwlan_dev->mode=%d\n", rtwlan_dev->mode); break; case IOC_RTWLAN_BITRATE: rate = cmd->args.set.bitrate; ofdm_rate = ieee80211_is_ofdm_rate(rate); dsss_rate = ieee80211_is_dsss_rate(rate); DEBUG("bitrate=%d\n", rate); if(!(dsss_rate ^ ofdm_rate)) NOTICE("Rate %d is not DSSS and not OFDM.\n", rate); core->config.bitrate = rate; core->config.update_flags |= UPDATE_BITRATE; break; case IOC_RTWLAN_CHANNEL: DEBUG("channel=%d\n", cmd->args.set.channel); core->config.channel = cmd->args.set.channel; core->config.update_flags |= UPDATE_CHANNEL; break; case IOC_RTWLAN_RETRY: core->config.short_retry = cmd->args.set.retry; core->config.update_flags |= UPDATE_RETRY; break; case IOC_RTWLAN_TXPOWER: core->config.txpower = cmd->args.set.txpower; core->config.update_flags |= UPDATE_TXPOWER; break; case IOC_RTWLAN_AUTORESP: if(cmd->args.set.autoresponder) core->config.config_flags |= CONFIG_AUTORESP; else core->config.config_flags &= ~CONFIG_AUTORESP; core->config.update_flags |= UPDATE_AUTORESP; break; case IOC_RTWLAN_DROPBCAST: if(cmd->args.set.dropbcast) core->config.config_flags |= CONFIG_DROP_BCAST; else core->config.config_flags &= ~CONFIG_DROP_BCAST; core->config.update_flags |= UPDATE_PACKET_FILTER; break; case IOC_RTWLAN_DROPMCAST: if(cmd->args.set.dropmcast) core->config.config_flags |= CONFIG_DROP_MCAST; else core->config.config_flags &= ~CONFIG_DROP_MCAST; core->config.update_flags |= UPDATE_PACKET_FILTER; break; case IOC_RTWLAN_TXMODE: core->rtwlan_dev->mode = cmd->args.set.mode; break; case IOC_RTWLAN_BBPSENS: value = cmd->args.set.bbpsens; if(value < 0) value = 0; if(value > 127) value = 127; core->config.bbpsens = value; core->config.update_flags |= UPDATE_BBPSENS; break; case IOC_RTWLAN_REGREAD: case IOC_RTWLAN_BBPREAD: address = cmd->args.reg.address; core->handler->dev_register_access(core, request, address, &value); cmd->args.reg.value = value; break; case IOC_RTWLAN_REGWRITE: case IOC_RTWLAN_BBPWRITE: address = cmd->args.reg.address; value = cmd->args.reg.value; core->handler->dev_register_access(core, request, address, &value) ; break; default: ERROR("Unknown request!\n"); return -1; } if(request != IOC_RTWLAN_IFINFO) rt2x00_update_config(core); return 0; }