network: allow to set a NIC's link from the status bar
This commit is contained in:
@@ -619,7 +619,7 @@ threec503_nic_init(const device_t *info)
|
||||
dev->regs.gacfr = 0x09; /* Start with RAM mapping enabled. */
|
||||
|
||||
/* Attach ourselves to the network module. */
|
||||
dev->dp8390->card = network_attach(dev->dp8390, dev->dp8390->physaddr, dp8390_rx, NULL, NULL);
|
||||
dev->dp8390->card = network_attach(dev->dp8390, dev->dp8390->physaddr, dp8390_rx, NULL);
|
||||
|
||||
return(dev);
|
||||
}
|
||||
|
||||
@@ -228,7 +228,9 @@ dp8390_write_cr(dp8390_t *dev, uint32_t val)
|
||||
/* Send the packet to the system driver */
|
||||
dev->CR.tx_packet = 1;
|
||||
|
||||
network_tx(dev->card, &dev->mem[(dev->tx_page_start * 256) - dev->mem_start], dev->tx_bytes);
|
||||
/* TODO: report TX error to the driver ? */
|
||||
if (!(dev->card->link_state & NET_LINK_DOWN))
|
||||
network_tx(dev->card, &dev->mem[(dev->tx_page_start * 256) - dev->mem_start], dev->tx_bytes);
|
||||
|
||||
/* some more debug */
|
||||
#ifdef ENABLE_DP8390_LOG
|
||||
@@ -291,6 +293,8 @@ dp8390_rx_common(void *priv, uint8_t *buf, int io_len)
|
||||
if ((dev->CR.stop != 0) || (dev->page_start == 0))
|
||||
return 0;
|
||||
|
||||
if (dev->card->link_state & NET_LINK_DOWN)
|
||||
return 0;
|
||||
/*
|
||||
* Add the pkt header + CRC to the length, and work
|
||||
* out how many 256-byte pages the frame would occupy.
|
||||
|
||||
@@ -1122,7 +1122,7 @@ nic_init(const device_t *info)
|
||||
nic_reset(dev);
|
||||
|
||||
/* Attach ourselves to the network module. */
|
||||
dev->dp8390->card = network_attach(dev->dp8390, dev->dp8390->physaddr, dp8390_rx, NULL, NULL);
|
||||
dev->dp8390->card = network_attach(dev->dp8390, dev->dp8390->physaddr, dp8390_rx, NULL);
|
||||
|
||||
nelog(1, "%s: %s attached IO=0x%X IRQ=%d\n", dev->name,
|
||||
dev->is_pci?"PCI":"ISA", dev->base_address, dev->base_irq);
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
#include <stdarg.h>
|
||||
#include <wchar.h>
|
||||
#include <time.h>
|
||||
#include <stdbool.h>
|
||||
#define HAVE_STDARG_H
|
||||
#include <86box/86box.h>
|
||||
#include <86box/io.h>
|
||||
@@ -1253,6 +1254,10 @@ pcnetReceiveNoSync(void *priv, uint8_t *buf, int size)
|
||||
if (!pcnetIsLinkUp(dev))
|
||||
return 0;
|
||||
|
||||
dev->fMaybeOutOfSpace = !pcnetCanReceive(dev);
|
||||
if (dev->fMaybeOutOfSpace)
|
||||
return 0;
|
||||
|
||||
pcnetlog(1, "%s: pcnetReceiveNoSync: RX %x:%x:%x:%x:%x:%x > %x:%x:%x:%x:%x:%x len %d\n", dev->name,
|
||||
buf[6], buf[7], buf[8], buf[9], buf[10], buf[11],
|
||||
buf[0], buf[1], buf[2], buf[3], buf[4], buf[5],
|
||||
@@ -2095,12 +2100,13 @@ pcnet_mii_readw(nic_t *dev, uint16_t miiaddr)
|
||||
| 0x0008 /* Able to do auto-negotiation. */
|
||||
| 0x0004 /* Link up. */
|
||||
| 0x0001; /* Extended Capability, i.e. registers 4+ valid. */
|
||||
if (!dev->fLinkUp || dev->fLinkTempDown || isolate) {
|
||||
if (!pcnetIsLinkUp(dev) || isolate) {
|
||||
val &= ~(0x0020 | 0x0004);
|
||||
dev->cLinkDownReported++;
|
||||
}
|
||||
if (!autoneg) {
|
||||
/* Auto-negotiation disabled. */
|
||||
val &= ~(0x0020 | 0x0008);
|
||||
if (duplex)
|
||||
val &= ~0x2800; /* Full duplex forced. */
|
||||
else
|
||||
@@ -2131,7 +2137,7 @@ pcnet_mii_readw(nic_t *dev, uint16_t miiaddr)
|
||||
|
||||
case 5:
|
||||
/* Link partner ability register. */
|
||||
if (dev->fLinkUp && !dev->fLinkTempDown && !isolate) {
|
||||
if (pcnetIsLinkUp(dev) && !isolate) {
|
||||
val = 0x8000 /* Next page bit. */
|
||||
| 0x4000 /* Link partner acked us. */
|
||||
| 0x0400 /* Can do flow control. */
|
||||
@@ -2145,7 +2151,7 @@ pcnet_mii_readw(nic_t *dev, uint16_t miiaddr)
|
||||
|
||||
case 6:
|
||||
/* Auto negotiation expansion register. */
|
||||
if (dev->fLinkUp && !dev->fLinkTempDown && !isolate) {
|
||||
if (pcnetIsLinkUp(dev) && !isolate) {
|
||||
val = 0x0008 /* Link partner supports npage. */
|
||||
| 0x0004 /* Enable npage words. */
|
||||
| 0x0001; /* Can do N-way auto-negotiation. */
|
||||
@@ -2157,7 +2163,7 @@ pcnet_mii_readw(nic_t *dev, uint16_t miiaddr)
|
||||
|
||||
case 18:
|
||||
/* Diagnostic Register (FreeBSD pcn/ac101 driver reads this). */
|
||||
if (dev->fLinkUp && !dev->fLinkTempDown && !isolate) {
|
||||
if (pcnetIsLinkUp(dev) && !isolate) {
|
||||
val = 0x1000 /* Receive PLL locked. */
|
||||
| 0x0200; /* Signal detected. */
|
||||
|
||||
@@ -2195,7 +2201,7 @@ pcnet_bcr_readw(nic_t *dev, uint16_t rap)
|
||||
case BCR_LED2:
|
||||
case BCR_LED3:
|
||||
val = dev->aBCR[rap] & ~0x8000;
|
||||
if (dev->fLinkTempDown || !dev->fLinkUp) {
|
||||
if (!(pcnetIsLinkUp(dev))) {
|
||||
if (rap == 4)
|
||||
dev->cLinkDownReported++;
|
||||
val &= ~0x40;
|
||||
@@ -2846,40 +2852,28 @@ pcnetCanReceive(nic_t *dev)
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
pcnetWaitReceiveAvail(void *priv)
|
||||
pcnetSetLinkState(void *priv, uint32_t link_state)
|
||||
{
|
||||
nic_t *dev = (nic_t *) priv;
|
||||
|
||||
dev->fMaybeOutOfSpace = !pcnetCanReceive(dev);
|
||||
|
||||
return dev->fMaybeOutOfSpace;
|
||||
}
|
||||
|
||||
static int
|
||||
pcnetSetLinkState(void *priv)
|
||||
{
|
||||
nic_t *dev = (nic_t *) priv;
|
||||
int fLinkUp;
|
||||
|
||||
if (dev->fLinkTempDown) {
|
||||
pcnetTempLinkDown(dev);
|
||||
return 1;
|
||||
if (link_state & NET_LINK_TEMP_DOWN) {
|
||||
pcnetTempLinkDown(dev);
|
||||
return 1;
|
||||
}
|
||||
|
||||
fLinkUp = (dev->fLinkUp && !dev->fLinkTempDown);
|
||||
if (dev->fLinkUp != fLinkUp) {
|
||||
dev->fLinkUp = fLinkUp;
|
||||
if (fLinkUp) {
|
||||
dev->fLinkTempDown = 1;
|
||||
dev->cLinkDownReported = 0;
|
||||
dev->aCSR[0] |= 0x8000 | 0x2000; /* ERR | CERR (this is probably wrong) */
|
||||
timer_set_delay_u64(&dev->timer_restore, (dev->cMsLinkUpDelay * 1000) * TIMER_USEC);
|
||||
} else {
|
||||
dev->cLinkDownReported = 0;
|
||||
dev->aCSR[0] |= 0x8000 | 0x2000; /* ERR | CERR (this is probably wrong) */
|
||||
}
|
||||
bool link_up = !(link_state & NET_LINK_DOWN);
|
||||
if (dev->fLinkUp != link_up) {
|
||||
dev->fLinkUp = link_up;
|
||||
if (link_up) {
|
||||
dev->fLinkTempDown = 1;
|
||||
dev->cLinkDownReported = 0;
|
||||
dev->aCSR[0] |= 0x8000 | 0x2000;
|
||||
timer_set_delay_u64(&dev->timer_restore, (dev->cMsLinkUpDelay * 1000) * TIMER_USEC);
|
||||
} else {
|
||||
dev->cLinkDownReported = 0;
|
||||
dev->aCSR[0] |= 0x8000 | 0x2000;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -3058,7 +3052,7 @@ pcnet_init(const device_t *info)
|
||||
pcnetHardReset(dev);
|
||||
|
||||
/* Attach ourselves to the network module. */
|
||||
dev->netcard = network_attach(dev, dev->aPROM, pcnetReceiveNoSync, pcnetWaitReceiveAvail, pcnetSetLinkState);
|
||||
dev->netcard = network_attach(dev, dev->aPROM, pcnetReceiveNoSync, pcnetSetLinkState);
|
||||
dev->netcard->byte_period = (dev->board == DEV_AM79C973) ? NET_PERIOD_100M : NET_PERIOD_10M;
|
||||
|
||||
timer_add(&dev->timer, pcnetPollTimer, dev, 0);
|
||||
|
||||
@@ -476,7 +476,7 @@ plip_net_init(const device_t *info)
|
||||
}
|
||||
|
||||
plip_log(1, " (attached to LPT)\n");
|
||||
instance->card = network_attach(instance, instance->mac, plip_rx, NULL, NULL);
|
||||
instance->card = network_attach(instance, instance->mac, plip_rx, NULL);
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
@@ -788,7 +788,7 @@ wd_init(const device_t *info)
|
||||
mem_mapping_disable(&dev->ram_mapping);
|
||||
|
||||
/* Attach ourselves to the network module. */
|
||||
dev->dp8390->card = network_attach(dev->dp8390, dev->dp8390->physaddr, dp8390_rx, NULL, NULL);
|
||||
dev->dp8390->card = network_attach(dev->dp8390, dev->dp8390->physaddr, dp8390_rx, NULL);
|
||||
|
||||
if (!(dev->board_chip & WE_ID_BUS_MCA)) {
|
||||
wdlog("%s: attached IO=0x%X IRQ=%d, RAM addr=0x%06x\n", dev->name,
|
||||
|
||||
@@ -346,6 +346,13 @@ network_rx_queue(void *priv)
|
||||
{
|
||||
netcard_t *card = (netcard_t *)priv;
|
||||
|
||||
uint32_t new_link_state = net_cards_conf[card->card_num].link_state;
|
||||
if (new_link_state != card->link_state) {
|
||||
if (card->set_link_state)
|
||||
card->set_link_state(card->card_drv, new_link_state);
|
||||
card->link_state = new_link_state;
|
||||
}
|
||||
|
||||
uint32_t rx_bytes = 0;
|
||||
for (int i = 0; i < NET_QUEUE_LEN; i++) {
|
||||
if (card->queued_pkt.len == 0) {
|
||||
@@ -386,7 +393,13 @@ network_rx_queue(void *priv)
|
||||
timer_on_auto(&card->timer, timer_period);
|
||||
|
||||
bool activity = rx_bytes || tx_bytes;
|
||||
ui_sb_update_icon(SB_NETWORK, activity);
|
||||
bool led_on = card->led_timer & 0x80000000;
|
||||
if ((activity && !led_on) || (card->led_timer & 0x7fffffff) >= 150000) {
|
||||
ui_sb_update_icon(SB_NETWORK | card->card_num, activity);
|
||||
card->led_timer = 0 | (activity << 31);
|
||||
}
|
||||
|
||||
card->led_timer += timer_period;
|
||||
}
|
||||
|
||||
|
||||
@@ -398,13 +411,12 @@ network_rx_queue(void *priv)
|
||||
* modules.
|
||||
*/
|
||||
netcard_t *
|
||||
network_attach(void *card_drv, uint8_t *mac, NETRXCB rx, NETWAITCB wait, NETSETLINKSTATE set_link_state)
|
||||
network_attach(void *card_drv, uint8_t *mac, NETRXCB rx, NETSETLINKSTATE set_link_state)
|
||||
{
|
||||
netcard_t *card = calloc(1, sizeof(netcard_t));
|
||||
card->queued_pkt.data = calloc(1, NET_MAX_FRAME);
|
||||
card->card_drv = card_drv;
|
||||
card->rx = rx;
|
||||
card->wait = wait;
|
||||
card->set_link_state = set_link_state;
|
||||
card->tx_mutex = thread_create_mutex();
|
||||
card->rx_mutex = thread_create_mutex();
|
||||
@@ -496,8 +508,7 @@ network_reset(void)
|
||||
#endif
|
||||
|
||||
for (i = 0; i < NET_CARD_MAX; i++) {
|
||||
if (!net_cards_conf[i].device_num || net_cards_conf[i].net_type == NET_TYPE_NONE ||
|
||||
(net_cards_conf[i].net_type == NET_TYPE_PCAP && !strcmp(net_cards_conf[i].host_dev_name, "none"))) {
|
||||
if (!network_dev_available(i)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -564,6 +575,28 @@ int network_rx_put_pkt(netcard_t *card, netpkt_t *pkt)
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
network_connect(int id, int connect)
|
||||
{
|
||||
if (id >= NET_CARD_MAX)
|
||||
return;
|
||||
|
||||
if (connect) {
|
||||
net_cards_conf[id].link_state &= ~NET_LINK_DOWN;
|
||||
} else {
|
||||
net_cards_conf[id].link_state |= NET_LINK_DOWN;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
network_is_connected(int id)
|
||||
{
|
||||
if (id >= NET_CARD_MAX)
|
||||
return 0;
|
||||
|
||||
return !(net_cards_conf[id].link_state & NET_LINK_DOWN);
|
||||
}
|
||||
|
||||
int
|
||||
network_dev_to_id(char *devname)
|
||||
{
|
||||
@@ -575,19 +608,29 @@ network_dev_to_id(char *devname)
|
||||
}
|
||||
}
|
||||
|
||||
/* If no match found, assume "none". */
|
||||
return(0);
|
||||
return(-1);
|
||||
}
|
||||
|
||||
|
||||
/* UI */
|
||||
int
|
||||
network_dev_available(int id)
|
||||
{
|
||||
int available = (net_cards_conf[id].device_num > 0) && (net_cards_conf[id].net_type != NET_TYPE_NONE);
|
||||
|
||||
if ((net_cards_conf[id].net_type == NET_TYPE_PCAP && (network_dev_to_id(net_cards_conf[id].host_dev_name) <= 0)))
|
||||
available = 0;
|
||||
|
||||
return available;
|
||||
}
|
||||
|
||||
int
|
||||
network_available(void)
|
||||
{
|
||||
int available = 0;
|
||||
|
||||
for (int i = 0; i < NET_CARD_MAX; i ++) {
|
||||
available |= (net_cards_conf[i].device_num > 0) && (net_cards_conf[i].net_type != NET_TYPE_NONE);
|
||||
available |= network_dev_available(i);
|
||||
}
|
||||
|
||||
return available;
|
||||
|
||||
Reference in New Issue
Block a user