Annotation of qemu/roms/ipxe/src/drivers/net/3c595.c, revision 1.1.1.1

1.1       root        1: /*
                      2: * 3c595.c -- 3COM 3C595 Fast Etherlink III PCI driver for etherboot
                      3: *
                      4: * Copyright (C) 2000 Shusuke Nisiyama <[email protected]>
                      5: * All rights reserved.
                      6: * Mar. 14, 2000
                      7: *
                      8: *  This software may be used, modified, copied, distributed, and sold, in
                      9: *  both source and binary form provided that the above copyright and these
                     10: *  terms are retained. Under no circumstances are the authors responsible for
                     11: *  the proper functioning of this software, nor do the authors assume any
                     12: *  responsibility for damages incurred with its use.
                     13: *
                     14: * This code is based on Martin Renters' etherboot-4.4.3 3c509.c and 
                     15: * Herb Peyerl's FreeBSD 3.4-RELEASE if_vx.c driver.
                     16: *
                     17: *  Copyright (C) 1993-1994, David Greenman, Martin Renters.
                     18: *  Copyright (C) 1993-1995, Andres Vega Garcia.
                     19: *  Copyright (C) 1995, Serge Babkin.
                     20: *
                     21: *  Copyright (c) 1994 Herb Peyerl <[email protected]>
                     22: *
                     23: * timlegge     08-24-2003      Add Multicast Support
                     24: */
                     25: 
                     26: FILE_LICENCE ( BSD2 );
                     27: 
                     28: /* #define EDEBUG */
                     29: 
                     30: #include "etherboot.h"
                     31: #include "nic.h"
                     32: #include <ipxe/pci.h>
                     33: #include <ipxe/ethernet.h>
                     34: #include "3c595.h"
                     35: 
                     36: static struct nic_operations t595_operations;
                     37: 
                     38: static unsigned short  eth_nic_base;
                     39: static unsigned short  vx_connector, vx_connectors;
                     40: 
                     41: static struct connector_entry {
                     42:   int bit;
                     43:   char *name;
                     44: } conn_tab[VX_CONNECTORS] = {
                     45: #define CONNECTOR_UTP   0
                     46:   { 0x08, "utp"},
                     47: #define CONNECTOR_AUI   1
                     48:   { 0x20, "aui"},
                     49: /* dummy */
                     50:   { 0, "???"},
                     51: #define CONNECTOR_BNC   3
                     52:   { 0x10, "bnc"},
                     53: #define CONNECTOR_TX    4
                     54:   { 0x02, "tx"},
                     55: #define CONNECTOR_FX    5
                     56:   { 0x04, "fx"},
                     57: #define CONNECTOR_MII   6
                     58:   { 0x40, "mii"},
                     59:   { 0, "???"}
                     60: };
                     61: 
                     62: static void vxgetlink(void);
                     63: static void vxsetlink(void);
                     64: 
                     65: /**************************************************************************
                     66: ETH_RESET - Reset adapter
                     67: ***************************************************************************/
                     68: static void t595_reset(struct nic *nic)
                     69: {
                     70:        int i;
                     71: 
                     72:        /***********************************************************
                     73:                        Reset 3Com 595 card
                     74:        *************************************************************/
                     75: 
                     76:        /* stop card */
                     77:        outw(RX_DISABLE, BASE + VX_COMMAND);
                     78:        outw(RX_DISCARD_TOP_PACK, BASE + VX_COMMAND);
                     79:        VX_BUSY_WAIT;
                     80:        outw(TX_DISABLE, BASE + VX_COMMAND);
                     81:        outw(STOP_TRANSCEIVER, BASE + VX_COMMAND);
                     82:        udelay(8000);
                     83:        outw(RX_RESET, BASE + VX_COMMAND);
                     84:        VX_BUSY_WAIT;
                     85:        outw(TX_RESET, BASE + VX_COMMAND);
                     86:        VX_BUSY_WAIT;
                     87:        outw(C_INTR_LATCH, BASE + VX_COMMAND);
                     88:        outw(SET_RD_0_MASK, BASE + VX_COMMAND);
                     89:        outw(SET_INTR_MASK, BASE + VX_COMMAND);
                     90:        outw(SET_RX_FILTER, BASE + VX_COMMAND);
                     91: 
                     92:        /*
                     93:        * initialize card
                     94:        */
                     95:        VX_BUSY_WAIT;
                     96: 
                     97:        GO_WINDOW(0);
                     98: 
                     99:        /* Disable the card */
                    100: /*     outw(0, BASE + VX_W0_CONFIG_CTRL); */
                    101: 
                    102:        /* Configure IRQ to none */
                    103: /*     outw(SET_IRQ(0), BASE + VX_W0_RESOURCE_CFG); */
                    104: 
                    105:        /* Enable the card */
                    106: /*     outw(ENABLE_DRQ_IRQ, BASE + VX_W0_CONFIG_CTRL); */
                    107: 
                    108:        GO_WINDOW(2);
                    109: 
                    110:        /* Reload the ether_addr. */
                    111:        for (i = 0; i < ETH_ALEN; i++)
                    112:                outb(nic->node_addr[i], BASE + VX_W2_ADDR_0 + i);
                    113: 
                    114:        outw(RX_RESET, BASE + VX_COMMAND);
                    115:        VX_BUSY_WAIT;
                    116:        outw(TX_RESET, BASE + VX_COMMAND);
                    117:        VX_BUSY_WAIT;
                    118: 
                    119:        /* Window 1 is operating window */
                    120:        GO_WINDOW(1);
                    121:        for (i = 0; i < 31; i++)
                    122:                inb(BASE + VX_W1_TX_STATUS);
                    123: 
                    124:        outw(SET_RD_0_MASK | S_CARD_FAILURE | S_RX_COMPLETE |
                    125:                S_TX_COMPLETE | S_TX_AVAIL, BASE + VX_COMMAND);
                    126:        outw(SET_INTR_MASK | S_CARD_FAILURE | S_RX_COMPLETE |
                    127:                S_TX_COMPLETE | S_TX_AVAIL, BASE + VX_COMMAND);
                    128: 
                    129: /*
                    130:  * Attempt to get rid of any stray interrupts that occured during
                    131:  * configuration.  On the i386 this isn't possible because one may
                    132:  * already be queued.  However, a single stray interrupt is
                    133:  * unimportant.
                    134:  */
                    135: 
                    136:        outw(ACK_INTR | 0xff, BASE + VX_COMMAND);
                    137: 
                    138:        outw(SET_RX_FILTER | FIL_INDIVIDUAL |
                    139:            FIL_BRDCST|FIL_MULTICAST, BASE + VX_COMMAND);
                    140: 
                    141:        vxsetlink();
                    142: /*{
                    143:        int i,j;
                    144:        i = CONNECTOR_TX;
                    145:        GO_WINDOW(3);
                    146:        j = inl(BASE + VX_W3_INTERNAL_CFG) & ~INTERNAL_CONNECTOR_MASK;
                    147:        outl(BASE + VX_W3_INTERNAL_CFG, j | (i <<INTERNAL_CONNECTOR_BITS));
                    148:         GO_WINDOW(4);
                    149:         outw(LINKBEAT_ENABLE, BASE + VX_W4_MEDIA_TYPE);
                    150:         GO_WINDOW(1);
                    151: }*/
                    152: 
                    153:        /* start tranciever and receiver */
                    154:        outw(RX_ENABLE, BASE + VX_COMMAND);
                    155:        outw(TX_ENABLE, BASE + VX_COMMAND);
                    156: 
                    157: }
                    158: 
                    159: /**************************************************************************
                    160: ETH_TRANSMIT - Transmit a frame
                    161: ***************************************************************************/
                    162: static char padmap[] = {
                    163:        0, 3, 2, 1};
                    164: 
                    165: static void t595_transmit(
                    166: struct nic *nic,
                    167: const char *d,                 /* Destination */
                    168: unsigned int t,                        /* Type */
                    169: unsigned int s,                        /* size */
                    170: const char *p)                 /* Packet */
                    171: {
                    172:        register int len;
                    173:        int pad;
                    174:        int status;
                    175: 
                    176: #ifdef EDEBUG
                    177:        printf("{l=%d,t=%hX}",s+ETH_HLEN,t);
                    178: #endif
                    179: 
                    180:        /* swap bytes of type */
                    181:        t= htons(t);
                    182: 
                    183:        len=s+ETH_HLEN; /* actual length of packet */
                    184:        pad = padmap[len & 3];
                    185: 
                    186:        /*
                    187:        * The 3c595 automatically pads short packets to minimum ethernet length,
                    188:        * but we drop packets that are too large. Perhaps we should truncate
                    189:        * them instead?
                    190:        */
                    191:        if (len + pad > ETH_FRAME_LEN) {
                    192:                return;
                    193:        }
                    194: 
                    195:        /* drop acknowledgements */
                    196:        while(( status=inb(BASE + VX_W1_TX_STATUS) )& TXS_COMPLETE ) {
                    197:                if(status & (TXS_UNDERRUN|TXS_MAX_COLLISION|TXS_STATUS_OVERFLOW)) {
                    198:                        outw(TX_RESET, BASE + VX_COMMAND);
                    199:                        outw(TX_ENABLE, BASE + VX_COMMAND);
                    200:                }
                    201: 
                    202:                outb(0x0, BASE + VX_W1_TX_STATUS);
                    203:        }
                    204: 
                    205:        while (inw(BASE + VX_W1_FREE_TX) < len + pad + 4) {
                    206:                /* no room in FIFO */
                    207:        }
                    208: 
                    209:        outw(len, BASE + VX_W1_TX_PIO_WR_1);
                    210:        outw(0x0, BASE + VX_W1_TX_PIO_WR_1);    /* Second dword meaningless */
                    211: 
                    212:        /* write packet */
                    213:        outsw(BASE + VX_W1_TX_PIO_WR_1, d, ETH_ALEN/2);
                    214:        outsw(BASE + VX_W1_TX_PIO_WR_1, nic->node_addr, ETH_ALEN/2);
                    215:        outw(t, BASE + VX_W1_TX_PIO_WR_1);
                    216:        outsw(BASE + VX_W1_TX_PIO_WR_1, p, s / 2);
                    217:        if (s & 1)
                    218:                outb(*(p+s - 1), BASE + VX_W1_TX_PIO_WR_1);
                    219: 
                    220:        while (pad--)
                    221:                outb(0, BASE + VX_W1_TX_PIO_WR_1);      /* Padding */
                    222: 
                    223:         /* wait for Tx complete */
                    224:         while((inw(BASE + VX_STATUS) & S_COMMAND_IN_PROGRESS) != 0)
                    225:                 ;
                    226: }
                    227: 
                    228: /**************************************************************************
                    229: ETH_POLL - Wait for a frame
                    230: ***************************************************************************/
                    231: static int t595_poll(struct nic *nic, int retrieve)
                    232: {
                    233:        /* common variables */
                    234:        /* variables for 3C595 */
                    235:        short status, cst;
                    236:        register short rx_fifo;
                    237: 
                    238:        cst=inw(BASE + VX_STATUS);
                    239: 
                    240: #ifdef EDEBUG
                    241:        if(cst & 0x1FFF)
                    242:                printf("-%hX-",cst);
                    243: #endif
                    244: 
                    245:        if( (cst & S_RX_COMPLETE)==0 ) {
                    246:                /* acknowledge  everything */
                    247:                outw(ACK_INTR | cst, BASE + VX_COMMAND);
                    248:                outw(C_INTR_LATCH, BASE + VX_COMMAND);
                    249: 
                    250:                return 0;
                    251:        }
                    252: 
                    253:        status = inw(BASE + VX_W1_RX_STATUS);
                    254: #ifdef EDEBUG
                    255:        printf("*%hX*",status);
                    256: #endif
                    257: 
                    258:        if (status & ERR_RX) {
                    259:                outw(RX_DISCARD_TOP_PACK, BASE + VX_COMMAND);
                    260:                return 0;
                    261:        }
                    262: 
                    263:        rx_fifo = status & RX_BYTES_MASK;
                    264:        if (rx_fifo==0)
                    265:                return 0;
                    266: 
                    267:        if ( ! retrieve ) return 1;
                    268: 
                    269:                /* read packet */
                    270: #ifdef EDEBUG
                    271:        printf("[l=%d",rx_fifo);
                    272: #endif
                    273:        insw(BASE + VX_W1_RX_PIO_RD_1, nic->packet, rx_fifo / 2);
                    274:        if(rx_fifo & 1)
                    275:                nic->packet[rx_fifo-1]=inb(BASE + VX_W1_RX_PIO_RD_1);
                    276:        nic->packetlen=rx_fifo;
                    277: 
                    278:        while(1) {
                    279:                status = inw(BASE + VX_W1_RX_STATUS);
                    280: #ifdef EDEBUG
                    281:                printf("*%hX*",status);
                    282: #endif
                    283:                rx_fifo = status & RX_BYTES_MASK;
                    284: 
                    285:                if(rx_fifo>0) {
                    286:                        insw(BASE + VX_W1_RX_PIO_RD_1, nic->packet+nic->packetlen, rx_fifo / 2);
                    287:                        if(rx_fifo & 1)
                    288:                                nic->packet[nic->packetlen+rx_fifo-1]=inb(BASE + VX_W1_RX_PIO_RD_1);
                    289:                        nic->packetlen+=rx_fifo;
                    290: #ifdef EDEBUG
                    291:                        printf("+%d",rx_fifo);
                    292: #endif
                    293:                }
                    294:                if(( status & RX_INCOMPLETE )==0) {
                    295: #ifdef EDEBUG
                    296:                        printf("=%d",nic->packetlen);
                    297: #endif
                    298:                        break;
                    299:                }
                    300:                udelay(1000);
                    301:        }
                    302: 
                    303:        /* acknowledge reception of packet */
                    304:        outw(RX_DISCARD_TOP_PACK, BASE + VX_COMMAND);
                    305:        while (inw(BASE + VX_STATUS) & S_COMMAND_IN_PROGRESS);
                    306: #ifdef EDEBUG
                    307: {
                    308:        unsigned short type = 0;        /* used by EDEBUG */
                    309:        type = (nic->packet[12]<<8) | nic->packet[13];
                    310:        if(nic->packet[0]+nic->packet[1]+nic->packet[2]+nic->packet[3]+nic->packet[4]+
                    311:            nic->packet[5] == 0xFF*ETH_ALEN)
                    312:                printf(",t=%hX,b]",type);
                    313:        else
                    314:                printf(",t=%hX]",type);
                    315: }
                    316: #endif
                    317:        return 1;
                    318: }
                    319: 
                    320: 
                    321: /*************************************************************************
                    322:        3Com 595 - specific routines
                    323: **************************************************************************/
                    324: 
                    325: static int
                    326: eeprom_rdy()
                    327: {
                    328:        int i;
                    329: 
                    330:        for (i = 0; is_eeprom_busy(BASE) && i < MAX_EEPROMBUSY; i++)
                    331:                udelay(1000);
                    332:        if (i >= MAX_EEPROMBUSY) {
                    333:                /* printf("3c595: eeprom failed to come ready.\n"); */
                    334:                printf("3c595: eeprom is busy.\n"); /* memory in EPROM is tight */
                    335:                return (0);
                    336:        }
                    337:        return (1);
                    338: }
                    339: 
                    340: /*
                    341:  * get_e: gets a 16 bits word from the EEPROM. we must have set the window
                    342:  * before
                    343:  */
                    344: static int
                    345: get_e(offset)
                    346: int offset;
                    347: {
                    348:        if (!eeprom_rdy())
                    349:                return (0xffff);
                    350:        outw(EEPROM_CMD_RD | offset, BASE + VX_W0_EEPROM_COMMAND);
                    351:        if (!eeprom_rdy())
                    352:                return (0xffff);
                    353:        return (inw(BASE + VX_W0_EEPROM_DATA));
                    354: }
                    355: 
                    356: static void            
                    357: vxgetlink(void)
                    358: {
                    359:     int n, k;
                    360: 
                    361:     GO_WINDOW(3);
                    362:     vx_connectors = inw(BASE + VX_W3_RESET_OPT) & 0x7f;
                    363:     for (n = 0, k = 0; k < VX_CONNECTORS; k++) {
                    364:       if (vx_connectors & conn_tab[k].bit) {
                    365:         if (n > 0) {
                    366:           printf("/");
                    367:        }
                    368:         printf("%s", conn_tab[k].name );
                    369:         n++;
                    370:       }
                    371:     }
                    372:     if (vx_connectors == 0) {
                    373:         printf("no connectors!");
                    374:         return;
                    375:     }
                    376:     GO_WINDOW(3);
                    377:     vx_connector = (inl(BASE + VX_W3_INTERNAL_CFG) 
                    378:                         & INTERNAL_CONNECTOR_MASK) 
                    379:                         >> INTERNAL_CONNECTOR_BITS;
                    380:     if (vx_connector & 0x10) {
                    381:         vx_connector &= 0x0f;
                    382:         printf("[*%s*]", conn_tab[vx_connector].name);
                    383:         printf(": disable 'auto select' with DOS util!");
                    384:     } else {
                    385:         printf("[*%s*]", conn_tab[vx_connector].name);
                    386:     }
                    387: }
                    388: 
                    389: static void            
                    390: vxsetlink(void)
                    391: {       
                    392:     int i, j;
                    393:     char *reason, *warning;
                    394:     static char prev_conn = -1;
                    395: 
                    396:     if (prev_conn == -1) {
                    397:         prev_conn = vx_connector;
                    398:     }
                    399: 
                    400:     i = vx_connector;       /* default in EEPROM */
                    401:     reason = "default";
                    402:     warning = 0;
                    403: 
                    404:     if ((vx_connectors & conn_tab[vx_connector].bit) == 0) {
                    405:         warning = "strange connector type in EEPROM.";
                    406:         reason = "forced";
                    407:         i = CONNECTOR_UTP;
                    408:     }
                    409: 
                    410:         if (warning != 0) {
                    411:             printf("warning: %s\n", warning);
                    412:         }
                    413:         printf("selected %s. (%s)\n", conn_tab[i].name, reason);
                    414: 
                    415:     /* Set the selected connector. */
                    416:     GO_WINDOW(3);
                    417:     j = inl(BASE + VX_W3_INTERNAL_CFG) & ~INTERNAL_CONNECTOR_MASK;
                    418:     outl(j | (i <<INTERNAL_CONNECTOR_BITS), BASE + VX_W3_INTERNAL_CFG);
                    419: 
                    420:     /* First, disable all. */
                    421:     outw(STOP_TRANSCEIVER, BASE + VX_COMMAND);
                    422:     udelay(8000);
                    423:     GO_WINDOW(4);
                    424:     outw(0, BASE + VX_W4_MEDIA_TYPE);
                    425: 
                    426:     /* Second, enable the selected one. */
                    427:     switch(i) {
                    428:       case CONNECTOR_UTP:
                    429:         GO_WINDOW(4);
                    430:         outw(ENABLE_UTP, BASE + VX_W4_MEDIA_TYPE);
                    431:         break;
                    432:       case CONNECTOR_BNC:
                    433:         outw(START_TRANSCEIVER,BASE + VX_COMMAND);
                    434:         udelay(8000);
                    435:         break;
                    436:       case CONNECTOR_TX:
                    437:       case CONNECTOR_FX:
                    438:         GO_WINDOW(4);
                    439:         outw(LINKBEAT_ENABLE, BASE + VX_W4_MEDIA_TYPE);
                    440:         break;
                    441:       default:  /* AUI and MII fall here */
                    442:         break;
                    443:     }
                    444:     GO_WINDOW(1); 
                    445: }
                    446: 
                    447: static void t595_disable ( struct nic *nic ) {
                    448: 
                    449:        t595_reset(nic);
                    450: 
                    451:        outw(STOP_TRANSCEIVER, BASE + VX_COMMAND);
                    452:        udelay(8000);
                    453:        GO_WINDOW(4);
                    454:        outw(0, BASE + VX_W4_MEDIA_TYPE);
                    455:        GO_WINDOW(1);
                    456: }
                    457: 
                    458: static void t595_irq(struct nic *nic __unused, irq_action_t action __unused)
                    459: {
                    460:   switch ( action ) {
                    461:   case DISABLE :
                    462:     break;
                    463:   case ENABLE :
                    464:     break;
                    465:   case FORCE :
                    466:     break;
                    467:   }
                    468: }
                    469: 
                    470: /**************************************************************************
                    471: ETH_PROBE - Look for an adapter
                    472: ***************************************************************************/
                    473: static int t595_probe ( struct nic *nic, struct pci_device *pci ) {
                    474: 
                    475:        int i;
                    476:        unsigned short *p;
                    477: 
                    478:        if (pci->ioaddr == 0)
                    479:                return 0;
                    480:        eth_nic_base = pci->ioaddr;
                    481: 
                    482:        nic->irqno  = 0;
                    483:        nic->ioaddr = pci->ioaddr;
                    484: 
                    485:        GO_WINDOW(0);
                    486:        outw(GLOBAL_RESET, BASE + VX_COMMAND);
                    487:        VX_BUSY_WAIT;
                    488: 
                    489:        vxgetlink();
                    490: 
                    491: /*
                    492:        printf("\nEEPROM:");
                    493:        for (i = 0; i < (EEPROMSIZE/2); i++) {
                    494:          printf("%hX:", get_e(i));
                    495:        }
                    496:        printf("\n");
                    497: */
                    498:        /*
                    499:        * Read the station address from the eeprom
                    500:        */
                    501:        p = (unsigned short *) nic->node_addr;
                    502:        for (i = 0; i < 3; i++) {
                    503:                GO_WINDOW(0);
                    504:                p[i] = htons(get_e(EEPROM_OEM_ADDR_0 + i));
                    505:                GO_WINDOW(2);
                    506:                outw(ntohs(p[i]), BASE + VX_W2_ADDR_0 + (i * 2));
                    507:        }
                    508: 
                    509:        DBG ( "Ethernet address: %s\n", eth_ntoa (nic->node_addr) );
                    510: 
                    511:        t595_reset(nic);
                    512:        nic->nic_op     = &t595_operations;
                    513:        return 1;
                    514: 
                    515: }
                    516: 
                    517: static struct nic_operations t595_operations = {
                    518:        .connect        = dummy_connect,
                    519:        .poll           = t595_poll,
                    520:        .transmit       = t595_transmit,
                    521:        .irq            = t595_irq,
                    522: 
                    523: };
                    524: 
                    525: static struct pci_device_id t595_nics[] = {
                    526: PCI_ROM(0x10b7, 0x5900, "3c590",           "3Com590", 0),              /* Vortex 10Mbps */
                    527: PCI_ROM(0x10b7, 0x5950, "3c595",           "3Com595", 0),              /* Vortex 100baseTx */
                    528: PCI_ROM(0x10b7, 0x5951, "3c595-1",         "3Com595", 0),              /* Vortex 100baseT4 */
                    529: PCI_ROM(0x10b7, 0x5952, "3c595-2",         "3Com595", 0),              /* Vortex 100base-MII */
                    530: PCI_ROM(0x10b7, 0x9000, "3c900-tpo",       "3Com900-TPO", 0),  /* 10 Base TPO */
                    531: PCI_ROM(0x10b7, 0x9001, "3c900-t4",        "3Com900-Combo", 0),        /* 10/100 T4 */
                    532: PCI_ROM(0x10b7, 0x9004, "3c900b-tpo",      "3Com900B-TPO", 0), /* 10 Base TPO */
                    533: PCI_ROM(0x10b7, 0x9005, "3c900b-combo",    "3Com900B-Combo", 0),       /* 10 Base Combo */
                    534: PCI_ROM(0x10b7, 0x9006, "3c900b-tpb2",     "3Com900B-2/T", 0), /* 10 Base TP and Base2 */
                    535: PCI_ROM(0x10b7, 0x900a, "3c900b-fl",       "3Com900B-FL", 0),  /* 10 Base F */
                    536: PCI_ROM(0x10b7, 0x9800, "3c980-cyclone-1", "3Com980-Cyclone", 0),      /* Cyclone */
                    537: PCI_ROM(0x10b7, 0x9805, "3c9805-1",        "3Com9805", 0),             /* Dual Port Server Cyclone */
                    538: PCI_ROM(0x10b7, 0x7646, "3csoho100-tx-1",  "3CSOHO100-TX", 0), /* Hurricane */
                    539: PCI_ROM(0x10b7, 0x4500, "3c450-1",         "3Com450 HomePNA Tornado", 0),
                    540: };
                    541: 
                    542: PCI_DRIVER ( t595_driver, t595_nics, PCI_NO_CLASS );
                    543: 
                    544: DRIVER ( "3C595", nic_driver, pci_driver, t595_driver,
                    545:         t595_probe, t595_disable );
                    546: 
                    547: /*
                    548:  * Local variables:
                    549:  *  c-basic-offset: 8
                    550:  *  c-indent-level: 8
                    551:  *  tab-width: 8
                    552:  * End:
                    553:  */

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.