Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/srv/net/nil/eth/eth.c

    r6d8455d r9cd8165  
    4848#include <ipc/net.h>
    4949#include <ipc/services.h>
     50#include <loc.h>
    5051#include <net/modules.h>
    5152#include <net_checksum.h>
     
    169170INT_MAP_IMPLEMENT(eth_protos, eth_proto_t);
    170171
    171 int nil_device_state_msg_local(nic_device_id_t device_id, sysarg_t state)
     172static void eth_nic_cb_connection(ipc_callid_t iid, ipc_call_t *icall,
     173    void *arg);
     174
     175static int eth_device_state(eth_device_t *device, sysarg_t state)
    172176{
    173177        int index;
     
    179183                proto = eth_protos_get_index(&eth_globals.protos, index);
    180184                if ((proto) && (proto->sess)) {
    181                         il_device_state_msg(proto->sess, device_id, state,
    182                             proto->service);
     185                        il_device_state_msg(proto->sess, device->device_id,
     186                            state, proto->service);
    183187                }
    184188        }
     
    226230 *
    227231 * @param[in] device_id New device identifier.
    228  * @param[in] handle    Device driver handle.
     232 * @param[in] sid       NIC service ID.
    229233 * @param[in] mtu       Device maximum transmission unit.
    230234 *
     
    234238 *
    235239 */
    236 static int eth_device_message(nic_device_id_t device_id, devman_handle_t handle,
     240static int eth_device_message(nic_device_id_t device_id, service_id_t sid,
    237241    size_t mtu)
    238242{
     
    259263        device = eth_devices_find(&eth_globals.devices, device_id);
    260264        if (device) {
    261                 if (device->handle != handle) {
     265                if (device->sid != sid) {
    262266                        printf("Device %d already exists\n", device->device_id);
    263267                        fibril_rwlock_write_unlock(&eth_globals.devices_lock);
     
    298302
    299303        device->device_id = device_id;
    300         device->handle = handle;
     304        device->sid = sid;
    301305        device->flags = 0;
    302306        if ((mtu > 0) && (mtu <= ETH_MAX_TAGGED_CONTENT(device->flags)))
     
    335339       
    336340        /* Bind the device driver */
    337         device->sess = devman_device_connect(EXCHANGE_SERIALIZE, handle,
     341        device->sess = loc_service_connect(EXCHANGE_SERIALIZE, sid,
    338342            IPC_FLAG_BLOCKING);
    339343        if (device->sess == NULL) {
     
    343347        }
    344348       
    345         nic_connect_to_nil(device->sess, SERVICE_ETHERNET, device_id);
     349        rc = nic_callback_create(device->sess, eth_nic_cb_connection, device);
     350        if (rc != EOK) {
     351                fibril_rwlock_write_unlock(&eth_globals.devices_lock);
     352                async_hangup(device->sess);
     353                free(device);
     354                return EIO;
     355        }
    346356       
    347357        /* Get hardware address */
     
    362372        }
    363373       
    364         printf("%s: Device registered (id: %d, handle: %zu: mtu: %zu, "
     374        printf("%s: Device registered (id: %d, sid: %zu: mtu: %zu, "
    365375            "mac: " PRIMAC ", flags: 0x%x)\n", NAME,
    366             device->device_id, device->handle, device->mtu,
     376            device->device_id, device->sid, device->mtu,
    367377            ARGSMAC(device->addr.address), device->flags);
    368378
     
    814824}
    815825
    816 static int eth_addr_changed(nic_device_id_t device_id)
     826static int eth_received(eth_device_t *device)
     827{
     828        void *data;
     829        size_t size;
     830        int rc;
     831       
     832        rc = async_data_write_accept(&data, false, 0, 0, 0, &size);
     833        if (rc != EOK) {
     834                printf("%s: data_write_accept() failed\n", NAME);
     835                return rc;
     836        }
     837       
     838        packet_t *packet = packet_get_1_remote(eth_globals.net_sess, size);
     839        if (packet == NULL)
     840                return ENOMEM;
     841       
     842        void *pdata = packet_suffix(packet, size);
     843        memcpy(pdata, data, size);
     844        free(data);
     845       
     846        return nil_received_msg_local(device->device_id, packet);
     847}
     848
     849static int eth_addr_changed(eth_device_t *device)
    817850{
    818851        nic_address_t address;
     
    832865
    833866        fibril_rwlock_write_lock(&eth_globals.devices_lock);
    834         /* An existing device? */
    835         eth_device_t *device = eth_devices_find(&eth_globals.devices, device_id);
    836         if (device) {
    837                 printf("Device %d changing address from " PRIMAC " to " PRIMAC "\n",
    838                         device_id, ARGSMAC(device->addr.address), ARGSMAC(address.address));
    839                 memcpy(&device->addr, &address, sizeof (nic_address_t));
    840                 fibril_rwlock_write_unlock(&eth_globals.devices_lock);
    841 
    842                 /* Notify all upper layer modules */
    843                 fibril_rwlock_read_lock(&eth_globals.protos_lock);
    844                 int index;
    845                 for (index = 0; index < eth_protos_count(&eth_globals.protos); index++) {
    846                         eth_proto_t *proto = eth_protos_get_index(&eth_globals.protos, index);
    847                         if (proto->sess != NULL) {
    848                                 il_addr_changed_msg(proto->sess, device->device_id,
    849                                                 ETH_ADDR, address.address);
    850                         }
    851                 }
    852 
    853                 fibril_rwlock_read_unlock(&eth_globals.protos_lock);
    854                 return EOK;
    855         } else {
    856                 return ENOENT;
    857         }
     867
     868        printf("Device %d changing address from " PRIMAC " to " PRIMAC "\n",
     869                device->device_id, ARGSMAC(device->addr.address),
     870                ARGSMAC(address.address));
     871        memcpy(&device->addr, &address, sizeof (nic_address_t));
     872        fibril_rwlock_write_unlock(&eth_globals.devices_lock);
     873
     874        /* Notify all upper layer modules */
     875        fibril_rwlock_read_lock(&eth_globals.protos_lock);
     876        int index;
     877        for (index = 0; index < eth_protos_count(&eth_globals.protos); index++) {
     878                eth_proto_t *proto = eth_protos_get_index(&eth_globals.protos, index);
     879                if (proto->sess != NULL) {
     880                        il_addr_changed_msg(proto->sess, device->device_id,
     881                                        ETH_ADDR, address.address);
     882                }
     883        }
     884
     885        fibril_rwlock_read_unlock(&eth_globals.protos_lock);
     886        return EOK;
    858887}
    859888
     
    921950               
    922951                return EOK;
    923         case NET_NIL_DEVICE_STATE:
    924                 nil_device_state_msg_local(IPC_GET_DEVICE(*call), IPC_GET_STATE(*call));
    925                 async_answer_0(callid, EOK);
    926                 return EOK;
    927         case NET_NIL_RECEIVED:
    928                 rc = packet_translate_remote(eth_globals.net_sess, &packet,
    929                     IPC_GET_ARG2(*call));
    930                 if (rc == EOK)
    931                         rc = nil_received_msg_local(IPC_GET_ARG1(*call), packet);
    932                
    933                 async_answer_0(callid, (sysarg_t) rc);
    934                 return rc;
    935         case NET_NIL_ADDR_CHANGED:
    936                 rc = eth_addr_changed(IPC_GET_DEVICE(*call));
    937                 async_answer_0(callid, (sysarg_t) rc);
    938                 return rc;
    939952        }
    940953       
    941954        return ENOTSUP;
     955}
     956
     957static void eth_nic_cb_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg)
     958{
     959        eth_device_t *device = (eth_device_t *)arg;
     960        int rc;
     961       
     962        async_answer_0(iid, EOK);
     963       
     964        while (true) {
     965                ipc_call_t call;
     966                ipc_callid_t callid = async_get_call(&call);
     967               
     968                if (!IPC_GET_IMETHOD(call))
     969                        break;
     970               
     971                switch (IPC_GET_IMETHOD(call)) {
     972                case NIC_EV_DEVICE_STATE:
     973                        rc = eth_device_state(device, IPC_GET_ARG1(call));
     974                        async_answer_0(callid, (sysarg_t) rc);
     975                        break;
     976                case NIC_EV_RECEIVED:
     977                        rc = eth_received(device);
     978                        async_answer_0(callid, (sysarg_t) rc);
     979                        break;
     980                case NIC_EV_ADDR_CHANGED:
     981                        rc = eth_addr_changed(device);
     982                        async_answer_0(callid, (sysarg_t) rc);
     983                        break;
     984                default:
     985                        async_answer_0(callid, ENOTSUP);
     986                }
     987        }
    942988}
    943989
Note: See TracChangeset for help on using the changeset viewer.