Changeset c62a8275 in mainline


Ignore:
Timestamp:
2014-09-01T11:17:23Z (10 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
a4666a9
Parents:
f93ba6d (diff), 320bd52 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge from lp:~nufcia/helenos/rtl8169.

Location:
uspace
Files:
12 edited

Legend:

Unmodified
Added
Removed
  • uspace/app/nic/nic.c

    rf93ba6d rc62a8275  
    4949        nic_cable_state_t link_state;
    5050        nic_channel_mode_t duplex;
     51        nic_unicast_mode_t unicast_mode;
     52        nic_multicast_mode_t multicast_mode;
     53        nic_broadcast_mode_t broadcast_mode;
    5154        int speed;
    5255} nic_info_t;
     
    6265        printf("\tduplex <half|full|simplex> - set duplex mode\n");
    6366        printf("\tauto - enable autonegotiation\n");
     67        printf("\tunicast <block|default|list|promisc> - set unicast receive filtering\n");
     68        printf("\tmulticast <block|list|promisc> - set multicast receive filtering\n");
     69        printf("\tbroadcast <block|allow> - block or allow incoming broadcast frames\n");
    6470}
    6571
     
    145151        }
    146152
     153        rc = nic_unicast_get_mode(sess, &info->unicast_mode, 0, NULL, NULL);
     154        if (rc != EOK) {
     155                printf("Error gettinc NIC unicast receive mode.\n");
     156                rc = EIO;
     157                goto error;
     158        }
     159
     160        rc = nic_multicast_get_mode(sess, &info->multicast_mode, 0, NULL, NULL);
     161        if (rc != EOK) {
     162                printf("Error gettinc NIC multicast receive mode.\n");
     163                rc = EIO;
     164                goto error;
     165        }
     166
     167        rc = nic_broadcast_get_mode(sess, &info->broadcast_mode);
     168        if (rc != EOK) {
     169                printf("Error gettinc NIC broadcast receive mode.\n");
     170                rc = EIO;
     171                goto error;
     172        }
    147173
    148174        return EOK;
     
    167193        case NIC_CM_HALF_DUPLEX: return "half-duplex";
    168194        case NIC_CM_SIMPLEX: return "simplex";
     195        default: assert(false); return NULL;
     196        }
     197}
     198
     199static const char *nic_unicast_mode_str(nic_unicast_mode_t mode)
     200{
     201        switch (mode) {
     202        case NIC_UNICAST_UNKNOWN: return "unknown";
     203        case NIC_UNICAST_BLOCKED: return "blocked";
     204        case NIC_UNICAST_DEFAULT: return "default";
     205        case NIC_UNICAST_LIST: return "list";
     206        case NIC_UNICAST_PROMISC: return "promisc";
     207        default: assert(false); return NULL;
     208        }
     209}
     210
     211static const char *nic_multicast_mode_str(nic_unicast_mode_t mode)
     212{
     213        switch (mode) {
     214        case NIC_MULTICAST_UNKNOWN: return "unknown";
     215        case NIC_MULTICAST_BLOCKED: return "blocked";
     216        case NIC_MULTICAST_LIST: return "list";
     217        case NIC_MULTICAST_PROMISC: return "promisc";
     218        default: assert(false); return NULL;
     219        }
     220}
     221
     222static const char *nic_broadcast_mode_str(nic_unicast_mode_t mode)
     223{
     224        switch (mode) {
     225        case NIC_BROADCAST_UNKNOWN: return "unknown";
     226        case NIC_BROADCAST_BLOCKED: return "blocked";
     227        case NIC_BROADCAST_ACCEPTED: return "accepted";
    169228        default: assert(false); return NULL;
    170229        }
     
    234293                printf("\tLink state: %s\n",
    235294                    nic_link_state_str(nic_info.link_state));
     295                printf("\tUnicast receive mode: %s\n",
     296                    nic_unicast_mode_str(nic_info.unicast_mode));
     297                printf("\tMulticast receive mode: %s\n",
     298                    nic_multicast_mode_str(nic_info.multicast_mode));
     299                printf("\tBroadcast receive mode: %s\n",
     300                    nic_broadcast_mode_str(nic_info.broadcast_mode));
    236301
    237302                if (nic_info.link_state == NIC_CS_PLUGGED) {
     
    369434
    370435        return nic_set_address(sess, &addr);
     436}
     437
     438static int nic_set_rx_unicast(int i, char *str)
     439{
     440        async_sess_t *sess;
     441
     442        sess = get_nic_by_index(i);
     443        if (sess == NULL) {
     444                printf("Specified NIC doesn't exist or cannot connect to it.\n");
     445                return EINVAL;
     446        }
     447
     448        if (!str_cmp(str, "block")) {
     449                nic_unicast_set_mode(sess, NIC_UNICAST_BLOCKED, NULL, 0);
     450                return EOK;
     451        }
     452
     453        if (!str_cmp(str, "default")) {
     454                nic_unicast_set_mode(sess, NIC_UNICAST_DEFAULT, NULL, 0);
     455                return EOK;
     456        }
     457
     458        if (!str_cmp(str, "list")) {
     459                nic_unicast_set_mode(sess, NIC_UNICAST_LIST, NULL, 0);
     460                return EOK;
     461        }
     462
     463        if (!str_cmp(str, "promisc")) {
     464                nic_unicast_set_mode(sess, NIC_UNICAST_PROMISC, NULL, 0);
     465                return EOK;
     466        }
     467
     468
     469        printf("Invalid pameter - should be one of: block, default, promisc\n");
     470        return EINVAL;
     471}
     472
     473static int nic_set_rx_multicast(int i, char *str)
     474{
     475        async_sess_t *sess;
     476
     477        sess = get_nic_by_index(i);
     478        if (sess == NULL) {
     479                printf("Specified NIC doesn't exist or cannot connect to it.\n");
     480                return EINVAL;
     481        }
     482
     483        if (!str_cmp(str, "block")) {
     484                nic_multicast_set_mode(sess, NIC_MULTICAST_BLOCKED, NULL, 0);
     485                return EOK;
     486        }
     487
     488        if (!str_cmp(str, "list")) {
     489                nic_multicast_set_mode(sess, NIC_MULTICAST_LIST, NULL, 0);
     490                return EOK;
     491        }
     492
     493        if (!str_cmp(str, "promisc")) {
     494                nic_multicast_set_mode(sess, NIC_MULTICAST_PROMISC, NULL, 0);
     495                return EOK;
     496        }
     497
     498        printf("Invalid pameter - should be one of: block, promisc\n");
     499        return EINVAL;
     500}
     501
     502static int nic_set_rx_broadcast(int i, char *str)
     503{
     504        async_sess_t *sess;
     505
     506        sess = get_nic_by_index(i);
     507        if (sess == NULL) {
     508                printf("Specified NIC doesn't exist or cannot connect to it.\n");
     509                return EINVAL;
     510        }
     511
     512        if (!str_cmp(str, "block")) {
     513                nic_broadcast_set_mode(sess, NIC_BROADCAST_BLOCKED);
     514                return EOK;
     515        }
     516
     517        if (!str_cmp(str, "accept")) {
     518                nic_broadcast_set_mode(sess, NIC_BROADCAST_ACCEPTED);
     519                return EOK;
     520        }
     521
     522        printf("Invalid pameter - should be 'block' or 'accept'\n");
     523        return EINVAL;
    371524}
    372525
     
    400553                        return nic_set_autoneg(index);
    401554
     555                if (!str_cmp(argv[2], "unicast"))
     556                        return nic_set_rx_unicast(index, argv[3]);
     557
     558                if (!str_cmp(argv[2], "multicast"))
     559                        return nic_set_rx_multicast(index, argv[3]);
     560
     561                if (!str_cmp(argv[2], "broadcast"))
     562                        return nic_set_rx_broadcast(index, argv[3]);
     563
    402564        } else {
    403565                printf(NAME ": Invalid argument.\n");
  • uspace/drv/nic/rtl8169/driver.c

    rf93ba6d rc62a8275  
    2727 */
    2828
    29 #define _DDF_DATA_IMPLANT
    30 
    3129#include <assert.h>
    3230#include <errno.h>
     
    330328}
    331329
     330static void rtl8169_dev_cleanup(ddf_dev_t *dev)
     331{
     332        assert(dev);
     333
     334        if (ddf_dev_data_get(dev))
     335                nic_unbind_and_destroy(dev);
     336}
     337
    332338static int rtl8169_dev_initialize(ddf_dev_t *dev)
    333339{
     
    351357failed:
    352358        ddf_msg(LVL_ERROR, "The device initialization failed");
    353 //      rtl8139_dev_cleanup(dev);
     359        rtl8169_dev_cleanup(dev);
    354360        return ret;
    355361
     
    439445        nic_set_ddf_fun(nic_data, fun);
    440446        ddf_fun_set_ops(fun, &rtl8169_dev_ops);
    441 //      ddf_fun_data_implant(fun, nic_data);
    442447
    443448        rc = ddf_fun_bind(fun);
     
    467472err_pio:
    468473err_destroy:
    469         //rtl8169_dev_cleanup(dev);
     474        rtl8169_dev_cleanup(dev);
    470475        return rc;
    471476
     
    733738        /* Configure Receive Control Register */
    734739        uint32_t rcr = pio_read_32(rtl8169->regs + RCR);
    735         rcr |= RCR_ACCEPT_ALL_PHYS | RCR_ACCEPT_PHYS_MATCH \
    736             | RCR_ACCEPT_BROADCAST | RCR_ACCEPT_ERROR \
    737             | RCR_ACCEPT_RUNT;
     740        rtl8169->rcr_ucast = RCR_ACCEPT_PHYS_MATCH;
     741        rcr |= RCR_ACCEPT_PHYS_MATCH | RCR_ACCEPT_ERROR | RCR_ACCEPT_RUNT;
    738742        pio_write_32(rtl8169->regs + RCR, rcr);
    739743        pio_write_16(rtl8169->regs + RMS, BUFFER_SIZE);
    740 
    741         ddf_msg(LVL_NOTE, "RCR: 0x%08x", pio_read_32(rtl8169->regs + RCR));
    742 
    743744
    744745        pio_write_16(rtl8169->regs + IMR, 0xffff);
     
    793794}
    794795
     796/** Notify NIC framework about HW filtering state when promisc mode was disabled
     797 *
     798 *  @param nic_data     The NIC data
     799 *  @param mcast_mode   Current multicast mode
     800 *  @param was_promisc  Sign if the promiscuous mode was active before disabling
     801 */
     802inline static void rtl8169_rcx_promics_rem(nic_t *nic_data,
     803    nic_multicast_mode_t mcast_mode, uint8_t was_promisc)
     804{
     805        assert(nic_data);
     806
     807        if (was_promisc != 0) {
     808                if (mcast_mode == NIC_MULTICAST_LIST)
     809                        nic_report_hw_filtering(nic_data, 1, 0, -1);
     810                else
     811                        nic_report_hw_filtering(nic_data, 1, 1, -1);
     812        } else {
     813                nic_report_hw_filtering(nic_data, 1, -1, -1);
     814        }
     815}
     816
    795817static int rtl8169_unicast_set(nic_t *nic_data, nic_unicast_mode_t mode,
    796818    const nic_address_t *addr, size_t addr_count)
    797819{
     820        rtl8169_t *rtl8169 = nic_get_specific(nic_data);
     821        uint32_t rcr = pio_read_32(rtl8169->regs + RCR);
     822        uint8_t was_promisc = rcr & RCR_ACCEPT_ALL_PHYS;
     823        nic_multicast_mode_t mcast_mode;
     824
     825        nic_query_multicast(nic_data, &mcast_mode, 0, NULL, NULL);
     826
     827        ddf_msg(LVL_DEBUG, "Unicast RX filter mode: %d", mode);
     828
     829
     830        switch (mode) {
     831        case NIC_UNICAST_BLOCKED:
     832                rtl8169->rcr_ucast = 0;
     833                rtl8169_rcx_promics_rem(nic_data, mcast_mode, was_promisc);
     834                break;
     835        case NIC_UNICAST_DEFAULT:
     836                rtl8169->rcr_ucast = RCR_ACCEPT_PHYS_MATCH;
     837                rtl8169_rcx_promics_rem(nic_data, mcast_mode, was_promisc);
     838                break;
     839        case NIC_UNICAST_LIST:
     840                rtl8169->rcr_ucast = RCR_ACCEPT_PHYS_MATCH | RCR_ACCEPT_ALL_PHYS;
     841
     842                if (mcast_mode == NIC_MULTICAST_PROMISC)
     843                        nic_report_hw_filtering(nic_data, 0, 1, -1);
     844                else
     845                        nic_report_hw_filtering(nic_data, 0, 0, -1);
     846                break;
     847        case NIC_UNICAST_PROMISC:
     848                rtl8169->rcr_ucast = RCR_ACCEPT_PHYS_MATCH | RCR_ACCEPT_ALL_PHYS;
     849
     850                if (mcast_mode == NIC_MULTICAST_PROMISC)
     851                        nic_report_hw_filtering(nic_data, 1, 1, -1);
     852                else
     853                        nic_report_hw_filtering(nic_data, 1, 0, -1);
     854                break;
     855        default:
     856                return ENOTSUP;
     857        }
     858
     859        fibril_mutex_lock(&rtl8169->rx_lock);
     860
     861        rcr &= ~(RCR_ACCEPT_PHYS_MATCH | RCR_ACCEPT_ALL_PHYS);
     862        pio_write_32(rtl8169->regs + RCR, rcr | rtl8169->rcr_ucast | rtl8169->rcr_mcast);
     863        ddf_msg(LVL_DEBUG, "new RCR value: 0x%08x", rcr | rtl8169->rcr_ucast | rtl8169->rcr_mcast);
     864
     865        fibril_mutex_unlock(&rtl8169->rx_lock);
    798866        return EOK;
    799867}
     
    802870    const nic_address_t *addr, size_t addr_count)
    803871{
     872        rtl8169_t *rtl8169 = nic_get_specific(nic_data);
     873        uint32_t rcr = pio_read_32(rtl8169->regs + RCR);
     874        uint64_t mask;
     875
     876        ddf_msg(LVL_DEBUG, "Multicast RX filter mode: %d", mode);
     877
     878        switch (mode) {
     879        case NIC_MULTICAST_BLOCKED:
     880                rtl8169->rcr_mcast = 0;
     881                if ((rtl8169->rcr_ucast & RCR_ACCEPT_ALL_PHYS) != 0)
     882                        nic_report_hw_filtering(nic_data, -1, 0, -1);
     883                else
     884                        nic_report_hw_filtering(nic_data, -1, 1, -1);
     885                break;
     886        case NIC_MULTICAST_LIST:
     887                mask = nic_mcast_hash(addr, addr_count);
     888                pio_write_32(rtl8169->regs + MAR0, (uint32_t)mask);
     889                pio_write_32(rtl8169->regs + MAR0 + 4, (uint32_t)(mask >> 32));
     890                rtl8169->rcr_mcast = RCR_ACCEPT_MULTICAST;
     891                nic_report_hw_filtering(nic_data, -1, 0, -1);
     892                break;
     893        case NIC_MULTICAST_PROMISC:
     894                pio_write_32(rtl8169->regs + MAR0, 0xffffffffULL);
     895                pio_write_32(rtl8169->regs + MAR0 + 4, (uint32_t)(0xffffffffULL >> 32));
     896                rtl8169->rcr_mcast = RCR_ACCEPT_MULTICAST;
     897                nic_report_hw_filtering(nic_data, -1, 1, -1);
     898                break;
     899        default:
     900                return ENOTSUP;
     901        }
     902
     903        fibril_mutex_lock(&rtl8169->rx_lock);
     904
     905        rcr &= ~(RCR_ACCEPT_PHYS_MATCH | RCR_ACCEPT_ALL_PHYS);
     906        pio_write_32(rtl8169->regs + RCR, rcr | rtl8169->rcr_ucast | rtl8169->rcr_mcast);
     907        ddf_msg(LVL_DEBUG, "new RCR value: 0x%08x", rcr | rtl8169->rcr_ucast | rtl8169->rcr_mcast);
     908
     909        fibril_mutex_unlock(&rtl8169->rx_lock);
    804910        return EOK;
    805911}
     
    807913static int rtl8169_broadcast_set(nic_t *nic_data, nic_broadcast_mode_t mode)
    808914{
     915        rtl8169_t *rtl8169 = nic_get_specific(nic_data);
     916       
     917        /* Configure Receive Control Register */
     918        uint32_t rcr = pio_read_32(rtl8169->regs + RCR);
     919
     920        ddf_msg(LVL_DEBUG, "Broadcast RX filter mode: %d", mode);
     921
     922        switch (mode) {
     923        case NIC_BROADCAST_BLOCKED:
     924                rcr &= RCR_ACCEPT_BROADCAST;
     925                break;
     926        case NIC_BROADCAST_ACCEPTED:
     927                rcr |= RCR_ACCEPT_BROADCAST;
     928                break;
     929        default:
     930                return ENOTSUP;
     931        }
     932
     933        pio_write_32(rtl8169->regs + RCR, rcr);
     934        ddf_msg(LVL_DEBUG," new RCR value: 0x%08x", rcr);
     935
    809936        return EOK;
    810937}
     
    816943        rtl8169_t *rtl8169 = nic_get_specific(nic_data);
    817944        rtl8169_descr_t *descr;
    818 
    819         ddf_msg(LVL_NOTE, "rtl8169_transmit_done()");
     945        int sent = 0;
     946
     947        ddf_msg(LVL_DEBUG, "rtl8169_transmit_done()");
    820948
    821949        fibril_mutex_lock(&rtl8169->tx_lock);
     
    828956                descr->control &= (~CONTROL_OWN);
    829957                write_barrier();
    830                 ddf_msg(LVL_NOTE, "TX status for descr %d: 0x%08x", tail, descr->control);
     958                ddf_msg(LVL_DEBUG, "TX status for descr %d: 0x%08x", tail, descr->control);
    831959       
    832960                tail = (tail + 1) % TX_BUFFERS_COUNT;
    833         }
     961                sent++;
     962        }
     963
     964        if (sent != 0)
     965                nic_set_tx_busy(nic_data, 0);
    834966
    835967        rtl8169->tx_tail = tail;
     
    849981        int frame_size;
    850982
    851         ddf_msg(LVL_NOTE, "rtl8169_receive_done()");
     983        ddf_msg(LVL_DEBUG, "rtl8169_receive_done()");
    852984
    853985        fibril_mutex_lock(&rtl8169->rx_lock);
     
    862994
    863995                if (descr->control & RXSTATUS_RES) {
    864                         ddf_msg(LVL_NOTE, "error at slot %d: 0x%08x\n", tail, descr->control);
     996                        ddf_msg(LVL_WARN, "error at slot %d: 0x%08x\n", tail, descr->control);
    865997                        tail = (tail + 1) % RX_BUFFERS_COUNT;
    866998                        continue;
     
    8711003               
    8721004                if (descr->control & CONTROL_LS) {
    873 
    874                         ddf_msg(LVL_NOTE, "received message at slot %d, control 0x%08x", tail, descr->control);
     1005                        ddf_msg(LVL_DEBUG, "received message at slot %d, control 0x%08x", tail, descr->control);
    8751006
    8761007                        if (fsidx != tail)
     
    9071038        rtl8169_t *rtl8169 = nic_get_specific(nic_data);
    9081039
    909         ddf_msg(LVL_NOTE, "rtl8169_irq_handler(): isr=0x%04x", isr);
     1040        ddf_msg(LVL_DEBUG, "rtl8169_irq_handler(): isr=0x%04x", isr);
    9101041        pio_write_16(rtl8169->regs + IMR, 0xffff);
    9111042
     
    9631094        fibril_mutex_lock(&rtl8169->tx_lock);
    9641095
    965         ddf_msg(LVL_NOTE, "send_frame: size: %zu, tx_head=%d tx_tail=%d",
     1096        ddf_msg(LVL_DEBUG, "send_frame: size: %zu, tx_head=%d tx_tail=%d",
    9661097            size, rtl8169->tx_head, rtl8169->tx_tail);
    9671098
     
    9861117        prev = &rtl8169->tx_ring[(head - 1) % TX_BUFFERS_COUNT];
    9871118
    988         ddf_msg(LVL_NOTE, "current_descr=%p, prev_descr=%p", descr, prev);
     1119        ddf_msg(LVL_DEBUG, "current_descr=%p, prev_descr=%p", descr, prev);
    9891120
    9901121        descr->control = CONTROL_OWN | CONTROL_FS | CONTROL_LS;
  • uspace/drv/nic/rtl8169/driver.h

    rf93ba6d rc62a8275  
    8686        size_t tx_used;
    8787
     88        /** Receive Control Register masks */
     89        uint32_t rcr_ucast;
     90        uint32_t rcr_mcast;
     91
    8892        /** Lock for receiver */
    8993        fibril_mutex_t rx_lock;
  • uspace/lib/c/generic/iplink.c

    rf93ba6d rc62a8275  
    171171}
    172172
     173int iplink_set_mac48(iplink_t *iplink, addr48_t mac)
     174{
     175        async_exch_t *exch = async_exchange_begin(iplink->sess);
     176       
     177        ipc_call_t answer;
     178        aid_t req = async_send_0(exch, IPLINK_GET_MAC48, &answer);
     179       
     180        int rc = async_data_read_start(exch, mac, sizeof(addr48_t));
     181       
     182        loc_exchange_end(exch);
     183       
     184        if (rc != EOK) {
     185                async_forget(req);
     186                return rc;
     187        }
     188       
     189        sysarg_t retval;
     190        async_wait_for(req, &retval);
     191       
     192        return (int) retval;
     193}
     194
     195
    173196int iplink_addr_add(iplink_t *iplink, inet_addr_t *addr)
    174197{
     
    230253        free(sdu.data);
    231254        async_answer_0(iid, rc);
     255}
     256
     257static void iplink_ev_change_addr(iplink_t *iplink, ipc_callid_t iid,
     258    ipc_call_t *icall)
     259{
     260        addr48_t *addr;
     261        size_t size;
     262       
     263        int rc = async_data_write_accept((void **)&addr, false,
     264            sizeof(addr48_t), sizeof(addr48_t), 0, &size);
     265        if (rc != EOK) {
     266                async_answer_0(iid, rc);
     267                return;
     268        }
     269
     270        rc = iplink->ev_ops->change_addr(iplink, *addr);
     271        free(addr);
     272        async_answer_0(iid, EOK);
    232273}
    233274
     
    249290                        iplink_ev_recv(iplink, callid, &call);
    250291                        break;
     292                case IPLINK_EV_CHANGE_ADDR:
     293                        iplink_ev_change_addr(iplink, callid, &call);
    251294                default:
    252295                        async_answer_0(callid, ENOTSUP);
  • uspace/lib/c/generic/iplink_srv.c

    rf93ba6d rc62a8275  
    8181}
    8282
     83static void iplink_set_mac48_srv(iplink_srv_t *srv, ipc_callid_t iid,
     84    ipc_call_t *icall)
     85{
     86        int rc;
     87        size_t size;
     88        addr48_t mac;
     89        ipc_callid_t callid;
     90
     91        rc = async_data_write_receive(&callid, &size);
     92        if (rc != EOK) {
     93                async_answer_0(callid, (sysarg_t) rc);
     94                async_answer_0(iid, (sysarg_t) rc);
     95        }
     96
     97        rc = srv->ops->set_mac48(srv, &mac);
     98        if (rc != EOK) {
     99                async_answer_0(iid, rc);
     100                return;
     101        }
     102       
     103        rc = async_data_read_finalize(callid, &mac, sizeof(addr48_t));
     104        if (rc != EOK)
     105                async_answer_0(callid, rc);
     106       
     107        async_answer_0(iid, (sysarg_t) rc);
     108}
     109
    83110static void iplink_addr_add_srv(iplink_srv_t *srv, ipc_callid_t iid,
    84111    ipc_call_t *icall)
     
    252279                        iplink_get_mac48_srv(srv, callid, &call);
    253280                        break;
     281                case IPLINK_SET_MAC48:
     282                        iplink_set_mac48_srv(srv, callid, &call);
     283                        break;
    254284                case IPLINK_SEND:
    255285                        iplink_send_srv(srv, callid, &call);
     
    300330}
    301331
     332int iplink_ev_change_addr(iplink_srv_t *srv, addr48_t *addr)
     333{
     334        if (srv->client_sess == NULL)
     335                return EIO;
     336       
     337        async_exch_t *exch = async_exchange_begin(srv->client_sess);
     338       
     339        ipc_call_t answer;
     340        aid_t req = async_send_0(exch, IPLINK_EV_CHANGE_ADDR, &answer);
     341       
     342        int rc = async_data_write_start(exch, addr, sizeof(addr48_t));
     343        async_exchange_end(exch);
     344       
     345        if (rc != EOK) {
     346                async_forget(req);
     347                return rc;
     348        }
     349       
     350        sysarg_t retval;
     351        async_wait_for(req, &retval);
     352        if (retval != EOK)
     353                return retval;
     354       
     355        return EOK;
     356}
     357
    302358/** @}
    303359 */
  • uspace/lib/c/include/inet/iplink.h

    rf93ba6d rc62a8275  
    7878typedef struct iplink_ev_ops {
    7979        int (*recv)(iplink_t *, iplink_recv_sdu_t *, ip_ver_t);
     80        int (*change_addr)(iplink_t *, addr48_t);
    8081} iplink_ev_ops_t;
    8182
     
    8889extern int iplink_get_mtu(iplink_t *, size_t *);
    8990extern int iplink_get_mac48(iplink_t *, addr48_t *);
     91extern int iplink_set_mac48(iplink_t *, addr48_t);
    9092
    9193#endif
  • uspace/lib/c/include/inet/iplink_srv.h

    rf93ba6d rc62a8275  
    5959        int (*get_mtu)(iplink_srv_t *, size_t *);
    6060        int (*get_mac48)(iplink_srv_t *, addr48_t *);
     61        int (*set_mac48)(iplink_srv_t *, addr48_t *);
    6162        int (*addr_add)(iplink_srv_t *, inet_addr_t *);
    6263        int (*addr_remove)(iplink_srv_t *, inet_addr_t *);
     
    6768extern int iplink_conn(ipc_callid_t, ipc_call_t *, void *);
    6869extern int iplink_ev_recv(iplink_srv_t *, iplink_recv_sdu_t *, ip_ver_t);
     70extern int iplink_ev_change_addr(iplink_srv_t *, addr48_t *);
    6971
    7072#endif
  • uspace/lib/c/include/ipc/iplink.h

    rf93ba6d rc62a8275  
    4141        IPLINK_GET_MTU = IPC_FIRST_USER_METHOD,
    4242        IPLINK_GET_MAC48,
     43        IPLINK_SET_MAC48,
    4344        IPLINK_SEND,
    4445        IPLINK_SEND6,
     
    4849
    4950typedef enum {
    50         IPLINK_EV_RECV = IPC_FIRST_USER_METHOD
     51        IPLINK_EV_RECV = IPC_FIRST_USER_METHOD,
     52        IPLINK_EV_CHANGE_ADDR,
    5153} iplink_event_t;
    5254
  • uspace/lib/nic/src/nic_driver.c

    rf93ba6d rc62a8275  
    4747#include <ops/nic.h>
    4848#include <errno.h>
    49 
    50 #include <io/log.h>
    5149
    5250#include "nic_driver.h"
     
    438436                int rc = nic_ev_addr_changed(nic_data->client_session,
    439437                    address);
    440                 log_msg(LOG_DEFAULT, LVL_WARN, "rc=%d", rc);
    441438
    442439                if (rc != EOK) {
  • uspace/srv/net/ethip/ethip.c

    rf93ba6d rc62a8275  
    5959static int ethip_get_mtu(iplink_srv_t *srv, size_t *mtu);
    6060static int ethip_get_mac48(iplink_srv_t *srv, addr48_t *mac);
     61static int ethip_set_mac48(iplink_srv_t *srv, addr48_t *mac);
    6162static int ethip_addr_add(iplink_srv_t *srv, inet_addr_t *addr);
    6263static int ethip_addr_remove(iplink_srv_t *srv, inet_addr_t *addr);
     
    7172        .get_mtu = ethip_get_mtu,
    7273        .get_mac48 = ethip_get_mac48,
     74        .set_mac48 = ethip_set_mac48,
    7375        .addr_add = ethip_addr_add,
    7476        .addr_remove = ethip_addr_remove
     
    284286}
    285287
     288static int ethip_set_mac48(iplink_srv_t *srv, addr48_t *mac)
     289{
     290        log_msg(LOG_DEFAULT, LVL_DEBUG, "ethip_set_mac48()");
     291       
     292        ethip_nic_t *nic = (ethip_nic_t *) srv->arg;
     293        addr48(*mac, nic->mac_addr);
     294       
     295        return EOK;
     296}
     297
    286298static int ethip_addr_add(iplink_srv_t *srv, inet_addr_t *addr)
    287299{
  • uspace/srv/net/ethip/ethip_nic.c

    rf93ba6d rc62a8275  
    245245            addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
    246246
     247        memcpy(&nic->mac_addr, addr, sizeof(nic->mac_addr));
     248
     249        rc = iplink_ev_change_addr(&nic->iplink, &nic->mac_addr);
     250        if (rc != EOK) {
     251                log_msg(LOG_DEFAULT, LVL_DEBUG, "iplink_ev_change_addr() failed");
     252                return;
     253        }
     254
    247255        free(addr);
    248256        async_answer_0(callid, EOK);
     
    309317                        break;
    310318                default:
    311                         log_msg(LOG_DEFAULT, LVL_DEBUG, "unknown IPC method: %d", (int) IPC_GET_IMETHOD(call));
     319                        log_msg(LOG_DEFAULT, LVL_DEBUG, "unknown IPC method: %" PRIun, IPC_GET_IMETHOD(call));
    312320                        async_answer_0(callid, ENOTSUP);
    313321                }
  • uspace/srv/net/inetsrv/inet_link.c

    rf93ba6d rc62a8275  
    5555
    5656static int inet_iplink_recv(iplink_t *, iplink_recv_sdu_t *, ip_ver_t);
     57static int inet_iplink_change_addr(iplink_t *, addr48_t);
    5758static inet_link_t *inet_link_get_by_id_locked(sysarg_t);
    5859
    5960static iplink_ev_ops_t inet_iplink_ev_ops = {
    60         .recv = inet_iplink_recv
     61        .recv = inet_iplink_recv,
     62        .change_addr = inet_iplink_change_addr,
    6163};
    6264
     
    110112       
    111113        return rc;
     114}
     115
     116static int inet_iplink_change_addr(iplink_t *iplink, addr48_t mac)
     117{
     118        log_msg(LOG_DEFAULT, LVL_DEBUG, "inet_iplink_change_addr(): "
     119            "new addr=%02x:%02x:%02x:%02x:%02x:%02x",
     120            mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
     121
     122        list_foreach(inet_links, link_list, inet_link_t, ilink) {
     123                if (ilink->sess == iplink->sess)
     124                        memcpy(&ilink->mac, mac, sizeof(addr48_t));
     125        }
     126
     127        return EOK;
    112128}
    113129
Note: See TracChangeset for help on using the changeset viewer.