···812812 tristate "SMC 91C9x/91C1xxx support"813813 select CRC32814814 select MII815815- depends on NET_ETHERNET && (ARM || REDWOOD_5 || REDWOOD_6 || M32R || SUPERH)815815+ depends on NET_ETHERNET && (ARM || REDWOOD_5 || REDWOOD_6 || M32R || SUPERH || SOC_AU1X00)816816 help817817 This is a driver for SMC's 91x series of Ethernet chipsets,818818 including the SMC91C94 and the SMC91C111. Say Y if you want it
+138-93
drivers/net/forcedeth.c
···8080 * into nv_close, otherwise reenabling for wol can8181 * cause DMA to kfree'd memory.8282 * 0.31: 14 Nov 2004: ethtool support for getting/setting link8383- * capabilities.8383+ * capabilities.8484 * 0.32: 16 Apr 2005: RX_ERROR4 handling added.8585 * 0.33: 16 May 2005: Support for MCP51 added.8686 * 0.34: 18 Jun 2005: Add DEV_NEED_LINKTIMER to all nForce nics.···8989 * 0.37: 10 Jul 2005: Additional ethtool support, cleanup of pci id list9090 * 0.38: 16 Jul 2005: tx irq rewrite: Use global flags instead of9191 * per-packet flags.9292- * 0.39: 18 Jul 2005: Add 64bit descriptor support.9393- * 0.40: 19 Jul 2005: Add support for mac address change.9494- * 0.41: 30 Jul 2005: Write back original MAC in nv_close instead9292+ * 0.39: 18 Jul 2005: Add 64bit descriptor support.9393+ * 0.40: 19 Jul 2005: Add support for mac address change.9494+ * 0.41: 30 Jul 2005: Write back original MAC in nv_close instead9595 * of nv_remove9696- * 0.42: 06 Aug 2005: Fix lack of link speed initialization9696+ * 0.42: 06 Aug 2005: Fix lack of link speed initialization9797 * in the second (and later) nv_open call9898- * 0.43: 10 Aug 2005: Add support for tx checksum.9999- * 0.44: 20 Aug 2005: Add support for scatter gather and segmentation.9898+ * 0.43: 10 Aug 2005: Add support for tx checksum.9999+ * 0.44: 20 Aug 2005: Add support for scatter gather and segmentation.100100+ * 0.45: 18 Sep 2005: Remove nv_stop/start_rx from every link check101101+ * 0.46: 20 Oct 2005: Add irq optimization modes.102102+ * 0.47: 26 Oct 2005: Add phyaddr 0 in phy scan.100103 *101104 * Known bugs:102105 * We suspect that on some hardware no TX done interrupts are generated.···111108 * DEV_NEED_TIMERIRQ will not harm you on sane hardware, only generating a few112109 * superfluous timer interrupts from the nic.113110 */114114-#define FORCEDETH_VERSION "0.44"111111+#define FORCEDETH_VERSION "0.47"115112#define DRV_NAME "forcedeth"116113117114#include <linux/module.h>···166163#define NVREG_IRQ_LINK 0x0040167164#define NVREG_IRQ_TX_ERROR 0x0080168165#define NVREG_IRQ_TX1 0x0100169169-#define NVREG_IRQMASK_WANTED 0x00df166166+#define NVREG_IRQMASK_THROUGHPUT 0x00df167167+#define NVREG_IRQMASK_CPU 0x0040170168171169#define NVREG_IRQ_UNKNOWN (~(NVREG_IRQ_RX_ERROR|NVREG_IRQ_RX|NVREG_IRQ_RX_NOBUF|NVREG_IRQ_TX_ERR| \172170 NVREG_IRQ_TX_OK|NVREG_IRQ_TIMER|NVREG_IRQ_LINK|NVREG_IRQ_TX_ERROR| \···181177 * NVREG_POLL_DEFAULT=97 would result in an interval length of 1 ms182178 */183179 NvRegPollingInterval = 0x00c,184184-#define NVREG_POLL_DEFAULT 970180180+#define NVREG_POLL_DEFAULT_THROUGHPUT 970181181+#define NVREG_POLL_DEFAULT_CPU 13185182 NvRegMisc1 = 0x080,186183#define NVREG_MISC1_HD 0x02187184#define NVREG_MISC1_FORCE 0x3b0f3c···542537 * is stuck. Overridable with module param.543538 */544539static int max_interrupt_work = 5;540540+541541+/*542542+ * Optimization can be either throuput mode or cpu mode543543+ * 544544+ * Throughput Mode: Every tx and rx packet will generate an interrupt.545545+ * CPU Mode: Interrupts are controlled by a timer.546546+ */547547+#define NV_OPTIMIZATION_MODE_THROUGHPUT 0548548+#define NV_OPTIMIZATION_MODE_CPU 1549549+static int optimization_mode = NV_OPTIMIZATION_MODE_THROUGHPUT;550550+551551+/*552552+ * Poll interval for timer irq553553+ *554554+ * This interval determines how frequent an interrupt is generated.555555+ * The is value is determined by [(time_in_micro_secs * 100) / (2^10)]556556+ * Min = 0, and Max = 65535557557+ */558558+static int poll_interval = -1;545559546560static inline struct fe_priv *get_nvpriv(struct net_device *dev)547561{···13521328 if (!(Flags & NV_RX_DESCRIPTORVALID))13531329 goto next_pkt;1354133013551355- if (Flags & NV_RX_MISSEDFRAME) {13561356- np->stats.rx_missed_errors++;13571357- np->stats.rx_errors++;13581358- goto next_pkt;13591359- }13601360- if (Flags & (NV_RX_ERROR1|NV_RX_ERROR2|NV_RX_ERROR3)) {13611361- np->stats.rx_errors++;13621362- goto next_pkt;13631363- }13641364- if (Flags & NV_RX_CRCERR) {13651365- np->stats.rx_crc_errors++;13661366- np->stats.rx_errors++;13671367- goto next_pkt;13681368- }13691369- if (Flags & NV_RX_OVERFLOW) {13701370- np->stats.rx_over_errors++;13711371- np->stats.rx_errors++;13721372- goto next_pkt;13731373- }13741374- if (Flags & NV_RX_ERROR4) {13751375- len = nv_getlen(dev, np->rx_skbuff[i]->data, len);13761376- if (len < 0) {13311331+ if (Flags & NV_RX_ERROR) {13321332+ if (Flags & NV_RX_MISSEDFRAME) {13331333+ np->stats.rx_missed_errors++;13771334 np->stats.rx_errors++;13781335 goto next_pkt;13791336 }13801380- }13811381- /* framing errors are soft errors. */13821382- if (Flags & NV_RX_FRAMINGERR) {13831383- if (Flags & NV_RX_SUBSTRACT1) {13841384- len--;13371337+ if (Flags & (NV_RX_ERROR1|NV_RX_ERROR2|NV_RX_ERROR3)) {13381338+ np->stats.rx_errors++;13391339+ goto next_pkt;13401340+ }13411341+ if (Flags & NV_RX_CRCERR) {13421342+ np->stats.rx_crc_errors++;13431343+ np->stats.rx_errors++;13441344+ goto next_pkt;13451345+ }13461346+ if (Flags & NV_RX_OVERFLOW) {13471347+ np->stats.rx_over_errors++;13481348+ np->stats.rx_errors++;13491349+ goto next_pkt;13501350+ }13511351+ if (Flags & NV_RX_ERROR4) {13521352+ len = nv_getlen(dev, np->rx_skbuff[i]->data, len);13531353+ if (len < 0) {13541354+ np->stats.rx_errors++;13551355+ goto next_pkt;13561356+ }13571357+ }13581358+ /* framing errors are soft errors. */13591359+ if (Flags & NV_RX_FRAMINGERR) {13601360+ if (Flags & NV_RX_SUBSTRACT1) {13611361+ len--;13621362+ }13851363 }13861364 }13871365 } else {13881366 if (!(Flags & NV_RX2_DESCRIPTORVALID))13891367 goto next_pkt;1390136813911391- if (Flags & (NV_RX2_ERROR1|NV_RX2_ERROR2|NV_RX2_ERROR3)) {13921392- np->stats.rx_errors++;13931393- goto next_pkt;13941394- }13951395- if (Flags & NV_RX2_CRCERR) {13961396- np->stats.rx_crc_errors++;13971397- np->stats.rx_errors++;13981398- goto next_pkt;13991399- }14001400- if (Flags & NV_RX2_OVERFLOW) {14011401- np->stats.rx_over_errors++;14021402- np->stats.rx_errors++;14031403- goto next_pkt;14041404- }14051405- if (Flags & NV_RX2_ERROR4) {14061406- len = nv_getlen(dev, np->rx_skbuff[i]->data, len);14071407- if (len < 0) {13691369+ if (Flags & NV_RX2_ERROR) {13701370+ if (Flags & (NV_RX2_ERROR1|NV_RX2_ERROR2|NV_RX2_ERROR3)) {14081371 np->stats.rx_errors++;14091372 goto next_pkt;14101373 }14111411- }14121412- /* framing errors are soft errors */14131413- if (Flags & NV_RX2_FRAMINGERR) {14141414- if (Flags & NV_RX2_SUBSTRACT1) {14151415- len--;13741374+ if (Flags & NV_RX2_CRCERR) {13751375+ np->stats.rx_crc_errors++;13761376+ np->stats.rx_errors++;13771377+ goto next_pkt;13781378+ }13791379+ if (Flags & NV_RX2_OVERFLOW) {13801380+ np->stats.rx_over_errors++;13811381+ np->stats.rx_errors++;13821382+ goto next_pkt;13831383+ }13841384+ if (Flags & NV_RX2_ERROR4) {13851385+ len = nv_getlen(dev, np->rx_skbuff[i]->data, len);13861386+ if (len < 0) {13871387+ np->stats.rx_errors++;13881388+ goto next_pkt;13891389+ }13901390+ }13911391+ /* framing errors are soft errors */13921392+ if (Flags & NV_RX2_FRAMINGERR) {13931393+ if (Flags & NV_RX2_SUBSTRACT1) {13941394+ len--;13951395+ }14161396 }14171397 }14181398 Flags &= NV_RX2_CHECKSUMMASK;···16401612 spin_unlock_irq(&np->lock);16411613}1642161416151615+/**16161616+ * nv_update_linkspeed: Setup the MAC according to the link partner16171617+ * @dev: Network device to be configured16181618+ *16191619+ * The function queries the PHY and checks if there is a link partner.16201620+ * If yes, then it sets up the MAC accordingly. Otherwise, the MAC is16211621+ * set to 10 MBit HD.16221622+ *16231623+ * The function returns 0 if there is no link partner and 1 if there is16241624+ * a good link partner.16251625+ */16431626static int nv_update_linkspeed(struct net_device *dev)16441627{16451628 struct fe_priv *np = netdev_priv(dev);···17901751static void nv_linkchange(struct net_device *dev)17911752{17921753 if (nv_update_linkspeed(dev)) {17931793- if (netif_carrier_ok(dev)) {17941794- nv_stop_rx(dev);17951795- } else {17541754+ if (!netif_carrier_ok(dev)) {17961755 netif_carrier_on(dev);17971756 printk(KERN_INFO "%s: link up.\n", dev->name);17571757+ nv_start_rx(dev);17981758 }17991799- nv_start_rx(dev);18001759 } else {18011760 if (netif_carrier_ok(dev)) {18021761 netif_carrier_off(dev);···18361799 if (!(events & np->irqmask))18371800 break;1838180118391839- if (events & (NVREG_IRQ_TX1|NVREG_IRQ_TX_OK|NVREG_IRQ_TX_ERROR|NVREG_IRQ_TX_ERR)) {18021802+ spin_lock(&np->lock);18031803+ nv_tx_done(dev);18041804+ spin_unlock(&np->lock);18051805+18061806+ nv_rx_process(dev);18071807+ if (nv_alloc_rx(dev)) {18401808 spin_lock(&np->lock);18411841- nv_tx_done(dev);18091809+ if (!np->in_shutdown)18101810+ mod_timer(&np->oom_kick, jiffies + OOM_REFILL);18421811 spin_unlock(&np->lock);18431812 }18441844-18451845- if (events & (NVREG_IRQ_RX_ERROR|NVREG_IRQ_RX|NVREG_IRQ_RX_NOBUF)) {18461846- nv_rx_process(dev);18471847- if (nv_alloc_rx(dev)) {18481848- spin_lock(&np->lock);18491849- if (!np->in_shutdown)18501850- mod_timer(&np->oom_kick, jiffies + OOM_REFILL);18511851- spin_unlock(&np->lock);18521852- }18531853- }18541854-18131813+18551814 if (events & NVREG_IRQ_LINK) {18561815 spin_lock(&np->lock);18571816 nv_link_irq(dev);···22492216 writel(NVREG_RNDSEED_FORCE | (i&NVREG_RNDSEED_MASK), base + NvRegRandomSeed);22502217 writel(NVREG_UNKSETUP1_VAL, base + NvRegUnknownSetupReg1);22512218 writel(NVREG_UNKSETUP2_VAL, base + NvRegUnknownSetupReg2);22522252- writel(NVREG_POLL_DEFAULT, base + NvRegPollingInterval);22192219+ if (poll_interval == -1) {22202220+ if (optimization_mode == NV_OPTIMIZATION_MODE_THROUGHPUT)22212221+ writel(NVREG_POLL_DEFAULT_THROUGHPUT, base + NvRegPollingInterval);22222222+ else22232223+ writel(NVREG_POLL_DEFAULT_CPU, base + NvRegPollingInterval);22242224+ }22252225+ else22262226+ writel(poll_interval & 0xFFFF, base + NvRegPollingInterval);22532227 writel(NVREG_UNKSETUP6_VAL, base + NvRegUnknownSetupReg6);22542228 writel((np->phyaddr << NVREG_ADAPTCTL_PHYSHIFT)|NVREG_ADAPTCTL_PHYVALID|NVREG_ADAPTCTL_RUNNING,22552229 base + NvRegAdapterControl);···25412501 } else {25422502 np->tx_flags = NV_TX2_VALID;25432503 }25442544- np->irqmask = NVREG_IRQMASK_WANTED;25042504+ if (optimization_mode == NV_OPTIMIZATION_MODE_THROUGHPUT)25052505+ np->irqmask = NVREG_IRQMASK_THROUGHPUT;25062506+ else25072507+ np->irqmask = NVREG_IRQMASK_CPU;25082508+25452509 if (id->driver_data & DEV_NEED_TIMERIRQ)25462510 np->irqmask |= NVREG_IRQ_TIMER;25472511 if (id->driver_data & DEV_NEED_LINKTIMER) {···25582514 }2559251525602516 /* find a suitable phy */25612561- for (i = 1; i < 32; i++) {25172517+ for (i = 1; i <= 32; i++) {25622518 int id1, id2;25192519+ int phyaddr = i & 0x1F;2563252025642521 spin_lock_irq(&np->lock);25652565- id1 = mii_rw(dev, i, MII_PHYSID1, MII_READ);25222522+ id1 = mii_rw(dev, phyaddr, MII_PHYSID1, MII_READ);25662523 spin_unlock_irq(&np->lock);25672524 if (id1 < 0 || id1 == 0xffff)25682525 continue;25692526 spin_lock_irq(&np->lock);25702570- id2 = mii_rw(dev, i, MII_PHYSID2, MII_READ);25272527+ id2 = mii_rw(dev, phyaddr, MII_PHYSID2, MII_READ);25712528 spin_unlock_irq(&np->lock);25722529 if (id2 < 0 || id2 == 0xffff)25732530 continue;···25762531 id1 = (id1 & PHYID1_OUI_MASK) << PHYID1_OUI_SHFT;25772532 id2 = (id2 & PHYID2_OUI_MASK) >> PHYID2_OUI_SHFT;25782533 dprintk(KERN_DEBUG "%s: open: Found PHY %04x:%04x at address %d.\n",25792579- pci_name(pci_dev), id1, id2, i);25802580- np->phyaddr = i;25342534+ pci_name(pci_dev), id1, id2, phyaddr);25352535+ np->phyaddr = phyaddr;25812536 np->phy_oui = id1 | id2;25822537 break;25832538 }25842584- if (i == 32) {25852585- /* PHY in isolate mode? No phy attached and user wants to25862586- * test loopback? Very odd, but can be correct.25872587- */25392539+ if (i == 33) {25882540 printk(KERN_INFO "%s: open: Could not find a valid PHY.\n",25892589- pci_name(pci_dev));25412541+ pci_name(pci_dev));25422542+ goto out_freering;25902543 }25912591-25922592- if (i != 32) {25932593- /* reset it */25942594- phy_init(dev);25952595- }25442544+25452545+ /* reset it */25462546+ phy_init(dev);2596254725972548 /* set default link speed settings */25982549 np->linkspeed = NVREG_LINKSPEED_FORCE|NVREG_LINKSPEED_10;···2730268927312690module_param(max_interrupt_work, int, 0);27322691MODULE_PARM_DESC(max_interrupt_work, "forcedeth maximum events handled per interrupt");26922692+module_param(optimization_mode, int, 0);26932693+MODULE_PARM_DESC(optimization_mode, "In throughput mode (0), every tx & rx packet will generate an interrupt. In CPU mode (1), interrupts are controlled by a timer.");26942694+module_param(poll_interval, int, 0);26952695+MODULE_PARM_DESC(poll_interval, "Interval determines how frequent timer interrupt is generated by [(time_in_micro_secs * 100) / (2^10)]. Min is 0 and Max is 65535.");2733269627342697MODULE_AUTHOR("Manfred Spraul <manfred@colorfullife.com>");27352698MODULE_DESCRIPTION("Reverse Engineered nForce ethernet driver");
···88 * Author(s): Original Code written by99 * DJ Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com)1010 * Rewritten by1111- * Frank Pavlic (pavlic@de.ibm.com) and1111+ * Frank Pavlic (fpavlic@de.ibm.com) and1212 * Martin Schwidefsky <schwidefsky@de.ibm.com>1313 *1414 * $Revision: 1.99 $ $Date: 2005/05/11 08:10:17 $···23422342module_init(lcs_init_module);23432343module_exit(lcs_cleanup_module);2344234423452345-MODULE_AUTHOR("Frank Pavlic <pavlic@de.ibm.com>");23452345+MODULE_AUTHOR("Frank Pavlic <fpavlic@de.ibm.com>");23462346MODULE_LICENSE("GPL");23472347
+59-18
drivers/s390/net/qeth.h
···88#include <linux/trdevice.h>99#include <linux/etherdevice.h>1010#include <linux/if_vlan.h>1111+#include <linux/ctype.h>11121213#include <net/ipv6.h>1314#include <linux/in6.h>···25242625#include "qeth_mpc.h"27262828-#define VERSION_QETH_H "$Revision: 1.142 $"2727+#define VERSION_QETH_H "$Revision: 1.152 $"29283029#ifdef CONFIG_QETH_IPV63130#define QETH_VERSION_IPV6 ":IPv6"···719718 atomic_t refcnt;720719};721720722722-#define QETH_BROADCAST_WITH_ECHO 1723723-#define QETH_BROADCAST_WITHOUT_ECHO 2724721725722struct qeth_card_blkt {726723 int time_total;···726727 int inter_packet_jumbo;727728};728729729729-730730-730730+#define QETH_BROADCAST_WITH_ECHO 0x01731731+#define QETH_BROADCAST_WITHOUT_ECHO 0x02732732+#define QETH_LAYER2_MAC_READ 0x01733733+#define QETH_LAYER2_MAC_REGISTERED 0x02731734struct qeth_card_info {732735 unsigned short unit_addr2;733736 unsigned short cula;···737736 __u16 func_level;738737 char mcl_level[QETH_MCL_LENGTH + 1];739738 int guestlan;740740- int layer2_mac_registered;739739+ int mac_bits;741740 int portname_required;742741 int portno;743742 char portname[9];···750749 int unique_id;751750 struct qeth_card_blkt blkt;752751 __u32 csum_mask;752752+ enum qeth_ipa_promisc_modes promisc_mode;753753};754754755755struct qeth_card_options {···777775enum qeth_threads {778776 QETH_SET_IP_THREAD = 1,779777 QETH_RECOVER_THREAD = 2,778778+ QETH_SET_PROMISC_MODE_THREAD = 4,780779};781780782781struct qeth_osn_info {···10771074 }10781075}1079107610771077+static inline int10781078+qeth_isdigit(char * buf)10791079+{10801080+ while (*buf) {10811081+ if (!isdigit(*buf++))10821082+ return 0;10831083+ }10841084+ return 1;10851085+}10861086+10871087+static inline int10881088+qeth_isxdigit(char * buf)10891089+{10901090+ while (*buf) {10911091+ if (!isxdigit(*buf++))10921092+ return 0;10931093+ }10941094+ return 1;10951095+}10961096+10801097static inline void10811098qeth_ipaddr4_to_string(const __u8 *addr, char *buf)10821099{···11131090 int i;1114109111151092 start = buf;11161116- for (i = 0; i < 3; i++) {11171117- if (!(end = strchr(start, '.')))10931093+ for (i = 0; i < 4; i++) {10941094+ if (i == 3) {10951095+ end = strchr(start,0xa);10961096+ if (end)10971097+ len = end - start;10981098+ else 10991099+ len = strlen(start);11001100+ }11011101+ else {11021102+ end = strchr(start, '.');11031103+ len = end - start;11041104+ }11051105+ if ((len <= 0) || (len > 3))11181106 return -EINVAL;11191119- len = end - start;11201107 memset(abuf, 0, 4);11211108 strncpy(abuf, start, len);11091109+ if (!qeth_isdigit(abuf))11101110+ return -EINVAL;11221111 addr[i] = simple_strtoul(abuf, &tmp, 10);11231112 start = end + 1;11241113 }11251125- memset(abuf, 0, 4);11261126- strcpy(abuf, start);11271127- addr[3] = simple_strtoul(abuf, &tmp, 10);11281114 return 0;11291115}11301116···1160112811611129 tmp_addr = (u16 *)addr;11621130 start = buf;11631163- for (i = 0; i < 7; i++) {11641164- if (!(end = strchr(start, ':')))11311131+ for (i = 0; i < 8; i++) {11321132+ if (i == 7) {11331133+ end = strchr(start,0xa);11341134+ if (end)11351135+ len = end - start;11361136+ else11371137+ len = strlen(start);11381138+ }11391139+ else {11401140+ end = strchr(start, ':');11411141+ len = end - start;11421142+ }11431143+ if ((len <= 0) || (len > 4))11651144 return -EINVAL;11661166- len = end - start;11671145 memset(abuf, 0, 5);11681146 strncpy(abuf, start, len);11471147+ if (!qeth_isxdigit(abuf))11481148+ return -EINVAL;11691149 tmp_addr[i] = simple_strtoul(abuf, &tmp, 16);11701150 start = end + 1;11711151 }11721172- memset(abuf, 0, 5);11731173- strcpy(abuf, start);11741174- tmp_addr[7] = simple_strtoul(abuf, &tmp, 16);11751152 return 0;11761153}11771154
+214-47
drivers/s390/net/qeth_main.c
···11/*22 *33- * linux/drivers/s390/net/qeth_main.c ($Revision: 1.224 $)33+ * linux/drivers/s390/net/qeth_main.c ($Revision: 1.242 $)44 *55 * Linux on zSeries OSA Express and HiperSockets support66 *···99 * Author(s): Original Code written by1010 * Utz Bacher (utz.bacher@de.ibm.com)1111 * Rewritten by1212- * Frank Pavlic (pavlic@de.ibm.com) and1212+ * Frank Pavlic (fpavlic@de.ibm.com) and1313 * Thomas Spatzier <tspat@de.ibm.com>1414 *1515- * $Revision: 1.224 $ $Date: 2005/05/04 20:19:18 $1515+ * $Revision: 1.242 $ $Date: 2005/05/04 20:19:18 $1616 *1717 * This program is free software; you can redistribute it and/or modify1818 * it under the terms of the GNU General Public License as published by···7272#include "qeth_eddp.h"7373#include "qeth_tso.h"74747575-#define VERSION_QETH_C "$Revision: 1.224 $"7575+#define VERSION_QETH_C "$Revision: 1.242 $"7676static const char *version = "qeth S/390 OSA-Express driver";77777878/**···158158159159static void160160qeth_set_multicast_list(struct net_device *);161161+162162+static void163163+qeth_setadp_promisc_mode(struct qeth_card *);161164162165static void163166qeth_notify_processes(void)···605602 int found = 0;606603607604 list_for_each_entry(addr, &card->ip_list, entry) {605605+ if (card->options.layer2) {606606+ if ((addr->type == todo->type) &&607607+ (memcmp(&addr->mac, &todo->mac, 608608+ OSA_ADDR_LEN) == 0)) {609609+ found = 1;610610+ break;611611+ }612612+ continue;613613+ } 608614 if ((addr->proto == QETH_PROT_IPV4) &&609615 (todo->proto == QETH_PROT_IPV4) &&610616 (addr->type == todo->type) &&611617 (addr->u.a4.addr == todo->u.a4.addr) &&612612- (addr->u.a4.mask == todo->u.a4.mask) ){618618+ (addr->u.a4.mask == todo->u.a4.mask)) {613619 found = 1;614620 break;615621 }···627615 (addr->type == todo->type) &&628616 (addr->u.a6.pfxlen == todo->u.a6.pfxlen) &&629617 (memcmp(&addr->u.a6.addr, &todo->u.a6.addr,630630- sizeof(struct in6_addr)) == 0)) {618618+ sizeof(struct in6_addr)) == 0)) {631619 found = 1;632620 break;633621 }634622 }635635- if (found){623623+ if (found) {636624 addr->users += todo->users;637625 if (addr->users <= 0){638626 *__addr = addr;···644632 return 0;645633 }646634 }647647- if (todo->users > 0){635635+ if (todo->users > 0) {648636 /* for VIPA and RXIP limit refcount to 1 */649637 if (todo->type != QETH_IP_TYPE_NORMAL)650638 todo->users = 1;···694682 if ((addr->type == QETH_IP_TYPE_DEL_ALL_MC) &&695683 (tmp->type == QETH_IP_TYPE_DEL_ALL_MC))696684 return 0;685685+ if (card->options.layer2) {686686+ if ((tmp->type == addr->type) &&687687+ (tmp->is_multicast == addr->is_multicast) &&688688+ (memcmp(&tmp->mac, &addr->mac, 689689+ OSA_ADDR_LEN) == 0)) {690690+ found = 1;691691+ break;692692+ }693693+ continue;694694+ } 697695 if ((tmp->proto == QETH_PROT_IPV4) &&698696 (addr->proto == QETH_PROT_IPV4) &&699697 (tmp->type == addr->type) &&700698 (tmp->is_multicast == addr->is_multicast) &&701699 (tmp->u.a4.addr == addr->u.a4.addr) &&702702- (tmp->u.a4.mask == addr->u.a4.mask) ){700700+ (tmp->u.a4.mask == addr->u.a4.mask)) {703701 found = 1;704702 break;705703 }···719697 (tmp->is_multicast == addr->is_multicast) &&720698 (tmp->u.a6.pfxlen == addr->u.a6.pfxlen) &&721699 (memcmp(&tmp->u.a6.addr, &addr->u.a6.addr,722722- sizeof(struct in6_addr)) == 0) ){700700+ sizeof(struct in6_addr)) == 0)) {723701 found = 1;724702 break;725703 }···729707 tmp->users += addr->users;730708 else731709 tmp->users += add? 1:-1;732732- if (tmp->users == 0){710710+ if (tmp->users == 0) {733711 list_del(&tmp->entry);734712 kfree(tmp);735713 }···760738 unsigned long flags;761739 int rc = 0;762740763763- QETH_DBF_TEXT(trace,4,"delip");764764- if (addr->proto == QETH_PROT_IPV4)765765- QETH_DBF_HEX(trace,4,&addr->u.a4.addr,4);741741+ QETH_DBF_TEXT(trace, 4, "delip");742742+743743+ if (card->options.layer2)744744+ QETH_DBF_HEX(trace, 4, &addr->mac, 6);745745+ else if (addr->proto == QETH_PROT_IPV4)746746+ QETH_DBF_HEX(trace, 4, &addr->u.a4.addr, 4);766747 else {767767- QETH_DBF_HEX(trace,4,&addr->u.a6.addr,8);768768- QETH_DBF_HEX(trace,4,((char *)&addr->u.a6.addr)+8,8);748748+ QETH_DBF_HEX(trace, 4, &addr->u.a6.addr, 8);749749+ QETH_DBF_HEX(trace, 4, ((char *)&addr->u.a6.addr) + 8, 8);769750 }770751 spin_lock_irqsave(&card->ip_lock, flags);771752 rc = __qeth_insert_ip_todo(card, addr, 0);···782757 unsigned long flags;783758 int rc = 0;784759785785- QETH_DBF_TEXT(trace,4,"addip");786786- if (addr->proto == QETH_PROT_IPV4)787787- QETH_DBF_HEX(trace,4,&addr->u.a4.addr,4);760760+ QETH_DBF_TEXT(trace, 4, "addip");761761+ if (card->options.layer2)762762+ QETH_DBF_HEX(trace, 4, &addr->mac, 6);763763+ else if (addr->proto == QETH_PROT_IPV4)764764+ QETH_DBF_HEX(trace, 4, &addr->u.a4.addr, 4);788765 else {789789- QETH_DBF_HEX(trace,4,&addr->u.a6.addr,8);790790- QETH_DBF_HEX(trace,4,((char *)&addr->u.a6.addr)+8,8);766766+ QETH_DBF_HEX(trace, 4, &addr->u.a6.addr, 8);767767+ QETH_DBF_HEX(trace, 4, ((char *)&addr->u.a6.addr) + 8, 8);791768 }792769 spin_lock_irqsave(&card->ip_lock, flags);793770 rc = __qeth_insert_ip_todo(card, addr, 1);···802775{803776 struct qeth_ipaddr *addr, *tmp;804777 int rc;805805-778778+again:806779 list_for_each_entry_safe(addr, tmp, &card->ip_list, entry) {807780 if (addr->is_multicast) {808781 spin_unlock_irqrestore(&card->ip_lock, *flags);···811784 if (!rc) {812785 list_del(&addr->entry);813786 kfree(addr);787787+ goto again;814788 }815789 }816790 }···879851880852static void qeth_delete_mc_addresses(struct qeth_card *);881853static void qeth_add_multicast_ipv4(struct qeth_card *);854854+static void qeth_layer2_add_multicast(struct qeth_card *);882855#ifdef CONFIG_QETH_IPV6883856static void qeth_add_multicast_ipv6(struct qeth_card *);884857#endif···968939 return 0;969940}970941942942+/*943943+ * Drive the SET_PROMISC_MODE thread944944+ */945945+static int946946+qeth_set_promisc_mode(void *ptr)947947+{948948+ struct qeth_card *card = (struct qeth_card *) ptr;949949+950950+ daemonize("qeth_setprm");951951+ QETH_DBF_TEXT(trace,4,"setprm1");952952+ if (!qeth_do_run_thread(card, QETH_SET_PROMISC_MODE_THREAD))953953+ return 0;954954+ QETH_DBF_TEXT(trace,4,"setprm2");955955+ qeth_setadp_promisc_mode(card);956956+ qeth_clear_thread_running_bit(card, QETH_SET_PROMISC_MODE_THREAD);957957+ return 0;958958+}959959+971960static int972961qeth_recover(void *ptr)973962{···1052100510531006 if (qeth_do_start_thread(card, QETH_SET_IP_THREAD))10541007 kernel_thread(qeth_register_ip_addresses, (void *)card,SIGCHLD);10081008+ if (qeth_do_start_thread(card, QETH_SET_PROMISC_MODE_THREAD))10091009+ kernel_thread(qeth_set_promisc_mode, (void *)card, SIGCHLD);10551010 if (qeth_do_start_thread(card, QETH_RECOVER_THREAD))10561011 kernel_thread(qeth_recover, (void *) card, SIGCHLD);10571012}···3798374937993750 if ( (card->info.type != QETH_CARD_TYPE_OSN) &&38003751 (card->options.layer2) &&38013801- (!card->info.layer2_mac_registered)) {37523752+ (!(card->info.mac_bits & QETH_LAYER2_MAC_REGISTERED))) {38023753 QETH_DBF_TEXT(trace,4,"nomacadr");38033754 return -EPERM;38043755 }···43604311out:43614312 if (flush_count)43624313 qeth_flush_buffers(queue, 0, start_index, flush_count);43144314+ else if (!atomic_read(&queue->set_pci_flags_count))43154315+ atomic_swap(&queue->state, QETH_OUT_Q_LOCKED_FLUSH);43634316 /*43644317 * queue->state will go from LOCKED -> UNLOCKED or from43654318 * LOCKED_FLUSH -> LOCKED if output_handler wanted to 'notify' us···50264975 unsigned long);5027497650284977static int49784978+qeth_default_setadapterparms_cb(struct qeth_card *card,49794979+ struct qeth_reply *reply,49804980+ unsigned long data);49814981+static int50294982qeth_send_setassparms(struct qeth_card *, struct qeth_cmd_buffer *,50304983 __u16, long,50314984 int (*reply_cb)···53565301 struct qeth_ipaddr *addr;5357530253585303 QETH_DBF_TEXT(trace, 4, "frvaddr4");53595359- if (!card->vlangrp)53605360- return;53045304+53615305 rcu_read_lock();53625306 in_dev = __in_dev_get_rcu(card->vlangrp->vlan_devices[vid]);53635307 if (!in_dev)···53845330 struct qeth_ipaddr *addr;5385533153865332 QETH_DBF_TEXT(trace, 4, "frvaddr6");53875387- if (!card->vlangrp)53885388- return;53335333+53895334 in6_dev = in6_dev_get(card->vlangrp->vlan_devices[vid]);53905335 if (!in6_dev)53915336 return;···54045351}5405535254065353static void53545354+qeth_free_vlan_addresses(struct qeth_card *card, unsigned short vid)53555355+{53565356+ if (card->options.layer2 || !card->vlangrp)53575357+ return;53585358+ qeth_free_vlan_addresses4(card, vid);53595359+ qeth_free_vlan_addresses6(card, vid);53605360+}53615361+53625362+static int53635363+qeth_layer2_send_setdelvlan_cb(struct qeth_card *card,53645364+ struct qeth_reply *reply,53655365+ unsigned long data)53665366+{53675367+ struct qeth_ipa_cmd *cmd;53685368+53695369+ QETH_DBF_TEXT(trace, 2, "L2sdvcb");53705370+ cmd = (struct qeth_ipa_cmd *) data;53715371+ if (cmd->hdr.return_code) {53725372+ PRINT_ERR("Error in processing VLAN %i on %s: 0x%x. "53735373+ "Continuing\n",cmd->data.setdelvlan.vlan_id, 53745374+ QETH_CARD_IFNAME(card), cmd->hdr.return_code);53755375+ QETH_DBF_TEXT_(trace, 2, "L2VL%4x", cmd->hdr.command);53765376+ QETH_DBF_TEXT_(trace, 2, "L2%s", CARD_BUS_ID(card));53775377+ QETH_DBF_TEXT_(trace, 2, "err%d", cmd->hdr.return_code);53785378+ }53795379+ return 0;53805380+}53815381+53825382+static int54075383qeth_layer2_send_setdelvlan(struct qeth_card *card, __u16 i,54085384 enum qeth_ipa_cmds ipacmd)54095385{54105410- int rc;54115386 struct qeth_ipa_cmd *cmd;54125387 struct qeth_cmd_buffer *iob;54135388···54435362 iob = qeth_get_ipacmd_buffer(card, ipacmd, QETH_PROT_IPV4);54445363 cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE);54455364 cmd->data.setdelvlan.vlan_id = i;54465446-54475447- rc = qeth_send_ipa_cmd(card, iob, NULL, NULL);54485448- if (rc) {54495449- PRINT_ERR("Error in processing VLAN %i on %s: 0x%x. "54505450- "Continuing\n",i, QETH_CARD_IFNAME(card), rc);54515451- QETH_DBF_TEXT_(trace, 2, "L2VL%4x", ipacmd);54525452- QETH_DBF_TEXT_(trace, 2, "L2%s", CARD_BUS_ID(card));54535453- QETH_DBF_TEXT_(trace, 2, "err%d", rc);54545454- }53655365+ return qeth_send_ipa_cmd(card, iob, 53665366+ qeth_layer2_send_setdelvlan_cb, NULL);54555367}5456536854575369static void···54945420 qeth_free_vlan_skbs(card, vid);54955421 spin_lock_irqsave(&card->vlanlock, flags);54965422 /* unregister IP addresses of vlan device */54975497- qeth_free_vlan_addresses4(card, vid);54985498- qeth_free_vlan_addresses6(card, vid);54235423+ qeth_free_vlan_addresses(card, vid);54995424 if (card->vlangrp)55005425 card->vlangrp->vlan_devices[vid] = NULL;55015426 spin_unlock_irqrestore(&card->vlanlock, flags);···55035430 qeth_set_multicast_list(card->dev);55045431}55055432#endif54335433+/**54345434+ * Examine hardware response to SET_PROMISC_MODE54355435+ */54365436+static int54375437+qeth_setadp_promisc_mode_cb(struct qeth_card *card, 54385438+ struct qeth_reply *reply,54395439+ unsigned long data)54405440+{54415441+ struct qeth_ipa_cmd *cmd;54425442+ struct qeth_ipacmd_setadpparms *setparms;54435443+54445444+ QETH_DBF_TEXT(trace,4,"prmadpcb");54455445+54465446+ cmd = (struct qeth_ipa_cmd *) data;54475447+ setparms = &(cmd->data.setadapterparms);54485448+54495449+ qeth_default_setadapterparms_cb(card, reply, (unsigned long)cmd);54505450+ if (cmd->hdr.return_code) { 54515451+ QETH_DBF_TEXT_(trace,4,"prmrc%2.2x",cmd->hdr.return_code); 54525452+ setparms->data.mode = SET_PROMISC_MODE_OFF;54535453+ }54545454+ card->info.promisc_mode = setparms->data.mode;54555455+ return 0;54565456+}54575457+/*54585458+ * Set promiscuous mode (on or off) (SET_PROMISC_MODE command)54595459+ */54605460+static void54615461+qeth_setadp_promisc_mode(struct qeth_card *card)54625462+{54635463+ enum qeth_ipa_promisc_modes mode;54645464+ struct net_device *dev = card->dev;54655465+ struct qeth_cmd_buffer *iob;54665466+ struct qeth_ipa_cmd *cmd;54675467+54685468+ QETH_DBF_TEXT(trace, 4, "setprom");54695469+54705470+ if (((dev->flags & IFF_PROMISC) &&54715471+ (card->info.promisc_mode == SET_PROMISC_MODE_ON)) ||54725472+ (!(dev->flags & IFF_PROMISC) &&54735473+ (card->info.promisc_mode == SET_PROMISC_MODE_OFF)))54745474+ return;54755475+ mode = SET_PROMISC_MODE_OFF;54765476+ if (dev->flags & IFF_PROMISC)54775477+ mode = SET_PROMISC_MODE_ON;54785478+ QETH_DBF_TEXT_(trace, 4, "mode:%x", mode);54795479+54805480+ iob = qeth_get_adapter_cmd(card, IPA_SETADP_SET_PROMISC_MODE,54815481+ sizeof(struct qeth_ipacmd_setadpparms));54825482+ cmd = (struct qeth_ipa_cmd *)(iob->data + IPA_PDU_HEADER_SIZE);54835483+ cmd->data.setadapterparms.data.mode = mode;54845484+ qeth_send_ipa_cmd(card, iob, qeth_setadp_promisc_mode_cb, NULL);54855485+}5506548655075487/**55085488 * set multicast address on card···5570544455715445 QETH_DBF_TEXT(trace,3,"setmulti");55725446 qeth_delete_mc_addresses(card);54475447+ if (card->options.layer2) {54485448+ qeth_layer2_add_multicast(card);54495449+ goto out;54505450+ }55735451 qeth_add_multicast_ipv4(card);55745452#ifdef CONFIG_QETH_IPV655755453 qeth_add_multicast_ipv6(card);55765454#endif54555455+out:55775456 if (qeth_set_thread_start_bit(card, QETH_SET_IP_THREAD) == 0)55785457 schedule_work(&card->kernel_thread_starter);54585458+ if (!qeth_adp_supported(card, IPA_SETADP_SET_PROMISC_MODE))54595459+ return;54605460+ if (qeth_set_thread_start_bit(card, QETH_SET_PROMISC_MODE_THREAD)==0)54615461+ schedule_work(&card->kernel_thread_starter);54625462+55795463}5580546455815465static int···57935657 in_dev_put(in4_dev);57945658}5795565956605660+static void56615661+qeth_layer2_add_multicast(struct qeth_card *card)56625662+{56635663+ struct qeth_ipaddr *ipm;56645664+ struct dev_mc_list *dm;56655665+56665666+ QETH_DBF_TEXT(trace,4,"L2addmc");56675667+ for (dm = card->dev->mc_list; dm; dm = dm->next) {56685668+ ipm = qeth_get_addr_buffer(QETH_PROT_IPV4);56695669+ if (!ipm)56705670+ continue;56715671+ memcpy(ipm->mac,dm->dmi_addr,MAX_ADDR_LEN);56725672+ ipm->is_multicast = 1;56735673+ if (!qeth_add_ip(card, ipm))56745674+ kfree(ipm);56755675+ }56765676+}56775677+57965678#ifdef CONFIG_QETH_IPV657975679static inline void57985680qeth_add_mc6(struct qeth_card *card, struct inet6_dev *in6_dev)···59795825 PRINT_WARN("Error in registering MAC address on " \59805826 "device %s: x%x\n", CARD_BUS_ID(card),59815827 cmd->hdr.return_code);59825982- card->info.layer2_mac_registered = 0;58285828+ card->info.mac_bits &= ~QETH_LAYER2_MAC_REGISTERED;59835829 cmd->hdr.return_code = -EIO;59845830 } else {59855985- card->info.layer2_mac_registered = 1;58315831+ card->info.mac_bits |= QETH_LAYER2_MAC_REGISTERED;59865832 memcpy(card->dev->dev_addr,cmd->data.setdelmac.mac,59875833 OSA_ADDR_LEN);59885834 PRINT_INFO("MAC address %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x "···60205866 cmd->hdr.return_code = -EIO;60215867 return 0;60225868 }60236023- card->info.layer2_mac_registered = 0;58695869+ card->info.mac_bits &= ~QETH_LAYER2_MAC_REGISTERED;6024587060255871 return 0;60265872}···60285874qeth_layer2_send_delmac(struct qeth_card *card, __u8 *mac)60295875{60305876 QETH_DBF_TEXT(trace, 2, "L2Delmac");60316031- if (!card->info.layer2_mac_registered)58775877+ if (!(card->info.mac_bits & QETH_LAYER2_MAC_REGISTERED))60325878 return 0;60335879 return qeth_layer2_send_setdelmac(card, mac, IPA_CMD_DELVMAC,60345880 qeth_layer2_send_delmac_cb);···60505896 card = (struct qeth_card *) dev->priv;6051589760525898 if (!card->options.layer2) {60536053- PRINT_WARN("Setting MAC address on %s is not supported"58995899+ PRINT_WARN("Setting MAC address on %s is not supported "60545900 "in Layer 3 mode.\n", dev->name);60555901 QETH_DBF_TEXT(trace, 3, "setmcLY3");60565902 return -EOPNOTSUPP;···65956441 return 0;65966442}6597644364446444+64456445+65986446static int65996447qeth_query_setadapterparms_cb(struct qeth_card *card, struct qeth_reply *reply,66006448 unsigned long data)···66376481 QETH_DBF_TEXT(trace,4,"chgmaccb");6638648266396483 cmd = (struct qeth_ipa_cmd *) data;66406640- memcpy(card->dev->dev_addr,66416641- &cmd->data.setadapterparms.data.change_addr.addr,OSA_ADDR_LEN);64846484+ if (!card->options.layer2 || card->info.guestlan ||64856485+ !(card->info.mac_bits & QETH_LAYER2_MAC_READ)) { 64866486+ memcpy(card->dev->dev_addr,64876487+ &cmd->data.setadapterparms.data.change_addr.addr,64886488+ OSA_ADDR_LEN);64896489+ card->info.mac_bits |= QETH_LAYER2_MAC_READ;64906490+ }66426491 qeth_default_setadapterparms_cb(card, reply, (unsigned long) cmd);66436492 return 0;66446493}···6762660167636602 QETH_DBF_TEXT(setup, 2, "doL2init");67646603 QETH_DBF_TEXT_(setup, 2, "doL2%s", CARD_BUS_ID(card));66046604+66056605+ rc = qeth_query_setadapterparms(card);66066606+ if (rc) {66076607+ PRINT_WARN("could not query adapter parameters on device %s: "66086608+ "x%x\n", CARD_BUS_ID(card), rc);66096609+ }6765661067666611 rc = qeth_setadpparms_change_macaddr(card);67676612 if (rc) {···87158548EXPORT_SYMBOL(qeth_osn_assist);87168549module_init(qeth_init);87178550module_exit(qeth_exit);87188718-MODULE_AUTHOR("Frank Pavlic <pavlic@de.ibm.com>");85518551+MODULE_AUTHOR("Frank Pavlic <fpavlic@de.ibm.com>");87198552MODULE_DESCRIPTION("Linux on zSeries OSA Express and HiperSockets support\n" \87208553 "Copyright 2000,2003 IBM Corporation\n");87218554
+1-1
drivers/s390/net/qeth_mpc.c
···44 * Linux on zSeries OSA Express and HiperSockets support55 *66 * Copyright 2000,2003 IBM Corporation77- * Author(s): Frank Pavlic <pavlic@de.ibm.com>77+ * Author(s): Frank Pavlic <fpavlic@de.ibm.com>88 * Thomas Spatzier <tspat@de.ibm.com>99 *1010 */