#include "common.h"
#include <linux/rtnetlink.h>
-#define NETIF_HASHSZ 1024
-#define NETIF_HASH(_d,_h) (((int)(_d)^(int)(_h))&(NETIF_HASHSZ-1))
-
-static netif_t *netif_hash[NETIF_HASHSZ];
-
-netif_t *netif_find_by_handle(domid_t domid, unsigned int handle)
-{
- netif_t *netif = netif_hash[NETIF_HASH(domid, handle)];
- while ( (netif != NULL) &&
- ((netif->domid != domid) || (netif->handle != handle)) )
- netif = netif->hash_next;
- return netif;
-}
-
static void __netif_up(netif_t *netif)
{
struct net_device *dev = netif->dev;
static int net_open(struct net_device *dev)
{
netif_t *netif = netdev_priv(dev);
- if ( netif->status == CONNECTED )
+ if (netif->status == CONNECTED)
__netif_up(netif);
netif_start_queue(dev);
return 0;
{
netif_t *netif = netdev_priv(dev);
netif_stop_queue(dev);
- if ( netif->status == CONNECTED )
+ if (netif->status == CONNECTED)
__netif_down(netif);
return 0;
}
{
int err = 0, i;
struct net_device *dev;
- netif_t **pnetif, *netif;
+ netif_t *netif;
char name[IFNAMSIZ] = {};
snprintf(name, IFNAMSIZ - 1, "vif%u.%u", domid, handle);
dev = alloc_netdev(sizeof(netif_t), name, ether_setup);
- if ( dev == NULL )
- {
+ if (dev == NULL) {
DPRINTK("Could not create netif: out of memory\n");
- // create->status = NETIF_BE_STATUS_OUT_OF_MEMORY;
return NULL;
}
netif->credit_usec = 0UL;
init_timer(&netif->credit_timeout);
- pnetif = &netif_hash[NETIF_HASH(domid, handle)];
- while ( *pnetif != NULL )
- {
- if ( ((*pnetif)->domid == domid) && ((*pnetif)->handle == handle) )
- {
- DPRINTK("Could not create netif: already exists\n");
- // create->status = NETIF_BE_STATUS_INTERFACE_EXISTS;
- free_netdev(dev);
- return NULL;
- }
- pnetif = &(*pnetif)->hash_next;
- }
-
dev->hard_start_xmit = netif_be_start_xmit;
dev->get_stats = netif_be_get_stats;
dev->open = net_open;
for (i = 0; i < ETH_ALEN; i++)
if (be_mac[i] != 0)
break;
- if (i == ETH_ALEN)
- {
+ if (i == ETH_ALEN) {
/*
* Initialise a dummy MAC address. We choose the numerically largest
* non-broadcast address to prevent the address getting stolen by an
*/
memset(dev->dev_addr, 0xFF, ETH_ALEN);
dev->dev_addr[0] &= ~0x01;
- }
- else
- {
+ } else
memcpy(dev->dev_addr, be_mac, ETH_ALEN);
- }
rtnl_lock();
err = register_netdevice(dev);
rtnl_unlock();
-
- if ( err != 0 )
- {
+ if (err) {
DPRINTK("Could not register new net device %s: err=%d\n",
dev->name, err);
- // create->status = NETIF_BE_STATUS_OUT_OF_MEMORY;
free_netdev(dev);
return NULL;
}
- netif->hash_next = *pnetif;
- *pnetif = netif;
-
DPRINTK("Successfully created netif\n");
- // create->status = NETIF_BE_STATUS_OKAY;
return netif;
}
evtchn_op_t op = { .cmd = EVTCHNOP_bind_interdomain };
int err;
-#if 0
- if ( netif->status != DISCONNECTED ) {
- connect->status = NETIF_BE_STATUS_INTERFACE_CONNECTED;
- return;
- }
-#endif
-
- if ( (vma = get_vm_area(2*PAGE_SIZE, VM_IOREMAP)) == NULL ) {
- // connect->status = NETIF_BE_STATUS_OUT_OF_MEMORY;
+ vma = get_vm_area(2*PAGE_SIZE, VM_IOREMAP);
+ if (vma == NULL)
return -ENOMEM;
- }
err = map_frontend_page(netif, (unsigned long)vma->addr, tx_ring_ref,
rx_ring_ref);
netif->evtchn = op.u.bind_interdomain.port1;
netif->remote_evtchn = evtchn;
- netif->tx_shmem_frame = tx_ring_ref;
- netif->rx_shmem_frame = rx_ring_ref;
- netif->tx =
- (netif_tx_interface_t *)vma->addr;
- netif->rx =
- (netif_rx_interface_t *)((char *)vma->addr + PAGE_SIZE);
+ netif->tx = (netif_tx_interface_t *)vma->addr;
+ netif->rx = (netif_rx_interface_t *)((char *)vma->addr + PAGE_SIZE);
netif->tx->resp_prod = netif->rx->resp_prod = 0;
netif_get(netif);
wmb(); /* Other CPUs see new state before interface is started. */
rtnl_lock();
netif->status = CONNECTED;
wmb();
- if ( netif_running(netif->dev) )
+ if (netif_running(netif->dev))
__netif_up(netif);
rtnl_unlock();
- // connect->status = NETIF_BE_STATUS_OKAY;
return 0;
}
static void free_netif(void *arg)
{
- netif_t *netif = (netif_t *)arg;
+ evtchn_op_t op = { .cmd = EVTCHNOP_close };
+ netif_t *netif = (netif_t *)arg;
/*
* These can't be done in netif_disconnect() because at that point there
* responses must still be notified to the remote driver.
*/
- unmap_frontend_page(netif);
- vfree(netif->tx); /* Frees netif->rx as well. */
+ op.u.close.port = netif->evtchn;
+ op.u.close.dom = DOMID_SELF;
+ HYPERVISOR_event_channel_op(&op);
+ op.u.close.port = netif->remote_evtchn;
+ op.u.close.dom = netif->domid;
+ HYPERVISOR_event_channel_op(&op);
- netif->status = DISCONNECTED;
+ unregister_netdev(netif->dev);
+
+ if (netif->tx) {
+ unmap_frontend_page(netif);
+ vfree(netif->tx); /* Frees netif->rx as well. */
+ }
+
+ free_netdev(netif->dev);
}
void free_netif_callback(netif_t *netif)
schedule_work(&netif->free_work);
}
-void netif_destroy(netif_be_destroy_t *destroy)
-{
- domid_t domid = destroy->domid;
- unsigned int handle = destroy->netif_handle;
- netif_t **pnetif, *netif;
-
- pnetif = &netif_hash[NETIF_HASH(domid, handle)];
- while ( (netif = *pnetif) != NULL )
- {
- if ( (netif->domid == domid) && (netif->handle == handle) )
- {
- if ( netif->status != DISCONNECTED )
- goto still_connected;
- goto destroy;
- }
- pnetif = &netif->hash_next;
- }
-
- destroy->status = NETIF_BE_STATUS_INTERFACE_NOT_FOUND;
- return;
-
- still_connected:
- destroy->status = NETIF_BE_STATUS_INTERFACE_CONNECTED;
- return;
-
- destroy:
- *pnetif = netif->hash_next;
- unregister_netdev(netif->dev);
- free_netdev(netif->dev);
- destroy->status = NETIF_BE_STATUS_OKAY;
-}
-
-void netif_creditlimit(netif_be_creditlimit_t *creditlimit)
+void netif_creditlimit(netif_t *netif)
{
- domid_t domid = creditlimit->domid;
- unsigned int handle = creditlimit->netif_handle;
- netif_t *netif;
-
- netif = netif_find_by_handle(domid, handle);
- if ( unlikely(netif == NULL) )
- {
- DPRINTK("netif_creditlimit attempted for non-existent netif"
- " (%u,%u)\n", creditlimit->domid, creditlimit->netif_handle);
- creditlimit->status = NETIF_BE_STATUS_INTERFACE_NOT_FOUND;
- return;
- }
-
+#if 0
/* Set the credit limit (reset remaining credit to new limit). */
netif->credit_bytes = netif->remaining_credit = creditlimit->credit_bytes;
netif->credit_usec = creditlimit->period_usec;
- if ( netif->status == CONNECTED )
- {
+ if (netif->status == CONNECTED) {
/*
* Schedule work so that any packets waiting under previous credit
* limit are dealt with (acts like a replenishment point).
netif->credit_timeout.expires = jiffies;
netif_schedule_work(netif);
}
-
- creditlimit->status = NETIF_BE_STATUS_OKAY;
+#endif
}
-int netif_disconnect(netif_be_disconnect_t *disconnect, u8 rsp_id)
+int netif_disconnect(netif_t *netif)
{
- domid_t domid = disconnect->domid;
- unsigned int handle = disconnect->netif_handle;
- netif_t *netif;
- netif = netif_find_by_handle(domid, handle);
- if ( unlikely(netif == NULL) )
- {
- DPRINTK("netif_disconnect attempted for non-existent netif"
- " (%u,%u)\n", disconnect->domid, disconnect->netif_handle);
- disconnect->status = NETIF_BE_STATUS_INTERFACE_NOT_FOUND;
- return 1; /* Caller will send response error message. */
- }
-
- if ( netif->status == CONNECTED )
- {
+ if (netif->status == CONNECTED) {
rtnl_lock();
netif->status = DISCONNECTING;
- netif->disconnect_rspid = rsp_id;
wmb();
- if ( netif_running(netif->dev) )
+ if (netif_running(netif->dev))
__netif_down(netif);
rtnl_unlock();
netif_put(netif);
return 0; /* Caller should not send response message. */
}
- disconnect->status = NETIF_BE_STATUS_OKAY;
return 1;
}
-
-void netif_interface_init(void)
-{
- memset(netif_hash, 0, sizeof(netif_hash));
-}
return;
}
-#if 0
- /* Supply the information about the device the frontend needs */
- err = xenbus_transaction_start(be->dev->nodename);
- if (err) {
- xenbus_dev_error(be->dev, err, "starting transaction");
- return;
- }
-
- err = xenbus_printf(be->dev->nodename, "sectors", "%lu",
- vbd_size(&be->blkif->vbd));
- if (err) {
- xenbus_dev_error(be->dev, err, "writing %s/sectors",
- be->dev->nodename);
- goto abort;
- }
-
- /* FIXME: use a typename instead */
- err = xenbus_printf(be->dev->nodename, "info", "%u",
- vbd_info(&be->blkif->vbd));
- if (err) {
- xenbus_dev_error(be->dev, err, "writing %s/info",
- be->dev->nodename);
- goto abort;
- }
- err = xenbus_printf(be->dev->nodename, "sector-size", "%lu",
- vbd_secsize(&be->blkif->vbd));
- if (err) {
- xenbus_dev_error(be->dev, err, "writing %s/sector-size",
- be->dev->nodename);
- goto abort;
- }
-#endif
-
/* Map the shared frame, irq etc. */
err = netif_map(be->netif, tx_ring_ref, rx_ring_ref, evtchn);
if (err) {
xenbus_dev_error(be->dev, err,
"mapping shared-frames %lu/%lu port %u",
tx_ring_ref, rx_ring_ref, evtchn);
- goto abort;
+ return;
}
-#if 0
- xenbus_transaction_end(0);
-#endif
xenbus_dev_ok(be->dev);
return;
-
-abort:
- // xenbus_transaction_end(1);
- ;
}
/*