Commit a6d384f8 authored by Vikram Narayanan's avatar Vikram Narayanan
Browse files

Update set_mac_addr functions


Signed-off-by: Vikram Narayanan's avatarVikram Narayanan <vikram186@gmail.com>
parent e61c4d25
......@@ -332,13 +332,16 @@ void __rtnl_link_unregister(struct rtnl_link_ops *ops)
int err;
struct fipc_message *request;
struct fipc_message *response;
struct rtnl_link_ops_container *ops_container;
ret = async_msg_blocking_send_start(net_async, &request);
if (ret) {
LIBLCD_ERR("failed to get a send slot");
lcd_exit(-1);
}
ops_container = container_of(ops, struct rtnl_link_ops_container, rtnl_link_ops);
async_msg_set_fn_type(request, __RTNL_LINK_UNREGISTER);
// fipc_set_reg1(request, ops->kind);
fipc_set_reg1(request, ops_container->other_ref.cptr);
err = thc_ipc_call(net_async, request, &response);
if (err) {
LIBLCD_ERR("thc_ipc_call");
......@@ -401,8 +404,6 @@ void ether_setup(struct net_device *dev)
netdev_container = container_of(dev, struct net_device_container, net_device);
fipc_set_reg1(request, netdev_container->other_ref.cptr);
LIBLCD_MSG("ndev other ref %lu\n", netdev_container->other_ref.cptr);
//fipc_set_reg3(request, rtnl_link_ops_container->my_ref.cptr);
//fipc_set_reg2(request, dev->rtnl_link_ops->kind);
err = thc_ipc_call(net_async, request, &response);
if (err) {
LIBLCD_ERR("thc_ipc_call");
......@@ -414,6 +415,17 @@ fail_async:
return;
}
int sync_prep_data(void *data, unsigned long *sz, unsigned long *off, cptr_t *data_cptr)
{
int ret;
ret = lcd_virt_to_cptr(__gva((unsigned long)data), data_cptr, sz, off);
if (ret) {
LIBLCD_ERR("virt to cptr failed");
}
return ret;
}
// TODO:
int eth_mac_addr(struct net_device *dev, void *p)
{
......@@ -424,6 +436,8 @@ int eth_mac_addr(struct net_device *dev, void *p)
unsigned long p_offset;
cptr_t p_cptr;
int ret;
struct net_device_container *dev_container;
uint32_t request_cookie;
ret = async_msg_blocking_send_start(net_async, &request);
......@@ -432,34 +446,48 @@ int eth_mac_addr(struct net_device *dev, void *p)
goto fail_async;
}
dev_container = container_of(dev, struct net_device_container, net_device);
fipc_set_reg1(request, dev_container->other_ref.cptr);
async_msg_set_fn_type(request, ETH_MAC_ADDR);
//fipc_set_reg1(request, netdev_ops_container->my_ref.cptr);
//fipc_set_reg3(request, rtnl_link_ops_container->my_ref.cptr);
//fipc_set_reg2(request, dev->rtnl_link_ops->kind);
sync_ret = lcd_virt_to_cptr(__gva(( unsigned long )p), &p_cptr, &p_mem_sz, &p_offset);
sync_ret = sync_prep_data(p, &p_mem_sz, &p_offset, &p_cptr);
if (sync_ret) {
LIBLCD_ERR("virt to cptr failed");
lcd_exit(-1);
}
ret = thc_ipc_call(net_async, request, &response);
ret = thc_ipc_send_request(net_async, request, &request_cookie);
if (ret) {
LIBLCD_ERR("thc_ipc_call");
goto fail_ipc;
}
lcd_set_r0(p_mem_sz);
lcd_set_r1(p_offset);
lcd_set_cr0(p_cptr);
sync_ret = lcd_sync_send(sync_ep);
sync_ret = lcd_sync_send(nullnet_sync_endpoint);
lcd_set_cr0(CAP_CPTR_NULL);
if (sync_ret) {
LIBLCD_ERR("failed to send");
goto fail_sync;
}
ret = thc_ipc_recv_response(net_async,
request_cookie,
&response);
if (ret) {
LIBLCD_ERR("async recv failed");
goto fail_ipc_recv;
}
ret = fipc_get_reg1(response);
fipc_recv_msg_end(thc_channel_to_fipc(net_async), response);
fail_async:
fail_sync:
fail_ipc_recv:
fail_ipc:
return ret;
}
......@@ -608,7 +636,7 @@ void rtnl_link_unregister(struct rtnl_link_ops *ops)
goto fail1;
}
async_msg_set_fn_type(request, RTNL_LINK_UNREGISTER);
fipc_set_reg2(request, ops_container->my_ref.cptr);
fipc_set_reg2(request, ops_container->other_ref.cptr);
err = thc_ipc_call(net_async, request, &response);
if (err) {
......@@ -875,8 +903,8 @@ fail_lookup:
// TODO:
int ndo_set_mac_address_callee(struct fipc_message *request, struct thc_channel *channel, struct glue_cspace *cspace, struct cptr sync_ep)
{
// void *addr;
struct fipc_message *response;
struct net_device_container *net_dev_container;
unsigned int request_cookie;
int ret;
int sync_ret;
......@@ -885,27 +913,41 @@ int ndo_set_mac_address_callee(struct fipc_message *request, struct thc_channel
cptr_t addr_cptr;
gva_t addr_gva;
request_cookie = thc_get_request_cookie(request);
ret = glue_cap_lookup_net_device_type(c_cspace, __cptr(fipc_get_reg1(request)), &net_dev_container);
if (ret) {
LIBLCD_ERR("lookup");
goto fail_lookup;
}
fipc_recv_msg_end(thc_channel_to_fipc(channel), request);
sync_ret = lcd_cptr_alloc(&addr_cptr);
if (sync_ret) {
LIBLCD_ERR("failed to get cptr");
lcd_exit(-1);
goto fail_sync;
}
lcd_set_cr0(addr_cptr);
sync_ret = lcd_sync_recv(sync_ep);
lcd_set_cr0(CAP_CPTR_NULL);
if (sync_ret) {
LIBLCD_ERR("failed to recv");
lcd_exit(-1);
goto fail_sync;
}
mem_order = lcd_r0();
addr_offset = lcd_r1();
LIBLCD_MSG("%s: cptr %lu | order %lu | offset %lu",
__func__, addr_cptr.cptr, mem_order, addr_offset);
sync_ret = lcd_map_virt(addr_cptr, mem_order, &addr_gva);
if (sync_ret) {
LIBLCD_ERR("failed to map void *addr");
lcd_exit(-1);
goto fail_sync;
}
//ret = ndo_set_mac_address(dev, addr);
ret = net_dev_container->net_device.netdev_ops->ndo_set_mac_address(&net_dev_container->net_device, (void*)(gva_val(addr_gva) + addr_offset));
if (async_msg_blocking_send_start(channel, &response)) {
LIBLCD_ERR("error getting response msg");
return -EIO;
......@@ -913,7 +955,9 @@ int ndo_set_mac_address_callee(struct fipc_message *request, struct thc_channel
fipc_set_reg1(response, ret);
thc_ipc_reply(channel, request_cookie, response);
return ret;
fail_lookup:
fail_sync:
return 0;
}
// DONE
......
......@@ -341,7 +341,8 @@ fail_async:
}
LCD_TRAMPOLINE_DATA(ndo_uninit_trampoline);
void LCD_TRAMPOLINE_LINKAGE(ndo_uninit_trampoline) ndo_uninit_trampoline(struct net_device *dev)
void LCD_TRAMPOLINE_LINKAGE(ndo_uninit_trampoline)
ndo_uninit_trampoline(struct net_device *dev)
{
void ( *volatile ndo_uninit_fp )(struct net_device *, struct trampoline_hidden_args *);
struct trampoline_hidden_args *hidden_args;
......@@ -398,11 +399,22 @@ int ndo_start_xmit(struct sk_buff *skb, struct net_device *dev, struct trampolin
struct net_device_container *net_dev_container;
if (!get_current()->ptstate) {
LIBLCD_MSG("%s:Called from userland - can't process", __func__);
LIBLCD_MSG("%s:Called from userspace", __func__);
// dump_stack();
/* LCD_MAIN( {
ret = ndo_start_xmit_user(skb, dev, hidden_args);
});*/
// return for now
LIBLCD_MSG("\nskb %p | skb->len %d | skb->datalen %d\n"
"skb->end %p | skb->head %p | skb->data %p\n"
"truesize %d",
skb, skb->len, skb->data_len,
skb_end_pointer(skb), skb->head, skb->data,
skb->truesize);
LIBLCD_MSG("\ncur->tskfrag 0x%X | frag off %d | frag sz %d\n"
"nr_frags %d\n",
current->task_frag.page, current->task_frag.offset, current->task_frag.size,
skb_shinfo(skb)->nr_frags);
return 0;
}
......@@ -620,6 +632,43 @@ void LCD_TRAMPOLINE_LINKAGE(ndo_set_rx_mode_trampoline) ndo_set_rx_mode_trampoli
}
int sync_setup_memory(void *data, size_t sz, unsigned long *order, cptr_t *data_cptr, unsigned long *data_offset)
{
int ret;
struct page *p;
unsigned long data_len;
unsigned long mem_len;
/*
* Determine page that contains (start of) data
*/
p = virt_to_head_page(data);
if (!p) {
LIBLCD_ERR("failed to translate to page");
ret = -EINVAL;
goto fail1;
}
data_len = sz;
mem_len = ALIGN(data + data_len - page_address(p), PAGE_SIZE);
*order = ilog2(roundup_pow_of_two(mem_len >> PAGE_SHIFT));
/*
* Volunteer memory
*/
*data_offset = data - page_address(p);
ret = lcd_volunteer_pages(p, *order, data_cptr);
if (ret) {
LIBLCD_ERR("failed to volunteer memory");
goto fail2;
}
/*
* Done
*/
return 0;
fail2:
fail1:
return ret;
}
extern struct cspace *klcd_cspace;
int ndo_set_mac_address_user(struct net_device *dev, void *addr, struct trampoline_hidden_args *hidden_args)
{
int ret;
......@@ -629,9 +678,17 @@ int ndo_set_mac_address_user(struct net_device *dev, void *addr, struct trampoli
unsigned long addr_mem_sz;
unsigned long addr_offset;
cptr_t addr_cptr;
unsigned int request_cookie;
struct net_device_container *net_dev_container;
cptr_t sync_end;
struct cspace *curr_cspace;
net_dev_container = container_of(dev, struct net_device_container, net_device);
thc_init();
/* creates lcd and cspace */
lcd_enter();
curr_cspace = get_current_cspace(current);
lcd_cptr_alloc(&sync_end);
ret = cap_grant(klcd_cspace, hidden_args->sync_ep, curr_cspace, sync_end);
ret = async_msg_blocking_send_start(hidden_args->async_chnl, &request);
if (ret) {
......@@ -641,33 +698,54 @@ int ndo_set_mac_address_user(struct net_device *dev, void *addr, struct trampoli
async_msg_set_fn_type(request, NDO_SET_MAC_ADDRESS);
fipc_set_reg1(request, net_dev_container->other_ref.cptr);
sync_ret = lcd_virt_to_cptr(__gva(( unsigned long )addr), &addr_cptr, &addr_mem_sz, &addr_offset);
if (sync_ret) {
ret = sync_setup_memory(addr, sizeof(struct sockaddr), &addr_mem_sz, &addr_cptr, &addr_offset);
if (ret) {
LIBLCD_ERR("virt to cptr failed");
goto fail_virt;
}
DO_FINISH_(ndo_set_mac_address, {
ASYNC_({
ret = thc_ipc_call(hidden_args->async_chnl, request, &response);
}, ndo_set_mac_address);
});
ret = thc_ipc_send_request(hidden_args->async_chnl, request, &request_cookie);
if (ret) {
LIBLCD_ERR("thc_ipc_call");
goto fail_ipc;
}
lcd_set_cr0(addr_cptr);
lcd_set_r0(addr_mem_sz);
lcd_set_r1(addr_offset);
lcd_set_cr0(addr_cptr);
sync_ret = lcd_sync_send(hidden_args->sync_ep);
LIBLCD_MSG("%s: cptr %lu | order %lu | offset %lu",
__func__, addr_cptr.cptr, addr_mem_sz, addr_offset);
sync_ret = lcd_sync_send(sync_end);
lcd_set_cr0(CAP_CPTR_NULL);
if (sync_ret) {
LIBLCD_ERR("failed to send");
goto fail_sync;
}
lcd_cap_delete(sync_end);
DO_FINISH_(ndo_set_mac_address, {
ASYNC_({
ret = thc_ipc_recv_response(hidden_args->async_chnl,
request_cookie,
&response);
}, ndo_set_mac_address);
});
if (ret) {
LIBLCD_ERR("async recv failed");
goto fail_ipcresp;
}
ret = fipc_get_reg1(response);
LIBLCD_MSG("%s: returned %d", __func__, ret);
fipc_recv_msg_end(thc_channel_to_fipc(hidden_args->async_chnl), response);
fail_ipcresp:
fail_virt:
fail_sync:
fail_ipc:
......@@ -689,12 +767,15 @@ int ndo_set_mac_address(struct net_device *dev, void *addr, struct trampoline_hi
if (!get_current()->ptstate) {
LIBLCD_MSG("%s:Called from userland - can't process", __func__);
if (0) {
for (ret = 0; ret < 14; ret++) {
printk("%02X:",((char*)addr)[ret]);
}
if (1) {
LCD_MAIN({
ret = ndo_set_mac_address_user(dev, addr, hidden_args);
});
}
return eth_mac_addr(dev, addr);
return ret;//eth_mac_addr(dev, addr);
}
net_dev_container = container_of(dev, struct net_device_container, net_device);
......@@ -1305,7 +1386,6 @@ int register_netdevice_callee(struct fipc_message *request, struct thc_channel *
dev_container->net_device.dev_addr = kmalloc(MAX_ADDR_LEN, GFP_KERNEL);
rtnl_lock();
LIBLCD_MSG("Got lock ");
ret = register_netdevice(( &dev_container->net_device ));
rtnl_unlock();
LIBLCD_MSG("unlocked ");
......@@ -1348,69 +1428,83 @@ fail_lookup:
return ret;
}
int eth_mac_addr_callee(struct fipc_message *request, struct thc_channel *channel, struct glue_cspace *cspace, struct cptr sync_ep)
int sync_recv_data(unsigned long *order, unsigned long *off, cptr_t *data_cptr, gva_t *data_gva, cptr_t sync_ep)
{
//struct net_device *dev;
int ret;
//void *p;
struct fipc_message *response;
unsigned int request_cookie;
/*dev = kzalloc(*sizeof( dev ), GFP_KERNEL);
if (!dev) {
LIBLCD_ERR("kzalloc");
lcd_exit(-1);
int ret;
ret = lcd_cptr_alloc(data_cptr);
if (ret) {
LIBLCD_ERR("failed to get cptr");
goto fail1;
}
dev->netdev_ops = kzalloc(*sizeof( dev->netdev_ops ), GFP_KERNEL);
if (!dev->netdev_ops) {
LIBLCD_ERR("kzalloc");
lcd_exit(-1);
lcd_set_cr0(*data_cptr);
ret = lcd_sync_recv(sync_ep);
lcd_set_cr0(CAP_CPTR_NULL);
if (ret) {
LIBLCD_ERR("failed to recv");
goto fail2;
}
dev->rtnl_link_ops = kzalloc(*sizeof( dev->rtnl_link_ops ), GFP_KERNEL);
if (!dev->rtnl_link_ops) {
LIBLCD_ERR("kzalloc");
lcd_exit(-1);
*order = lcd_r0();
*off = lcd_r1();
ret = lcd_map_virt(*data_cptr, *order, data_gva);
if (ret) {
LIBLCD_ERR("failed to map void *addr");
goto fail3;
}
dev->rtnl_link_ops->kind = kzalloc(sizeof( char ), GFP_KERNEL);
if (!dev->rtnl_link_ops->kind) {
LIBLCD_ERR("kzalloc");
lcd_exit(-1);
}*/
return 0;
fail3:
lcd_cap_delete(*data_cptr);
fail2:
lcd_cptr_free(*data_cptr);
fail1:
return ret;
}
int eth_mac_addr_callee(struct fipc_message *request, struct thc_channel *channel, struct glue_cspace *cspace, struct cptr sync_ep)
{
struct net_device_container *dev_container;
int ret;
struct fipc_message *response;
int sync_ret;
unsigned long mem_order;
unsigned long p_offset;
cptr_t p_cptr;
gva_t p_gva;
unsigned int request_cookie;
request_cookie = thc_get_request_cookie(request);
fipc_recv_msg_end(thc_channel_to_fipc(net_async), request);
//dev->rtnl_link_ops->kind = fipc_get_reg2(request);
sync_ret = lcd_cptr_alloc(&p_cptr);
if (sync_ret) {
LIBLCD_ERR("failed to get cptr");
lcd_exit(-1);
}
lcd_set_cr0(p_cptr);
sync_ret = lcd_sync_recv(sync_ep);
lcd_set_cr0(CAP_CPTR_NULL);
if (sync_ret) {
LIBLCD_ERR("failed to recv");
lcd_exit(-1);
fipc_recv_msg_end(thc_channel_to_fipc(channel), request);
ret = glue_cap_lookup_net_device_type(c_cspace, __cptr(fipc_get_reg1(request)), &dev_container);
if (ret) {
LIBLCD_MSG("lookup failed");
goto fail_lookup;
}
mem_order = lcd_r0();
p_offset = lcd_r1();
sync_ret = lcd_map_virt(p_cptr, mem_order, &p_gva);
sync_ret = sync_recv_data(&mem_order, &p_offset, &p_cptr, &p_gva, sync_ep);
if (sync_ret) {
LIBLCD_ERR("failed to map void *p");
LIBLCD_ERR("failed to recv data");
lcd_exit(-1);
}
//ret = eth_mac_addr(dev, p);
if (async_msg_blocking_send_start(net_async, &response)) {
ret = eth_mac_addr(&dev_container->net_device, (void*)(gva_val(p_gva) + p_offset));
LIBLCD_MSG("eth_mac_addr returned %d", ret);
if (async_msg_blocking_send_start(channel, &response)) {
LIBLCD_ERR("error getting response msg");
return -EIO;
}
fipc_set_reg1(response, ret);
thc_ipc_reply(net_async, request_cookie, response);
thc_ipc_reply(channel, request_cookie, response);
fail_lookup:
return ret;
}
int eth_validate_addr_callee(struct fipc_message *request, struct thc_channel *channel, struct glue_cspace *cspace, struct cptr sync_ep)
......@@ -1530,6 +1624,8 @@ fail_lookup:
return ret;
}
extern struct rtnl_link_ops_container *main_ops_container;
int __rtnl_link_register_callee(void)
{
struct rtnl_link_ops_container *ops_container;
......@@ -1545,6 +1641,7 @@ int __rtnl_link_register_callee(void)
LIBLCD_ERR("kzalloc");
goto fail7;
}
main_ops_container = ops_container;
err = glue_cap_insert_rtnl_link_ops_type(c_cspace, ops_container, &ops_container->my_ref);
if (err) {
LIBLCD_ERR("lcd insert");
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment