41 static int ql_m_multicst(void *, boolean_t, const uint8_t *); |
41 static int ql_m_multicst(void *, boolean_t, const uint8_t *); |
42 static int ql_m_unicst(void *, const uint8_t *); |
42 static int ql_m_unicst(void *, const uint8_t *); |
43 static mblk_t *ql_m_tx(void *, mblk_t *); |
43 static mblk_t *ql_m_tx(void *, mblk_t *); |
44 static void ql_m_ioctl(void *, queue_t *, mblk_t *); |
44 static void ql_m_ioctl(void *, queue_t *, mblk_t *); |
45 static boolean_t ql_m_getcapab(void *, mac_capab_t, void *); |
45 static boolean_t ql_m_getcapab(void *, mac_capab_t, void *); |
46 static int ql_unicst_set(qlge_t *qlge, const uint8_t *macaddr, int slot); |
|
47 |
46 |
48 static int ql_m_setprop(void *, const char *, mac_prop_id_t, uint_t, |
47 static int ql_m_setprop(void *, const char *, mac_prop_id_t, uint_t, |
49 const void *); |
48 const void *); |
50 static int ql_m_getprop(void *, const char *, mac_prop_id_t, uint_t, void *); |
49 static int ql_m_getprop(void *, const char *, mac_prop_id_t, uint_t, void *); |
51 static void ql_m_propinfo(void *, const char *, mac_prop_id_t, |
50 static void ql_m_propinfo(void *, const char *, mac_prop_id_t, |
164 (uint8_t *)ep, 8, ETHERADDRL); |
164 (uint8_t *)ep, 8, ETHERADDRL); |
165 ret = ql_remove_from_multicast_list(qlge, (uint8_t *)ep); |
165 ret = ql_remove_from_multicast_list(qlge, (uint8_t *)ep); |
166 } |
166 } |
167 mutex_exit(&qlge->gen_mutex); |
167 mutex_exit(&qlge->gen_mutex); |
168 |
168 |
169 return ((ret == DDI_SUCCESS) ? 0 : EIO); |
169 if (ret != DDI_SUCCESS) { |
|
170 ret = EIO; |
|
171 if (qlge->fm_enable) { |
|
172 ddi_fm_service_impact(qlge->dip, DDI_SERVICE_DEGRADED); |
|
173 } |
|
174 } else { |
|
175 ret = 0; |
|
176 } |
|
177 return (ret); |
170 } |
178 } |
171 |
179 |
172 /* |
180 /* |
173 * Enable or disable promiscuous mode |
181 * Enable or disable promiscuous mode |
174 */ |
182 */ |
397 } |
405 } |
398 |
406 |
399 /* |
407 /* |
400 * Set the physical network address |
408 * Set the physical network address |
401 */ |
409 */ |
402 static int |
410 int |
403 ql_unicst_set(qlge_t *qlge, const uint8_t *macaddr, int slot) |
411 ql_unicst_set(qlge_t *qlge, const uint8_t *macaddr, int slot) |
404 { |
412 { |
405 int status; |
413 int ret; |
406 |
414 |
407 status = ql_sem_spinlock(qlge, SEM_MAC_ADDR_MASK); |
415 ret = ql_sem_spinlock(qlge, SEM_MAC_ADDR_MASK); |
408 if (status != DDI_SUCCESS) |
416 if (ret != DDI_SUCCESS) |
409 return (EIO); |
417 goto exit; |
410 status = ql_set_mac_addr_reg(qlge, (uint8_t *)macaddr, |
418 ret = ql_set_mac_addr_reg(qlge, (uint8_t *)macaddr, |
411 MAC_ADDR_TYPE_CAM_MAC, |
419 MAC_ADDR_TYPE_CAM_MAC, |
412 (uint16_t)(qlge->func_number * MAX_CQ + slot)); |
420 (uint16_t)(qlge->func_number * MAX_CQ + slot)); |
413 ql_sem_unlock(qlge, SEM_MAC_ADDR_MASK); |
421 ql_sem_unlock(qlge, SEM_MAC_ADDR_MASK); |
414 |
422 |
415 return ((status == DDI_SUCCESS) ? 0 : EIO); |
423 exit: |
|
424 if (ret != DDI_SUCCESS) { |
|
425 ret = EIO; |
|
426 if (qlge->fm_enable) { |
|
427 ddi_fm_service_impact(qlge->dip, DDI_SERVICE_DEGRADED); |
|
428 } |
|
429 } else { |
|
430 ret = 0; |
|
431 } |
|
432 return (ret); |
416 } |
433 } |
417 |
434 |
418 /* |
435 /* |
419 * Set default MAC address |
436 * Set default MAC address |
420 * Each function has a total of 128 mac address, function0: 0~127, |
437 * Each function has a total of 128 mac address, function0: 0~127, |
454 qlge_t *qlge = (qlge_t *)arg; |
471 qlge_t *qlge = (qlge_t *)arg; |
455 struct tx_ring *tx_ring; |
472 struct tx_ring *tx_ring; |
456 mblk_t *next; |
473 mblk_t *next; |
457 int rval; |
474 int rval; |
458 uint32_t tx_count = 0; |
475 uint32_t tx_count = 0; |
459 |
476 caddr_t bp; |
460 if (qlge->port_link_state == LS_DOWN) { |
477 uint8_t selected_ring = 0; |
461 cmn_err(CE_WARN, "%s(%d): exit due to link down", |
478 |
|
479 if ((qlge->port_link_state == LS_DOWN) || |
|
480 (qlge->mac_flags != QL_MAC_STARTED)) { |
|
481 |
|
482 cmn_err(CE_WARN, "!%s(%d): exit due to link down", |
462 __func__, qlge->instance); |
483 __func__, qlge->instance); |
463 freemsgchain(mp); |
484 freemsgchain(mp); |
464 mp = NULL; |
485 mp = NULL; |
465 goto tx_exit; |
486 goto tx_exit; |
466 } |
487 } |
467 |
488 |
468 /* |
489 /* |
469 * Always send this packet through tx ring 0 for now. |
490 * Calculate which tx ring to send this packet |
470 * Will use multiple tx rings when Crossbow is supported |
|
471 */ |
491 */ |
472 tx_ring = &qlge->tx_ring[0]; |
492 bp = (caddr_t)mp->b_rptr; |
|
493 selected_ring = ql_tx_hashing(qlge, bp); |
|
494 tx_ring = &qlge->tx_ring[selected_ring]; |
473 mutex_enter(&tx_ring->tx_lock); |
495 mutex_enter(&tx_ring->tx_lock); |
474 if (tx_ring->mac_flags != QL_MAC_STARTED) { |
496 if (tx_ring->mac_flags != QL_MAC_STARTED) { |
475 mutex_exit(&tx_ring->tx_lock); |
497 mutex_exit(&tx_ring->tx_lock); |
476 goto tx_exit; |
498 goto tx_exit; |
477 } |
499 } |
682 err = EINVAL; |
704 err = EINVAL; |
683 } else if (qlge->pause != (uint32_t)result) { |
705 } else if (qlge->pause != (uint32_t)result) { |
684 qlge->pause = (uint32_t)result; |
706 qlge->pause = (uint32_t)result; |
685 if (qlge->flags & INTERRUPTS_ENABLED) { |
707 if (qlge->flags & INTERRUPTS_ENABLED) { |
686 mutex_enter(&qlge->mbx_mutex); |
708 mutex_enter(&qlge->mbx_mutex); |
687 if (ql_set_port_cfg(qlge) == DDI_FAILURE) |
709 if (ql_set_pause_mode(qlge) == DDI_FAILURE) |
688 err = EINVAL; |
710 err = EINVAL; |
689 mutex_exit(&qlge->mbx_mutex); |
711 mutex_exit(&qlge->mbx_mutex); |
690 } |
712 } |
|
713 } |
|
714 return (err); |
|
715 } else if (strcmp(pr_name, "_fm_enable") == 0) { |
|
716 (void) ddi_strtol(pr_val, (char **)NULL, 0, &result); |
|
717 if ((result != 0) && (result != 1)) { |
|
718 err = EINVAL; |
|
719 } else if (qlge->fm_enable != (boolean_t)result) { |
|
720 qlge->fm_enable = (boolean_t)result; |
691 } |
721 } |
692 return (err); |
722 return (err); |
693 } |
723 } |
694 return (ENOTSUP); |
724 return (ENOTSUP); |
695 } |
725 } |
770 uint32_t value; |
800 uint32_t value; |
771 |
801 |
772 if (strcmp(pr_name, "_adv_pause_mode") == 0) { |
802 if (strcmp(pr_name, "_adv_pause_mode") == 0) { |
773 value = qlge->pause; |
803 value = qlge->pause; |
774 err = 0; |
804 err = 0; |
775 goto done; |
805 } else if (strcmp(pr_name, "_fm_enable") == 0) { |
776 } |
806 value = qlge->fm_enable; |
777 |
807 err = 0; |
778 done: |
808 } |
|
809 |
779 if (err == 0) { |
810 if (err == 0) { |
780 (void) snprintf(pr_val, pr_valsize, "%d", value); |
811 (void) snprintf(pr_val, pr_valsize, "%d", value); |
781 } |
812 } |
782 return (err); |
813 return (err); |
783 } |
814 } |
835 out: |
866 out: |
836 mutex_exit(&qlge->gen_mutex); |
867 mutex_exit(&qlge->gen_mutex); |
837 return (err); |
868 return (err); |
838 } |
869 } |
839 |
870 |
|
871 /* ARGSUSED */ |
840 static void |
872 static void |
841 ql_m_propinfo(void *barg, const char *pr_name, mac_prop_id_t pr_num, |
873 ql_m_propinfo(void *barg, const char *pr_name, mac_prop_id_t pr_num, |
842 mac_prop_info_handle_t prh) |
874 mac_prop_info_handle_t prh) |
843 { |
875 { |
844 _NOTE(ARGUNUSED(barg)); |
876 _NOTE(ARGUNUSED(barg)); |
845 |
877 |
846 switch (pr_num) { |
878 switch (pr_num) { |
847 case MAC_PROP_DUPLEX: |
879 case MAC_PROP_DUPLEX: |
848 case MAC_PROP_SPEED: |
880 case MAC_PROP_SPEED: |
849 case MAC_PROP_STATUS: |
881 case MAC_PROP_STATUS: |
854 char val_str[64]; |
886 char val_str[64]; |
855 int default_val; |
887 int default_val; |
856 |
888 |
857 if (strcmp(pr_name, "_adv_pause_mode") == 0) |
889 if (strcmp(pr_name, "_adv_pause_mode") == 0) |
858 default_val = 2; |
890 default_val = 2; |
|
891 else if (strcmp(pr_name, "_fm_enable") == 0) |
|
892 default_val = 1; |
859 else |
893 else |
860 return; |
894 return; |
861 |
895 |
862 (void) snprintf(val_str, sizeof (val_str), "%d", default_val); |
896 (void) snprintf(val_str, sizeof (val_str), "%d", default_val); |
863 mac_prop_info_set_default_str(prh, val_str); |
897 mac_prop_info_set_default_str(prh, val_str); |
894 break; |
928 break; |
895 |
929 |
896 case MAC_CAPAB_LSO: { |
930 case MAC_CAPAB_LSO: { |
897 mac_capab_lso_t *cap_lso = (mac_capab_lso_t *)cap_data; |
931 mac_capab_lso_t *cap_lso = (mac_capab_lso_t *)cap_data; |
898 uint32_t page_size; |
932 uint32_t page_size; |
|
933 uint32_t lso_max; |
899 |
934 |
900 if ((qlge->cfg_flags & CFG_LSO)&& |
935 if ((qlge->cfg_flags & CFG_LSO)&& |
901 (qlge->cfg_flags & CFG_SUPPORT_SCATTER_GATHER)) { |
936 (qlge->cfg_flags & CFG_SUPPORT_SCATTER_GATHER)) { |
902 cap_lso->lso_flags = LSO_TX_BASIC_TCP_IPV4; |
937 cap_lso->lso_flags = LSO_TX_BASIC_TCP_IPV4; |
903 page_size = ddi_ptob(qlge->dip, (ulong_t)1); |
938 page_size = ddi_ptob(qlge->dip, (ulong_t)1); |
904 cap_lso->lso_basic_tcp_ipv4.lso_max = page_size * |
939 lso_max = page_size * (QL_MAX_TX_DMA_HANDLES-1); |
905 (QL_MAX_TX_DMA_HANDLES-1); |
940 cap_lso->lso_basic_tcp_ipv4.lso_max = |
|
941 min(lso_max, QL_LSO_MAX); |
906 ret = B_TRUE; |
942 ret = B_TRUE; |
907 } |
943 } |
908 break; |
944 break; |
909 } |
945 } |
910 |
946 |