static void smsnet_set_multicast_list(struct net_device *dev) { #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 34) int mc_count = netdev_mc_count(dev); sms_info("mc count %d", mc_count); if (!netdev_mc_empty(dev)) { struct netdev_hw_addr *ha; netdev_for_each_mc_addr(ha, dev) sms_info( "%02x %02x %02x %02x %02x %02x %02x %02x", ha->addr[0], ha->addr[1], ha->addr[2], ha->addr[3], ha->addr[4], ha->addr[5], ha->addr[6], ha->addr[7] ); } #else sms_info("mc count %d", dev->mc_count); if (dev->mc_count) { struct dev_mc_list *p; for (p = dev->mc_list; p; p = p->next) sms_info( "%d %02x %02x %02x %02x %02x %02x %02x %02x", p->dmi_addrlen, p->dmi_addr[0], p->dmi_addr[1], p->dmi_addr[2], p->dmi_addr[3], p->dmi_addr[4], p->dmi_addr[5], p->dmi_addr[6], p->dmi_addr[7] ); } #endif }
static void elp_set_mc_list(struct net_device *dev) { elp_device *adapter = netdev_priv(dev); struct netdev_hw_addr *ha; int i; unsigned long flags; if (elp_debug >= 3) pr_debug("%s: request to set multicast list\n", dev->name); spin_lock_irqsave(&adapter->lock, flags); if (!(dev->flags & (IFF_PROMISC | IFF_ALLMULTI))) { /* send a "load multicast list" command to the board, max 10 addrs/cmd */ /* if num_addrs==0 the list will be cleared */ adapter->tx_pcb.command = CMD_LOAD_MULTICAST_LIST; adapter->tx_pcb.length = 6 * netdev_mc_count(dev); i = 0; netdev_for_each_mc_addr(ha, dev) memcpy(adapter->tx_pcb.data.multicast[i++], ha->addr, 6); adapter->got[CMD_LOAD_MULTICAST_LIST] = 0; if (!send_pcb(dev, &adapter->tx_pcb)) pr_err("%s: couldn't send set_multicast command\n", dev->name); else { unsigned long timeout = jiffies + TIMEOUT; while (adapter->got[CMD_LOAD_MULTICAST_LIST] == 0 && time_before(jiffies, timeout)); if (time_after_eq(jiffies, timeout)) { TIMEOUT_MSG(__LINE__); } } if (!netdev_mc_empty(dev)) adapter->tx_pcb.data.configure = NO_LOOPBACK | RECV_BROAD | RECV_MULTI; else /* num_addrs == 0 */ adapter->tx_pcb.data.configure = NO_LOOPBACK | RECV_BROAD; } else adapter->tx_pcb.data.configure = NO_LOOPBACK | RECV_PROMISC; /* * configure adapter to receive messages (as specified above) * and wait for response */ if (elp_debug >= 3) pr_debug("%s: sending 82586 configure command\n", dev->name); adapter->tx_pcb.command = CMD_CONFIGURE_82586; adapter->tx_pcb.length = 2; adapter->got[CMD_CONFIGURE_82586] = 0; if (!send_pcb(dev, &adapter->tx_pcb)) { spin_unlock_irqrestore(&adapter->lock, flags); pr_err("%s: couldn't send 82586 configure command\n", dev->name); } else { unsigned long timeout = jiffies + TIMEOUT; spin_unlock_irqrestore(&adapter->lock, flags); while (adapter->got[CMD_CONFIGURE_82586] == 0 && time_before(jiffies, timeout)); if (time_after_eq(jiffies, timeout)) TIMEOUT_MSG(__LINE__); } }
/* * Copies the multicast address list from device to driver. * * This function does not validate the destination memory for * size, and the calling function must ensure enough memory is * available. */ int mwifiex_copy_mcast_addr(struct mwifiex_multicast_list *mlist, struct net_device *dev) { int i = 0; struct netdev_hw_addr *ha; netdev_for_each_mc_addr(ha, dev) memcpy(&mlist->mac_list[i++], ha->addr, ETH_ALEN); return i; }
static void set_multicast_list(struct net_device *dev) { struct netdev_hw_addr *ha; if ((dev->flags & IFF_PROMISC) == 0) { set_multicast_start(dev); netdev_for_each_mc_addr(ha, dev) set_multicast_one(dev, ha->addr); set_multicast_finish(dev); } else set_promiscuous_mode(dev); }
/* * Copies the multicast address list from device to driver. * * This function does not validate the destination memory for * size, and the calling function must ensure enough memory is * available. */ int mwifiex_copy_mcast_addr(struct mwifiex_multicast_list *mlist, struct net_device *dev) { int i = 0; struct netdev_hw_addr *ha; netdev_for_each_mc_addr(ha, dev) #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35)) memcpy(&mlist->mac_list[i++], ha->addr, ETH_ALEN); #else memcpy(&mlist->mac_list[i++], ha->dmi_addr, ETH_ALEN); #endif return i; }
static int init586(struct net_device *dev) { void *ptr; int i,result=0; struct priv *p = netdev_priv(dev); volatile struct configure_cmd_struct *cfg_cmd; volatile struct iasetup_cmd_struct *ias_cmd; volatile struct tdr_cmd_struct *tdr_cmd; volatile struct mcsetup_cmd_struct *mc_cmd; struct netdev_hw_addr *ha; int num_addrs=netdev_mc_count(dev); ptr = (void *) ((char *)p->scb + sizeof(struct scb_struct)); cfg_cmd = (struct configure_cmd_struct *)ptr; /* configure-command */ cfg_cmd->cmd_status = 0; cfg_cmd->cmd_cmd = swab16(CMD_CONFIGURE | CMD_LAST); cfg_cmd->cmd_link = 0xffff; cfg_cmd->byte_cnt = 0x0a; /* number of cfg bytes */ cfg_cmd->fifo = fifo; /* fifo-limit (8=tx:32/rx:64) */ cfg_cmd->sav_bf = 0x40; /* hold or discard bad recv frames (bit 7) */ cfg_cmd->adr_len = 0x2e; /* addr_len |!src_insert |pre-len |loopback */ cfg_cmd->priority = 0x00; cfg_cmd->ifs = 0x60; cfg_cmd->time_low = 0x00; cfg_cmd->time_high = 0xf2; cfg_cmd->promisc = 0; if(dev->flags & IFF_ALLMULTI) { int len = ((char *) p->iscp - (char *) ptr - 8) / 6; if(num_addrs > len) { printk("%s: switching to promisc. mode\n",dev->name); cfg_cmd->promisc = 1; } } if(dev->flags&IFF_PROMISC) cfg_cmd->promisc = 1; cfg_cmd->carr_coll = 0x00; p->scb->cbl_offset = make16(cfg_cmd); p->scb->cmd_ruc = 0; p->scb->cmd_cuc = CUC_START; /* cmd.-unit start */ sun3_attn586(); WAIT_4_STAT_COMPL(cfg_cmd); if((swab16(cfg_cmd->cmd_status) & (STAT_OK|STAT_COMPL)) != (STAT_COMPL|STAT_OK)) { printk("%s: configure command failed: %x\n",dev->name,swab16(cfg_cmd->cmd_status)); return 1; } /* * individual address setup */ ias_cmd = (struct iasetup_cmd_struct *)ptr; ias_cmd->cmd_status = 0; ias_cmd->cmd_cmd = swab16(CMD_IASETUP | CMD_LAST); ias_cmd->cmd_link = 0xffff; memcpy((char *)&ias_cmd->iaddr,(char *) dev->dev_addr,ETH_ALEN); p->scb->cbl_offset = make16(ias_cmd); p->scb->cmd_cuc = CUC_START; /* cmd.-unit start */ sun3_attn586(); WAIT_4_STAT_COMPL(ias_cmd); if((swab16(ias_cmd->cmd_status) & (STAT_OK|STAT_COMPL)) != (STAT_OK|STAT_COMPL)) { printk("%s (82586): individual address setup command failed: %04x\n",dev->name,swab16(ias_cmd->cmd_status)); return 1; } /* * TDR, wire check .. e.g. no resistor e.t.c */ tdr_cmd = (struct tdr_cmd_struct *)ptr; tdr_cmd->cmd_status = 0; tdr_cmd->cmd_cmd = swab16(CMD_TDR | CMD_LAST); tdr_cmd->cmd_link = 0xffff; tdr_cmd->status = 0; p->scb->cbl_offset = make16(tdr_cmd); p->scb->cmd_cuc = CUC_START; /* cmd.-unit start */ sun3_attn586(); WAIT_4_STAT_COMPL(tdr_cmd); if(!(swab16(tdr_cmd->cmd_status) & STAT_COMPL)) { printk("%s: Problems while running the TDR.\n",dev->name); } else { DELAY_16(); /* wait for result */ result = swab16(tdr_cmd->status); p->scb->cmd_cuc = p->scb->cus & STAT_MASK; sun3_attn586(); /* ack the interrupts */ if(result & TDR_LNK_OK) ; else if(result & TDR_XCVR_PRB) printk("%s: TDR: Transceiver problem. Check the cable(s)!\n",dev->name); else if(result & TDR_ET_OPN) printk("%s: TDR: No correct termination %d clocks away.\n",dev->name,result & TDR_TIMEMASK); else if(result & TDR_ET_SRT) { if (result & TDR_TIMEMASK) /* time == 0 -> strange :-) */ printk("%s: TDR: Detected a short circuit %d clocks away.\n",dev->name,result & TDR_TIMEMASK); } else printk("%s: TDR: Unknown status %04x\n",dev->name,result); } /* * Multicast setup */ if(num_addrs && !(dev->flags & IFF_PROMISC) ) { mc_cmd = (struct mcsetup_cmd_struct *) ptr; mc_cmd->cmd_status = 0; mc_cmd->cmd_cmd = swab16(CMD_MCSETUP | CMD_LAST); mc_cmd->cmd_link = 0xffff; mc_cmd->mc_cnt = swab16(num_addrs * 6); i = 0; netdev_for_each_mc_addr(ha, dev) memcpy((char *) mc_cmd->mc_list[i++], ha->addr, ETH_ALEN); p->scb->cbl_offset = make16(mc_cmd); p->scb->cmd_cuc = CUC_START; sun3_attn586(); WAIT_4_STAT_COMPL(mc_cmd); if( (swab16(mc_cmd->cmd_status) & (STAT_COMPL|STAT_OK)) != (STAT_COMPL|STAT_OK) ) printk("%s: Can't apply multicast-address-list.\n",dev->name); } /* * alloc nop/xmit-cmds */ #if (NUM_XMIT_BUFFS == 1) for(i=0;i<2;i++) { p->nop_cmds[i] = (struct nop_cmd_struct *)ptr; p->nop_cmds[i]->cmd_cmd = swab16(CMD_NOP); p->nop_cmds[i]->cmd_status = 0; p->nop_cmds[i]->cmd_link = make16((p->nop_cmds[i])); ptr = (char *) ptr + sizeof(struct nop_cmd_struct); } #else for(i=0;i<NUM_XMIT_BUFFS;i++) { p->nop_cmds[i] = (struct nop_cmd_struct *)ptr; p->nop_cmds[i]->cmd_cmd = swab16(CMD_NOP); p->nop_cmds[i]->cmd_status = 0; p->nop_cmds[i]->cmd_link = make16((p->nop_cmds[i])); ptr = (char *) ptr + sizeof(struct nop_cmd_struct); } #endif ptr = alloc_rfa(dev,(void *)ptr); /* init receive-frame-area */ /* * alloc xmit-buffs / init xmit_cmds */ for(i=0;i<NUM_XMIT_BUFFS;i++) { p->xmit_cmds[i] = (struct transmit_cmd_struct *)ptr; /*transmit cmd/buff 0*/ ptr = (char *) ptr + sizeof(struct transmit_cmd_struct); p->xmit_cbuffs[i] = (char *)ptr; /* char-buffs */ ptr = (char *) ptr + XMIT_BUFF_SIZE; p->xmit_buffs[i] = (struct tbd_struct *)ptr; /* TBD */ ptr = (char *) ptr + sizeof(struct tbd_struct); if((void *)ptr > (void *)dev->mem_end) { printk("%s: not enough shared-mem for your configuration!\n",dev->name); return 1; } memset((char *)(p->xmit_cmds[i]) ,0, sizeof(struct transmit_cmd_struct)); memset((char *)(p->xmit_buffs[i]),0, sizeof(struct tbd_struct)); p->xmit_cmds[i]->cmd_link = make16(p->nop_cmds[(i+1)%NUM_XMIT_BUFFS]); p->xmit_cmds[i]->cmd_status = swab16(STAT_COMPL); p->xmit_cmds[i]->cmd_cmd = swab16(CMD_XMIT | CMD_INT); p->xmit_cmds[i]->tbd_offset = make16((p->xmit_buffs[i])); p->xmit_buffs[i]->next = 0xffff; p->xmit_buffs[i]->buffer = make24((p->xmit_cbuffs[i])); } p->xmit_count = 0; p->xmit_last = 0; #ifndef NO_NOPCOMMANDS p->nop_point = 0; #endif /* * 'start transmitter' */ #ifndef NO_NOPCOMMANDS p->scb->cbl_offset = make16(p->nop_cmds[0]); p->scb->cmd_cuc = CUC_START; sun3_attn586(); WAIT_4_SCB_CMD(); #else p->xmit_cmds[0]->cmd_link = make16(p->xmit_cmds[0]); p->xmit_cmds[0]->cmd_cmd = swab16(CMD_XMIT | CMD_SUSPEND | CMD_INT); #endif /* * ack. interrupts */ p->scb->cmd_cuc = p->scb->cus & STAT_MASK; sun3_attn586(); DELAY_16(); sun3_enaint(); sun3_active(); return 0; }
/* * Proc info file read handler. * * This function is called when the 'info' file is opened for reading. * It prints the following driver related information - * - Driver name * - Driver version * - Driver extended version * - Interface name * - BSS mode * - Media state (connected or disconnected) * - MAC address * - Total number of Tx bytes * - Total number of Rx bytes * - Total number of Tx packets * - Total number of Rx packets * - Total number of dropped Tx packets * - Total number of dropped Rx packets * - Total number of corrupted Tx packets * - Total number of corrupted Rx packets * - Carrier status (on or off) * - Tx queue status (started or stopped) * * For STA mode drivers, it also prints the following extra - * - ESSID * - BSSID * - Channel * - Region code * - Multicast count * - Multicast addresses */ static ssize_t mwifiex_info_read(struct file *file, char __user *ubuf, size_t count, loff_t *ppos) { struct mwifiex_private *priv = (struct mwifiex_private *) file->private_data; struct net_device *netdev = priv->netdev; struct netdev_hw_addr *ha; struct netdev_queue *txq; unsigned long page = get_zeroed_page(GFP_KERNEL); char *p = (char *) page, fmt[64]; struct mwifiex_bss_info info; ssize_t ret; int i = 0; if (!p) return -ENOMEM; memset(&info, 0, sizeof(info)); ret = mwifiex_get_bss_info(priv, &info); if (ret) goto free_and_exit; mwifiex_drv_get_driver_version(priv->adapter, fmt, sizeof(fmt) - 1); if (!priv->version_str[0]) mwifiex_get_ver_ext(priv); p += sprintf(p, "driver_name = " "\"mwifiex\"\n"); p += sprintf(p, "driver_version = %s", fmt); p += sprintf(p, "\nverext = %s", priv->version_str); p += sprintf(p, "\ninterface_name=\"%s\"\n", netdev->name); if (info.bss_mode >= ARRAY_SIZE(bss_modes)) p += sprintf(p, "bss_mode=\"%d\"\n", info.bss_mode); else p += sprintf(p, "bss_mode=\"%s\"\n", bss_modes[info.bss_mode]); p += sprintf(p, "media_state=\"%s\"\n", (!priv->media_connected ? "Disconnected" : "Connected")); p += sprintf(p, "mac_address=\"%pM\"\n", netdev->dev_addr); if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA) { p += sprintf(p, "multicast_count=\"%d\"\n", netdev_mc_count(netdev)); p += sprintf(p, "essid=\"%s\"\n", info.ssid.ssid); p += sprintf(p, "bssid=\"%pM\"\n", info.bssid); p += sprintf(p, "channel=\"%d\"\n", (int) info.bss_chan); p += sprintf(p, "country_code = \"%s\"\n", info.country_code); netdev_for_each_mc_addr(ha, netdev) p += sprintf(p, "multicast_address[%d]=\"%pM\"\n", i++, ha->addr); } p += sprintf(p, "num_tx_bytes = %lu\n", priv->stats.tx_bytes); p += sprintf(p, "num_rx_bytes = %lu\n", priv->stats.rx_bytes); p += sprintf(p, "num_tx_pkts = %lu\n", priv->stats.tx_packets); p += sprintf(p, "num_rx_pkts = %lu\n", priv->stats.rx_packets); p += sprintf(p, "num_tx_pkts_dropped = %lu\n", priv->stats.tx_dropped); p += sprintf(p, "num_rx_pkts_dropped = %lu\n", priv->stats.rx_dropped); p += sprintf(p, "num_tx_pkts_err = %lu\n", priv->stats.tx_errors); p += sprintf(p, "num_rx_pkts_err = %lu\n", priv->stats.rx_errors); p += sprintf(p, "carrier %s\n", ((netif_carrier_ok(priv->netdev)) ? "on" : "off")); p += sprintf(p, "tx queue"); for (i = 0; i < netdev->num_tx_queues; i++) { txq = netdev_get_tx_queue(netdev, i); p += sprintf(p, " %d:%s", i, netif_tx_queue_stopped(txq) ? "stopped" : "started"); } p += sprintf(p, "\n"); ret = simple_read_from_buffer(ubuf, count, ppos, (char *) page, (unsigned long) p - page); free_and_exit: free_page(page); return ret; }
static int init586(struct net_device *dev) { void __iomem *ptr; int i, result = 0; struct priv *p = netdev_priv(dev); struct configure_cmd_struct __iomem *cfg_cmd; struct iasetup_cmd_struct __iomem *ias_cmd; struct tdr_cmd_struct __iomem *tdr_cmd; struct mcsetup_cmd_struct __iomem *mc_cmd; struct netdev_hw_addr *ha; int num_addrs = netdev_mc_count(dev); ptr = p->scb + 1; cfg_cmd = ptr; /* */ writew(0, &cfg_cmd->cmd_status); writew(CMD_CONFIGURE | CMD_LAST, &cfg_cmd->cmd_cmd); writew(0xFFFF, &cfg_cmd->cmd_link); /* */ writeb(0x0a, &cfg_cmd->byte_cnt); /* */ writeb(fifo, &cfg_cmd->fifo); /* */ writeb(0x40, &cfg_cmd->sav_bf); /* */ writeb(0x2e, &cfg_cmd->adr_len); writeb(0x00, &cfg_cmd->priority); writeb(0x60, &cfg_cmd->ifs); writeb(0x00, &cfg_cmd->time_low); writeb(0xf2, &cfg_cmd->time_high); writeb(0x00, &cfg_cmd->promisc); if (dev->flags & IFF_ALLMULTI) { int len = ((char __iomem *)p->iscp - (char __iomem *)ptr - 8) / 6; if (num_addrs > len) { printk(KERN_ERR "%s: switching to promisc. mode\n", dev->name); writeb(0x01, &cfg_cmd->promisc); } } if (dev->flags & IFF_PROMISC) writeb(0x01, &cfg_cmd->promisc); writeb(0x00, &cfg_cmd->carr_coll); writew(make16(cfg_cmd), &p->scb->cbl_offset); writeb(0, &p->scb->cmd_ruc); writeb(CUC_START, &p->scb->cmd_cuc); /* */ ni_attn586(); wait_for_stat_compl(cfg_cmd); if ((readw(&cfg_cmd->cmd_status) & (STAT_OK|STAT_COMPL)) != (STAT_COMPL|STAT_OK)) { printk(KERN_ERR "%s: configure command failed: %x\n", dev->name, readw(&cfg_cmd->cmd_status)); return 1; } /* */ ias_cmd = ptr; writew(0, &ias_cmd->cmd_status); writew(CMD_IASETUP | CMD_LAST, &ias_cmd->cmd_cmd); writew(0xffff, &ias_cmd->cmd_link); memcpy_toio(&ias_cmd->iaddr, (char *)dev->dev_addr, ETH_ALEN); writew(make16(ias_cmd), &p->scb->cbl_offset); writeb(CUC_START, &p->scb->cmd_cuc); /* */ ni_attn586(); wait_for_stat_compl(ias_cmd); if ((readw(&ias_cmd->cmd_status) & (STAT_OK|STAT_COMPL)) != (STAT_OK|STAT_COMPL)) { printk(KERN_ERR "%s (ni52): individual address setup command failed: %04x\n", dev->name, readw(&ias_cmd->cmd_status)); return 1; } /* */ tdr_cmd = ptr; writew(0, &tdr_cmd->cmd_status); writew(CMD_TDR | CMD_LAST, &tdr_cmd->cmd_cmd); writew(0xffff, &tdr_cmd->cmd_link); writew(0, &tdr_cmd->status); writew(make16(tdr_cmd), &p->scb->cbl_offset); writeb(CUC_START, &p->scb->cmd_cuc); /* */ ni_attn586(); wait_for_stat_compl(tdr_cmd); if (!(readw(&tdr_cmd->cmd_status) & STAT_COMPL)) printk(KERN_ERR "%s: Problems while running the TDR.\n", dev->name); else { udelay(16); result = readw(&tdr_cmd->status); writeb(readb(&p->scb->cus) & STAT_MASK, &p->scb->cmd_cuc); ni_attn586(); /* */ if (result & TDR_LNK_OK) ; else if (result & TDR_XCVR_PRB) printk(KERN_ERR "%s: TDR: Transceiver problem. Check the cable(s)!\n", dev->name); else if (result & TDR_ET_OPN) printk(KERN_ERR "%s: TDR: No correct termination %d clocks away.\n", dev->name, result & TDR_TIMEMASK); else if (result & TDR_ET_SRT) { /* */ if (result & TDR_TIMEMASK) printk(KERN_ERR "%s: TDR: Detected a short circuit %d clocks away.\n", dev->name, result & TDR_TIMEMASK); } else printk(KERN_ERR "%s: TDR: Unknown status %04x\n", dev->name, result); } /* */ if (num_addrs && !(dev->flags & IFF_PROMISC)) { mc_cmd = ptr; writew(0, &mc_cmd->cmd_status); writew(CMD_MCSETUP | CMD_LAST, &mc_cmd->cmd_cmd); writew(0xffff, &mc_cmd->cmd_link); writew(num_addrs * 6, &mc_cmd->mc_cnt); i = 0; netdev_for_each_mc_addr(ha, dev) memcpy_toio(mc_cmd->mc_list[i++], ha->addr, 6); writew(make16(mc_cmd), &p->scb->cbl_offset); writeb(CUC_START, &p->scb->cmd_cuc); ni_attn586(); wait_for_stat_compl(mc_cmd); if ((readw(&mc_cmd->cmd_status) & (STAT_COMPL|STAT_OK)) != (STAT_COMPL|STAT_OK)) printk(KERN_ERR "%s: Can't apply multicast-address-list.\n", dev->name); } /* */ #if (NUM_XMIT_BUFFS == 1) for (i = 0; i < 2; i++) { p->nop_cmds[i] = ptr; writew(CMD_NOP, &p->nop_cmds[i]->cmd_cmd); writew(0, &p->nop_cmds[i]->cmd_status); writew(make16(p->nop_cmds[i]), &p->nop_cmds[i]->cmd_link); ptr = ptr + sizeof(struct nop_cmd_struct); } #else for (i = 0; i < NUM_XMIT_BUFFS; i++) { p->nop_cmds[i] = ptr; writew(CMD_NOP, &p->nop_cmds[i]->cmd_cmd); writew(0, &p->nop_cmds[i]->cmd_status); writew(make16(p->nop_cmds[i]), &p->nop_cmds[i]->cmd_link); ptr = ptr + sizeof(struct nop_cmd_struct); } #endif ptr = alloc_rfa(dev, ptr); /* */ /* */ for (i = 0; i < NUM_XMIT_BUFFS; i++) { /* */ p->xmit_cmds[i] = ptr; ptr = ptr + sizeof(struct transmit_cmd_struct); p->xmit_cbuffs[i] = ptr; /* */ ptr = ptr + XMIT_BUFF_SIZE; p->xmit_buffs[i] = ptr; /* */ ptr = ptr + sizeof(struct tbd_struct); if ((void __iomem *)ptr > (void __iomem *)p->iscp) { printk(KERN_ERR "%s: not enough shared-mem for your configuration!\n", dev->name); return 1; } memset_io(p->xmit_cmds[i], 0, sizeof(struct transmit_cmd_struct)); memset_io(p->xmit_buffs[i], 0, sizeof(struct tbd_struct)); writew(make16(p->nop_cmds[(i+1)%NUM_XMIT_BUFFS]), &p->xmit_cmds[i]->cmd_link); writew(STAT_COMPL, &p->xmit_cmds[i]->cmd_status); writew(CMD_XMIT|CMD_INT, &p->xmit_cmds[i]->cmd_cmd); writew(make16(p->xmit_buffs[i]), &p->xmit_cmds[i]->tbd_offset); writew(0xffff, &p->xmit_buffs[i]->next); writel(make24(p->xmit_cbuffs[i]), &p->xmit_buffs[i]->buffer); } p->xmit_count = 0; p->xmit_last = 0; #ifndef NO_NOPCOMMANDS p->nop_point = 0; #endif /* */ #ifndef NO_NOPCOMMANDS writew(make16(p->nop_cmds[0]), &p->scb->cbl_offset); writeb(CUC_START, &p->scb->cmd_cuc); ni_attn586(); wait_for_scb_cmd(dev); #else writew(make16(p->xmit_cmds[0]), &p->xmit_cmds[0]->cmd_link); writew(CMD_XMIT | CMD_SUSPEND | CMD_INT, &p->xmit_cmds[0]->cmd_cmd); #endif /* */ writeb(readb(&p->scb->cus) & STAT_MASK, &p->scb->cmd_cuc); ni_attn586(); udelay(16); ni_enaint(); return 0; }
static void octeon_mgmt_set_rx_filtering(struct net_device *netdev) { struct octeon_mgmt *p = netdev_priv(netdev); union cvmx_agl_gmx_rxx_adr_ctl adr_ctl; union cvmx_agl_gmx_prtx_cfg agl_gmx_prtx; unsigned long flags; unsigned int prev_packet_enable; unsigned int cam_mode = 1; /* 1 - Accept on CAM match */ unsigned int multicast_mode = 1; /* 1 - Reject all multicast. */ struct octeon_mgmt_cam_state cam_state; struct netdev_hw_addr *ha; int available_cam_entries; memset(&cam_state, 0, sizeof(cam_state)); if ((netdev->flags & IFF_PROMISC) || netdev->uc.count > 7) { cam_mode = 0; available_cam_entries = 8; } else { /* One CAM entry for the primary address, leaves seven * for the secondary addresses. */ available_cam_entries = 7 - netdev->uc.count; } if (netdev->flags & IFF_MULTICAST) { if (cam_mode == 0 || (netdev->flags & IFF_ALLMULTI) || netdev_mc_count(netdev) > available_cam_entries) multicast_mode = 2; /* 2 - Accept all multicast. */ else multicast_mode = 0; /* 0 - Use CAM. */ } if (cam_mode == 1) { /* Add primary address. */ octeon_mgmt_cam_state_add(&cam_state, netdev->dev_addr); netdev_for_each_uc_addr(ha, netdev) octeon_mgmt_cam_state_add(&cam_state, ha->addr); } if (multicast_mode == 0) { netdev_for_each_mc_addr(ha, netdev) octeon_mgmt_cam_state_add(&cam_state, ha->addr); } spin_lock_irqsave(&p->lock, flags); /* Disable packet I/O. */ agl_gmx_prtx.u64 = cvmx_read_csr(p->agl + AGL_GMX_PRT_CFG); prev_packet_enable = agl_gmx_prtx.s.en; agl_gmx_prtx.s.en = 0; cvmx_write_csr(p->agl + AGL_GMX_PRT_CFG, agl_gmx_prtx.u64); adr_ctl.u64 = 0; adr_ctl.s.cam_mode = cam_mode; adr_ctl.s.mcst = multicast_mode; adr_ctl.s.bcst = 1; /* Allow broadcast */ cvmx_write_csr(p->agl + AGL_GMX_RX_ADR_CTL, adr_ctl.u64); cvmx_write_csr(p->agl + AGL_GMX_RX_ADR_CAM0, cam_state.cam[0]); cvmx_write_csr(p->agl + AGL_GMX_RX_ADR_CAM1, cam_state.cam[1]); cvmx_write_csr(p->agl + AGL_GMX_RX_ADR_CAM2, cam_state.cam[2]); cvmx_write_csr(p->agl + AGL_GMX_RX_ADR_CAM3, cam_state.cam[3]); cvmx_write_csr(p->agl + AGL_GMX_RX_ADR_CAM4, cam_state.cam[4]); cvmx_write_csr(p->agl + AGL_GMX_RX_ADR_CAM5, cam_state.cam[5]); cvmx_write_csr(p->agl + AGL_GMX_RX_ADR_CAM_EN, cam_state.cam_mask); /* Restore packet I/O. */ agl_gmx_prtx.s.en = prev_packet_enable; cvmx_write_csr(p->agl + AGL_GMX_PRT_CFG, agl_gmx_prtx.u64); spin_unlock_irqrestore(&p->lock, flags); }
/** * @brief Proc read function for info * * @param page Pointer to buffer * @param start Read data starting position * @param offset Offset * @param count Counter * @param eof End of file flag * @param data Data to output * * @return Number of output data */ static int woal_info_proc_read(char *page, char **start, off_t offset, int count, int *eof, void *data) { char *p = page; struct net_device *netdev = data; char fmt[64]; moal_private *priv = (moal_private *) netdev_priv(netdev); #ifdef STA_SUPPORT int i = 0; moal_handle *handle = priv->phandle; mlan_bss_info info; #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,35) struct dev_mc_list *mcptr = netdev->mc_list; int mc_count = netdev->mc_count; #else struct netdev_hw_addr *mcptr = NULL; int mc_count = netdev_mc_count(netdev); #endif /* < 2.6.35 */ #endif #ifdef UAP_SUPPORT mlan_ds_uap_stats ustats; #endif if (offset) { *eof = 1; goto exit; } #ifdef UAP_SUPPORT if (GET_BSS_ROLE(priv) == MLAN_BSS_ROLE_UAP) { p += sprintf(p, "driver_name = " "\"uap\"\n"); woal_uap_get_version(priv, fmt, sizeof(fmt) - 1); if (MLAN_STATUS_SUCCESS != woal_uap_get_stats(priv, MOAL_PROC_WAIT, &ustats)) { *eof = 1; goto exit; } } #endif /* UAP_SUPPORT */ #ifdef STA_SUPPORT if (GET_BSS_ROLE(priv) == MLAN_BSS_ROLE_STA) { woal_get_version(handle, fmt, sizeof(fmt) - 1); memset(&info, 0, sizeof(info)); if (MLAN_STATUS_SUCCESS != woal_get_bss_info(priv, MOAL_PROC_WAIT, &info)) { *eof = 1; goto exit; } p += sprintf(p, "driver_name = " "\"wlan\"\n"); } #endif p += sprintf(p, "driver_version = %s", fmt); p += sprintf(p, "\ninterface_name=\"%s\"\n", netdev->name); #ifdef STA_SUPPORT if (GET_BSS_ROLE(priv) == MLAN_BSS_ROLE_STA) p += sprintf(p, "bss_mode=\"%s\"\n", szModes[info.bss_mode]); #endif p += sprintf(p, "media_state=\"%s\"\n", ((priv->media_connected == MFALSE) ? "Disconnected" : "Connected")); p += sprintf(p, "mac_address=\"%02x:%02x:%02x:%02x:%02x:%02x\"\n", netdev->dev_addr[0], netdev->dev_addr[1], netdev->dev_addr[2], netdev->dev_addr[3], netdev->dev_addr[4], netdev->dev_addr[5]); #ifdef STA_SUPPORT if (GET_BSS_ROLE(priv) == MLAN_BSS_ROLE_STA) { p += sprintf(p, "multicast_count=\"%d\"\n", mc_count); p += sprintf(p, "essid=\"%s\"\n", info.ssid.ssid); p += sprintf(p, "bssid=\"%02x:%02x:%02x:%02x:%02x:%02x\"\n", info.bssid[0], info.bssid[1], info.bssid[2], info.bssid[3], info.bssid[4], info.bssid[5]); p += sprintf(p, "channel=\"%d\"\n", (int) info.bss_chan); p += sprintf(p, "region_code = \"%02x\"\n", (t_u8) info.region_code); /* * Put out the multicast list */ #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,35) for (i = 0; i < netdev->mc_count; i++) { p += sprintf(p, "multicast_address[%d]=\"%02x:%02x:%02x:%02x:%02x:%02x\"\n", i, mcptr->dmi_addr[0], mcptr->dmi_addr[1], mcptr->dmi_addr[2], mcptr->dmi_addr[3], mcptr->dmi_addr[4], mcptr->dmi_addr[5]); mcptr = mcptr->next; } #else netdev_for_each_mc_addr(mcptr, netdev) p += sprintf(p, "multicast_address[%d]=\"%02x:%02x:%02x:%02x:%02x:%02x\"\n", i++, mcptr->addr[0], mcptr->addr[1], mcptr->addr[2], mcptr->addr[3], mcptr->addr[4], mcptr->addr[5]); #endif /* < 2.6.35 */ } #endif p += sprintf(p, "num_tx_bytes = %lu\n", priv->stats.tx_bytes); p += sprintf(p, "num_rx_bytes = %lu\n", priv->stats.rx_bytes); p += sprintf(p, "num_tx_pkts = %lu\n", priv->stats.tx_packets); p += sprintf(p, "num_rx_pkts = %lu\n", priv->stats.rx_packets); p += sprintf(p, "num_tx_pkts_dropped = %lu\n", priv->stats.tx_dropped); p += sprintf(p, "num_rx_pkts_dropped = %lu\n", priv->stats.rx_dropped); p += sprintf(p, "num_tx_pkts_err = %lu\n", priv->stats.tx_errors); p += sprintf(p, "num_rx_pkts_err = %lu\n", priv->stats.rx_errors); p += sprintf(p, "carrier %s\n", ((netif_carrier_ok(priv->netdev)) ? "on" : "off")); p += sprintf(p, "tx queue %s\n", ((netif_queue_stopped(priv->netdev)) ? "stopped" : "started")); #ifdef UAP_SUPPORT if (GET_BSS_ROLE(priv) == MLAN_BSS_ROLE_UAP) { p += sprintf(p, "tkip_mic_failures = %lu\n", ustats.tkip_mic_failures); p += sprintf(p, "ccmp_decrypt_errors = %lu\n", ustats.ccmp_decrypt_errors); p += sprintf(p, "wep_undecryptable_count = %lu\n", ustats.wep_undecryptable_count); p += sprintf(p, "wep_icv_error_count = %lu\n", ustats.wep_icv_error_count); p += sprintf(p, "decrypt_failure_count = %lu\n", ustats.decrypt_failure_count); p += sprintf(p, "mcast_tx_count = %lu\n", ustats.mcast_tx_count); p += sprintf(p, "failed_count = %lu\n", ustats.failed_count); p += sprintf(p, "retry_count = %lu\n", ustats.retry_count); p += sprintf(p, "multiple_retry_count = %lu\n", ustats.multi_retry_count); p += sprintf(p, "frame_duplicate_count = %lu\n", ustats.frame_dup_count); p += sprintf(p, "rts_success_count = %lu\n", ustats.rts_success_count); p += sprintf(p, "rts_failure_count = %lu\n", ustats.rts_failure_count); p += sprintf(p, "ack_failure_count = %lu\n", ustats.ack_failure_count); p += sprintf(p, "rx_fragment_count = %lu\n", ustats.rx_fragment_count); p += sprintf(p, "mcast_rx_frame_count = %lu\n", ustats.mcast_rx_frame_count); p += sprintf(p, "fcs_error_count = %lu\n", ustats.fcs_error_count); p += sprintf(p, "tx_frame_count = %lu\n", ustats.tx_frame_count); p += sprintf(p, "rsna_tkip_cm_invoked = %lu\n", ustats.rsna_tkip_cm_invoked); p += sprintf(p, "rsna_4way_hshk_failures = %lu\n", ustats.rsna_4way_hshk_failures); } #endif /* UAP_SUPPORT */ exit: return (p - page); }
static int init586(struct net_device *dev) { void *ptr; unsigned long s; int i, result = 0; struct priv *p = netdev_priv(dev); volatile struct configure_cmd_struct *cfg_cmd; volatile struct iasetup_cmd_struct *ias_cmd; volatile struct tdr_cmd_struct *tdr_cmd; volatile struct mcsetup_cmd_struct *mc_cmd; struct netdev_hw_addr *ha; int num_addrs = netdev_mc_count(dev); ptr = (void *) ((char *) p->scb + sizeof(struct scb_struct)); cfg_cmd = (struct configure_cmd_struct *) ptr; /* configure-command */ cfg_cmd->cmd_status = 0; cfg_cmd->cmd_cmd = CMD_CONFIGURE | CMD_LAST; cfg_cmd->cmd_link = 0xffff; cfg_cmd->byte_cnt = 0x0a; /* number of cfg bytes */ cfg_cmd->fifo = 0x08; /* fifo-limit (8=tx:32/rx:64) */ cfg_cmd->sav_bf = 0x40; /* hold or discard bad recv frames (bit 7) */ cfg_cmd->adr_len = 0x2e; /* addr_len |!src_insert |pre-len |loopback */ cfg_cmd->priority = 0x00; cfg_cmd->ifs = 0x60; cfg_cmd->time_low = 0x00; cfg_cmd->time_high = 0xf2; cfg_cmd->promisc = 0; if (dev->flags & (IFF_ALLMULTI | IFF_PROMISC)) cfg_cmd->promisc = 1; cfg_cmd->carr_coll = 0x00; p->scb->cbl_offset = make16(cfg_cmd); p->scb->cmd = CUC_START; /* cmd.-unit start */ elmc_id_attn586(); s = jiffies; /* warning: only active with interrupts on !! */ while (!(cfg_cmd->cmd_status & STAT_COMPL)) { if (time_after(jiffies, s + 30*HZ/100)) break; } if ((cfg_cmd->cmd_status & (STAT_OK | STAT_COMPL)) != (STAT_COMPL | STAT_OK)) { pr_warning("%s (elmc): configure command failed: %x\n", dev->name, cfg_cmd->cmd_status); return 1; } /* * individual address setup */ ias_cmd = (struct iasetup_cmd_struct *) ptr; ias_cmd->cmd_status = 0; ias_cmd->cmd_cmd = CMD_IASETUP | CMD_LAST; ias_cmd->cmd_link = 0xffff; memcpy((char *) &ias_cmd->iaddr, (char *) dev->dev_addr, ETH_ALEN); p->scb->cbl_offset = make16(ias_cmd); p->scb->cmd = CUC_START; /* cmd.-unit start */ elmc_id_attn586(); s = jiffies; while (!(ias_cmd->cmd_status & STAT_COMPL)) { if (time_after(jiffies, s + 30*HZ/100)) break; } if ((ias_cmd->cmd_status & (STAT_OK | STAT_COMPL)) != (STAT_OK | STAT_COMPL)) { pr_warning("%s (elmc): individual address setup command failed: %04x\n", dev->name, ias_cmd->cmd_status); return 1; } /* * TDR, wire check .. e.g. no resistor e.t.c */ tdr_cmd = (struct tdr_cmd_struct *) ptr; tdr_cmd->cmd_status = 0; tdr_cmd->cmd_cmd = CMD_TDR | CMD_LAST; tdr_cmd->cmd_link = 0xffff; tdr_cmd->status = 0; p->scb->cbl_offset = make16(tdr_cmd); p->scb->cmd = CUC_START; /* cmd.-unit start */ elmc_attn586(); s = jiffies; while (!(tdr_cmd->cmd_status & STAT_COMPL)) { if (time_after(jiffies, s + 30*HZ/100)) { pr_warning("%s: %d Problems while running the TDR.\n", dev->name, __LINE__); result = 1; break; } } if (!result) { DELAY(2); /* wait for result */ result = tdr_cmd->status; p->scb->cmd = p->scb->status & STAT_MASK; elmc_id_attn586(); /* ack the interrupts */ if (result & TDR_LNK_OK) { /* empty */ } else if (result & TDR_XCVR_PRB) { pr_warning("%s: TDR: Transceiver problem!\n", dev->name); } else if (result & TDR_ET_OPN) { pr_warning("%s: TDR: No correct termination %d clocks away.\n", dev->name, result & TDR_TIMEMASK); } else if (result & TDR_ET_SRT) { if (result & TDR_TIMEMASK) /* time == 0 -> strange :-) */ pr_warning("%s: TDR: Detected a short circuit %d clocks away.\n", dev->name, result & TDR_TIMEMASK); } else { pr_warning("%s: TDR: Unknown status %04x\n", dev->name, result); } } /* * ack interrupts */ p->scb->cmd = p->scb->status & STAT_MASK; elmc_id_attn586(); /* * alloc nop/xmit-cmds */ #if (NUM_XMIT_BUFFS == 1) for (i = 0; i < 2; i++) { p->nop_cmds[i] = (struct nop_cmd_struct *) ptr; p->nop_cmds[i]->cmd_cmd = CMD_NOP; p->nop_cmds[i]->cmd_status = 0; p->nop_cmds[i]->cmd_link = make16((p->nop_cmds[i])); ptr = (char *) ptr + sizeof(struct nop_cmd_struct); } p->xmit_cmds[0] = (struct transmit_cmd_struct *) ptr; /* transmit cmd/buff 0 */ ptr = (char *) ptr + sizeof(struct transmit_cmd_struct); #else for (i = 0; i < NUM_XMIT_BUFFS; i++) { p->nop_cmds[i] = (struct nop_cmd_struct *) ptr; p->nop_cmds[i]->cmd_cmd = CMD_NOP; p->nop_cmds[i]->cmd_status = 0; p->nop_cmds[i]->cmd_link = make16((p->nop_cmds[i])); ptr = (char *) ptr + sizeof(struct nop_cmd_struct); p->xmit_cmds[i] = (struct transmit_cmd_struct *) ptr; /*transmit cmd/buff 0 */ ptr = (char *) ptr + sizeof(struct transmit_cmd_struct); } #endif ptr = alloc_rfa(dev, (void *) ptr); /* init receive-frame-area */ /* * Multicast setup */ if (num_addrs) { /* I don't understand this: do we really need memory after the init? */ int len = ((char *) p->iscp - (char *) ptr - 8) / 6; if (len <= 0) { pr_err("%s: Ooooops, no memory for MC-Setup!\n", dev->name); } else { if (len < num_addrs) { num_addrs = len; pr_warning("%s: Sorry, can only apply %d MC-Address(es).\n", dev->name, num_addrs); } mc_cmd = (struct mcsetup_cmd_struct *) ptr; mc_cmd->cmd_status = 0; mc_cmd->cmd_cmd = CMD_MCSETUP | CMD_LAST; mc_cmd->cmd_link = 0xffff; mc_cmd->mc_cnt = num_addrs * 6; i = 0; netdev_for_each_mc_addr(ha, dev) memcpy((char *) mc_cmd->mc_list[i++], ha->addr, 6); p->scb->cbl_offset = make16(mc_cmd); p->scb->cmd = CUC_START; elmc_id_attn586(); s = jiffies; while (!(mc_cmd->cmd_status & STAT_COMPL)) { if (time_after(jiffies, s + 30*HZ/100)) break; } if (!(mc_cmd->cmd_status & STAT_COMPL)) { pr_warning("%s: Can't apply multicast-address-list.\n", dev->name); } } } /* * alloc xmit-buffs / init xmit_cmds */ for (i = 0; i < NUM_XMIT_BUFFS; i++) { p->xmit_cbuffs[i] = (char *) ptr; /* char-buffs */ ptr = (char *) ptr + XMIT_BUFF_SIZE; p->xmit_buffs[i] = (struct tbd_struct *) ptr; /* TBD */ ptr = (char *) ptr + sizeof(struct tbd_struct); if ((void *) ptr > (void *) p->iscp) { pr_err("%s: not enough shared-mem for your configuration!\n", dev->name); return 1; } memset((char *) (p->xmit_cmds[i]), 0, sizeof(struct transmit_cmd_struct)); memset((char *) (p->xmit_buffs[i]), 0, sizeof(struct tbd_struct)); p->xmit_cmds[i]->cmd_status = STAT_COMPL; p->xmit_cmds[i]->cmd_cmd = CMD_XMIT | CMD_INT; p->xmit_cmds[i]->tbd_offset = make16((p->xmit_buffs[i])); p->xmit_buffs[i]->next = 0xffff; p->xmit_buffs[i]->buffer = make24((p->xmit_cbuffs[i])); } p->xmit_count = 0; p->xmit_last = 0; #ifndef NO_NOPCOMMANDS p->nop_point = 0; #endif /* * 'start transmitter' (nop-loop) */ #ifndef NO_NOPCOMMANDS p->scb->cbl_offset = make16(p->nop_cmds[0]); p->scb->cmd = CUC_START; elmc_id_attn586(); WAIT_4_SCB_CMD(); #else p->xmit_cmds[0]->cmd_link = 0xffff; p->xmit_cmds[0]->cmd_cmd = CMD_XMIT | CMD_LAST | CMD_INT; #endif return 0; }