diff options
author | Sreenivasa Honnur <sreenivasa.honnur@neterion.com> | 2008-01-24 04:45:43 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-01-28 18:03:52 -0500 |
commit | faa4f7969f3340606f46515560ce193d9bd74ea4 (patch) | |
tree | 31bd54a2162dd35767baaeaaf4ae55ada2dd7958 | |
parent | db0ce50d3792e993a1b24f16fb70153eccf38f33 (diff) |
[S2IO]: Support for add/delete/store/restore ethernet addresses
- Support to add/delete/store/restore 64 and 128 Ethernet addresses for Xframe I and Xframe II respectively.
Signed-off-by: Sreenivasa Honnur <sreenivasa.honnur@neterion.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/s2io-regs.h | 16 | ||||
-rw-r--r-- | drivers/net/s2io.c | 194 | ||||
-rw-r--r-- | drivers/net/s2io.h | 14 |
3 files changed, 201 insertions, 23 deletions
diff --git a/drivers/net/s2io-regs.h b/drivers/net/s2io-regs.h index f25264f2638e..2109508c047a 100644 --- a/drivers/net/s2io-regs.h +++ b/drivers/net/s2io-regs.h | |||
@@ -723,11 +723,17 @@ struct XENA_dev_config { | |||
723 | u64 rmac_cfg_key; | 723 | u64 rmac_cfg_key; |
724 | #define RMAC_CFG_KEY(val) vBIT(val,0,16) | 724 | #define RMAC_CFG_KEY(val) vBIT(val,0,16) |
725 | 725 | ||
726 | #define MAX_MAC_ADDRESSES 16 | 726 | #define S2IO_MAC_ADDR_START_OFFSET 0 |
727 | #define MAX_MC_ADDRESSES 32 /* Multicast addresses */ | 727 | |
728 | #define MAC_MAC_ADDR_START_OFFSET 0 | 728 | #define S2IO_XENA_MAX_MC_ADDRESSES 64 /* multicast addresses */ |
729 | #define MAC_MC_ADDR_START_OFFSET 16 | 729 | #define S2IO_HERC_MAX_MC_ADDRESSES 256 |
730 | #define MAC_MC_ALL_MC_ADDR_OFFSET 63 /* enables all multicast pkts */ | 730 | |
731 | #define S2IO_XENA_MAX_MAC_ADDRESSES 16 | ||
732 | #define S2IO_HERC_MAX_MAC_ADDRESSES 64 | ||
733 | |||
734 | #define S2IO_XENA_MC_ADDR_START_OFFSET 16 | ||
735 | #define S2IO_HERC_MC_ADDR_START_OFFSET 64 | ||
736 | |||
731 | u64 rmac_addr_cmd_mem; | 737 | u64 rmac_addr_cmd_mem; |
732 | #define RMAC_ADDR_CMD_MEM_WE s2BIT(7) | 738 | #define RMAC_ADDR_CMD_MEM_WE s2BIT(7) |
733 | #define RMAC_ADDR_CMD_MEM_RD 0 | 739 | #define RMAC_ADDR_CMD_MEM_RD 0 |
diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c index 67e0a65fc28c..644d71bfb640 100644 --- a/drivers/net/s2io.c +++ b/drivers/net/s2io.c | |||
@@ -3375,6 +3375,9 @@ static void s2io_reset(struct s2io_nic * sp) | |||
3375 | /* Set swapper to enable I/O register access */ | 3375 | /* Set swapper to enable I/O register access */ |
3376 | s2io_set_swapper(sp); | 3376 | s2io_set_swapper(sp); |
3377 | 3377 | ||
3378 | /* restore mac_addr entries */ | ||
3379 | do_s2io_restore_unicast_mc(sp); | ||
3380 | |||
3378 | /* Restore the MSIX table entries from local variables */ | 3381 | /* Restore the MSIX table entries from local variables */ |
3379 | restore_xmsi_data(sp); | 3382 | restore_xmsi_data(sp); |
3380 | 3383 | ||
@@ -3433,9 +3436,6 @@ static void s2io_reset(struct s2io_nic * sp) | |||
3433 | writeq(val64, &bar0->pcc_err_reg); | 3436 | writeq(val64, &bar0->pcc_err_reg); |
3434 | } | 3437 | } |
3435 | 3438 | ||
3436 | /* restore the previously assigned mac address */ | ||
3437 | do_s2io_prog_unicast(sp->dev, (u8 *)&sp->def_mac_addr[0].mac_addr); | ||
3438 | |||
3439 | sp->device_enabled_once = FALSE; | 3439 | sp->device_enabled_once = FALSE; |
3440 | } | 3440 | } |
3441 | 3441 | ||
@@ -3920,6 +3920,9 @@ hw_init_failed: | |||
3920 | static int s2io_close(struct net_device *dev) | 3920 | static int s2io_close(struct net_device *dev) |
3921 | { | 3921 | { |
3922 | struct s2io_nic *sp = dev->priv; | 3922 | struct s2io_nic *sp = dev->priv; |
3923 | struct config_param *config = &sp->config; | ||
3924 | u64 tmp64; | ||
3925 | int offset; | ||
3923 | 3926 | ||
3924 | /* Return if the device is already closed * | 3927 | /* Return if the device is already closed * |
3925 | * Can happen when s2io_card_up failed in change_mtu * | 3928 | * Can happen when s2io_card_up failed in change_mtu * |
@@ -3928,6 +3931,14 @@ static int s2io_close(struct net_device *dev) | |||
3928 | return 0; | 3931 | return 0; |
3929 | 3932 | ||
3930 | netif_stop_queue(dev); | 3933 | netif_stop_queue(dev); |
3934 | |||
3935 | /* delete all populated mac entries */ | ||
3936 | for (offset = 1; offset < config->max_mc_addr; offset++) { | ||
3937 | tmp64 = do_s2io_read_unicast_mc(sp, offset); | ||
3938 | if (tmp64 != S2IO_DISABLE_MAC_ENTRY) | ||
3939 | do_s2io_delete_unicast_mc(sp, tmp64); | ||
3940 | } | ||
3941 | |||
3931 | /* Reset card, kill tasklet and free Tx and Rx buffers. */ | 3942 | /* Reset card, kill tasklet and free Tx and Rx buffers. */ |
3932 | s2io_card_down(sp); | 3943 | s2io_card_down(sp); |
3933 | 3944 | ||
@@ -4728,8 +4739,9 @@ static void s2io_set_multicast(struct net_device *dev) | |||
4728 | struct XENA_dev_config __iomem *bar0 = sp->bar0; | 4739 | struct XENA_dev_config __iomem *bar0 = sp->bar0; |
4729 | u64 val64 = 0, multi_mac = 0x010203040506ULL, mask = | 4740 | u64 val64 = 0, multi_mac = 0x010203040506ULL, mask = |
4730 | 0xfeffffffffffULL; | 4741 | 0xfeffffffffffULL; |
4731 | u64 dis_addr = 0xffffffffffffULL, mac_addr = 0; | 4742 | u64 dis_addr = S2IO_DISABLE_MAC_ENTRY, mac_addr = 0; |
4732 | void __iomem *add; | 4743 | void __iomem *add; |
4744 | struct config_param *config = &sp->config; | ||
4733 | 4745 | ||
4734 | if ((dev->flags & IFF_ALLMULTI) && (!sp->m_cast_flg)) { | 4746 | if ((dev->flags & IFF_ALLMULTI) && (!sp->m_cast_flg)) { |
4735 | /* Enable all Multicast addresses */ | 4747 | /* Enable all Multicast addresses */ |
@@ -4739,7 +4751,7 @@ static void s2io_set_multicast(struct net_device *dev) | |||
4739 | &bar0->rmac_addr_data1_mem); | 4751 | &bar0->rmac_addr_data1_mem); |
4740 | val64 = RMAC_ADDR_CMD_MEM_WE | | 4752 | val64 = RMAC_ADDR_CMD_MEM_WE | |
4741 | RMAC_ADDR_CMD_MEM_STROBE_NEW_CMD | | 4753 | RMAC_ADDR_CMD_MEM_STROBE_NEW_CMD | |
4742 | RMAC_ADDR_CMD_MEM_OFFSET(MAC_MC_ALL_MC_ADDR_OFFSET); | 4754 | RMAC_ADDR_CMD_MEM_OFFSET(config->max_mc_addr - 1); |
4743 | writeq(val64, &bar0->rmac_addr_cmd_mem); | 4755 | writeq(val64, &bar0->rmac_addr_cmd_mem); |
4744 | /* Wait till command completes */ | 4756 | /* Wait till command completes */ |
4745 | wait_for_cmd_complete(&bar0->rmac_addr_cmd_mem, | 4757 | wait_for_cmd_complete(&bar0->rmac_addr_cmd_mem, |
@@ -4747,7 +4759,7 @@ static void s2io_set_multicast(struct net_device *dev) | |||
4747 | S2IO_BIT_RESET); | 4759 | S2IO_BIT_RESET); |
4748 | 4760 | ||
4749 | sp->m_cast_flg = 1; | 4761 | sp->m_cast_flg = 1; |
4750 | sp->all_multi_pos = MAC_MC_ALL_MC_ADDR_OFFSET; | 4762 | sp->all_multi_pos = config->max_mc_addr - 1; |
4751 | } else if ((dev->flags & IFF_ALLMULTI) && (sp->m_cast_flg)) { | 4763 | } else if ((dev->flags & IFF_ALLMULTI) && (sp->m_cast_flg)) { |
4752 | /* Disable all Multicast addresses */ | 4764 | /* Disable all Multicast addresses */ |
4753 | writeq(RMAC_ADDR_DATA0_MEM_ADDR(dis_addr), | 4765 | writeq(RMAC_ADDR_DATA0_MEM_ADDR(dis_addr), |
@@ -4816,7 +4828,7 @@ static void s2io_set_multicast(struct net_device *dev) | |||
4816 | /* Update individual M_CAST address list */ | 4828 | /* Update individual M_CAST address list */ |
4817 | if ((!sp->m_cast_flg) && dev->mc_count) { | 4829 | if ((!sp->m_cast_flg) && dev->mc_count) { |
4818 | if (dev->mc_count > | 4830 | if (dev->mc_count > |
4819 | (MAX_ADDRS_SUPPORTED - MAC_MC_ADDR_START_OFFSET - 1)) { | 4831 | (config->max_mc_addr - config->max_mac_addr)) { |
4820 | DBG_PRINT(ERR_DBG, "%s: No more Rx filters ", | 4832 | DBG_PRINT(ERR_DBG, "%s: No more Rx filters ", |
4821 | dev->name); | 4833 | dev->name); |
4822 | DBG_PRINT(ERR_DBG, "can be added, please enable "); | 4834 | DBG_PRINT(ERR_DBG, "can be added, please enable "); |
@@ -4836,7 +4848,7 @@ static void s2io_set_multicast(struct net_device *dev) | |||
4836 | val64 = RMAC_ADDR_CMD_MEM_WE | | 4848 | val64 = RMAC_ADDR_CMD_MEM_WE | |
4837 | RMAC_ADDR_CMD_MEM_STROBE_NEW_CMD | | 4849 | RMAC_ADDR_CMD_MEM_STROBE_NEW_CMD | |
4838 | RMAC_ADDR_CMD_MEM_OFFSET | 4850 | RMAC_ADDR_CMD_MEM_OFFSET |
4839 | (MAC_MC_ADDR_START_OFFSET + i); | 4851 | (config->mc_start_offset + i); |
4840 | writeq(val64, &bar0->rmac_addr_cmd_mem); | 4852 | writeq(val64, &bar0->rmac_addr_cmd_mem); |
4841 | 4853 | ||
4842 | /* Wait for command completes */ | 4854 | /* Wait for command completes */ |
@@ -4868,7 +4880,7 @@ static void s2io_set_multicast(struct net_device *dev) | |||
4868 | val64 = RMAC_ADDR_CMD_MEM_WE | | 4880 | val64 = RMAC_ADDR_CMD_MEM_WE | |
4869 | RMAC_ADDR_CMD_MEM_STROBE_NEW_CMD | | 4881 | RMAC_ADDR_CMD_MEM_STROBE_NEW_CMD | |
4870 | RMAC_ADDR_CMD_MEM_OFFSET | 4882 | RMAC_ADDR_CMD_MEM_OFFSET |
4871 | (i + MAC_MC_ADDR_START_OFFSET); | 4883 | (i + config->mc_start_offset); |
4872 | writeq(val64, &bar0->rmac_addr_cmd_mem); | 4884 | writeq(val64, &bar0->rmac_addr_cmd_mem); |
4873 | 4885 | ||
4874 | /* Wait for command completes */ | 4886 | /* Wait for command completes */ |
@@ -4884,8 +4896,78 @@ static void s2io_set_multicast(struct net_device *dev) | |||
4884 | } | 4896 | } |
4885 | } | 4897 | } |
4886 | 4898 | ||
4887 | /* add unicast MAC address to CAM */ | 4899 | /* read from CAM unicast & multicast addresses and store it in |
4888 | static int do_s2io_add_unicast(struct s2io_nic *sp, u64 addr, int off) | 4900 | * def_mac_addr structure |
4901 | */ | ||
4902 | void do_s2io_store_unicast_mc(struct s2io_nic *sp) | ||
4903 | { | ||
4904 | int offset; | ||
4905 | u64 mac_addr = 0x0; | ||
4906 | struct config_param *config = &sp->config; | ||
4907 | |||
4908 | /* store unicast & multicast mac addresses */ | ||
4909 | for (offset = 0; offset < config->max_mc_addr; offset++) { | ||
4910 | mac_addr = do_s2io_read_unicast_mc(sp, offset); | ||
4911 | /* if read fails disable the entry */ | ||
4912 | if (mac_addr == FAILURE) | ||
4913 | mac_addr = S2IO_DISABLE_MAC_ENTRY; | ||
4914 | do_s2io_copy_mac_addr(sp, offset, mac_addr); | ||
4915 | } | ||
4916 | } | ||
4917 | |||
4918 | /* restore unicast & multicast MAC to CAM from def_mac_addr structure */ | ||
4919 | static void do_s2io_restore_unicast_mc(struct s2io_nic *sp) | ||
4920 | { | ||
4921 | int offset; | ||
4922 | struct config_param *config = &sp->config; | ||
4923 | /* restore unicast mac address */ | ||
4924 | for (offset = 0; offset < config->max_mac_addr; offset++) | ||
4925 | do_s2io_prog_unicast(sp->dev, | ||
4926 | sp->def_mac_addr[offset].mac_addr); | ||
4927 | |||
4928 | /* restore multicast mac address */ | ||
4929 | for (offset = config->mc_start_offset; | ||
4930 | offset < config->max_mc_addr; offset++) | ||
4931 | do_s2io_add_mc(sp, sp->def_mac_addr[offset].mac_addr); | ||
4932 | } | ||
4933 | |||
4934 | /* add a multicast MAC address to CAM */ | ||
4935 | static int do_s2io_add_mc(struct s2io_nic *sp, u8 *addr) | ||
4936 | { | ||
4937 | int i; | ||
4938 | u64 mac_addr = 0; | ||
4939 | struct config_param *config = &sp->config; | ||
4940 | |||
4941 | for (i = 0; i < ETH_ALEN; i++) { | ||
4942 | mac_addr <<= 8; | ||
4943 | mac_addr |= addr[i]; | ||
4944 | } | ||
4945 | if ((0ULL == mac_addr) || (mac_addr == S2IO_DISABLE_MAC_ENTRY)) | ||
4946 | return SUCCESS; | ||
4947 | |||
4948 | /* check if the multicast mac already preset in CAM */ | ||
4949 | for (i = config->mc_start_offset; i < config->max_mc_addr; i++) { | ||
4950 | u64 tmp64; | ||
4951 | tmp64 = do_s2io_read_unicast_mc(sp, i); | ||
4952 | if (tmp64 == S2IO_DISABLE_MAC_ENTRY) /* CAM entry is empty */ | ||
4953 | break; | ||
4954 | |||
4955 | if (tmp64 == mac_addr) | ||
4956 | return SUCCESS; | ||
4957 | } | ||
4958 | if (i == config->max_mc_addr) { | ||
4959 | DBG_PRINT(ERR_DBG, | ||
4960 | "CAM full no space left for multicast MAC\n"); | ||
4961 | return FAILURE; | ||
4962 | } | ||
4963 | /* Update the internal structure with this new mac address */ | ||
4964 | do_s2io_copy_mac_addr(sp, i, mac_addr); | ||
4965 | |||
4966 | return (do_s2io_add_mac(sp, mac_addr, i)); | ||
4967 | } | ||
4968 | |||
4969 | /* add MAC address to CAM */ | ||
4970 | static int do_s2io_add_mac(struct s2io_nic *sp, u64 addr, int off) | ||
4889 | { | 4971 | { |
4890 | u64 val64; | 4972 | u64 val64; |
4891 | struct XENA_dev_config __iomem *bar0 = sp->bar0; | 4973 | struct XENA_dev_config __iomem *bar0 = sp->bar0; |
@@ -4902,15 +4984,62 @@ static int do_s2io_add_unicast(struct s2io_nic *sp, u64 addr, int off) | |||
4902 | if (wait_for_cmd_complete(&bar0->rmac_addr_cmd_mem, | 4984 | if (wait_for_cmd_complete(&bar0->rmac_addr_cmd_mem, |
4903 | RMAC_ADDR_CMD_MEM_STROBE_CMD_EXECUTING, | 4985 | RMAC_ADDR_CMD_MEM_STROBE_CMD_EXECUTING, |
4904 | S2IO_BIT_RESET)) { | 4986 | S2IO_BIT_RESET)) { |
4905 | DBG_PRINT(INFO_DBG, "add_mac_addr failed\n"); | 4987 | DBG_PRINT(INFO_DBG, "do_s2io_add_mac failed\n"); |
4906 | return FAILURE; | 4988 | return FAILURE; |
4907 | } | 4989 | } |
4908 | return SUCCESS; | 4990 | return SUCCESS; |
4909 | } | 4991 | } |
4992 | /* deletes a specified unicast/multicast mac entry from CAM */ | ||
4993 | static int do_s2io_delete_unicast_mc(struct s2io_nic *sp, u64 addr) | ||
4994 | { | ||
4995 | int offset; | ||
4996 | u64 dis_addr = S2IO_DISABLE_MAC_ENTRY, tmp64; | ||
4997 | struct config_param *config = &sp->config; | ||
4998 | |||
4999 | for (offset = 1; | ||
5000 | offset < config->max_mc_addr; offset++) { | ||
5001 | tmp64 = do_s2io_read_unicast_mc(sp, offset); | ||
5002 | if (tmp64 == addr) { | ||
5003 | /* disable the entry by writing 0xffffffffffffULL */ | ||
5004 | if (do_s2io_add_mac(sp, dis_addr, offset) == FAILURE) | ||
5005 | return FAILURE; | ||
5006 | /* store the new mac list from CAM */ | ||
5007 | do_s2io_store_unicast_mc(sp); | ||
5008 | return SUCCESS; | ||
5009 | } | ||
5010 | } | ||
5011 | DBG_PRINT(ERR_DBG, "MAC address 0x%llx not found in CAM\n", | ||
5012 | (unsigned long long)addr); | ||
5013 | return FAILURE; | ||
5014 | } | ||
5015 | |||
5016 | /* read mac entries from CAM */ | ||
5017 | static u64 do_s2io_read_unicast_mc(struct s2io_nic *sp, int offset) | ||
5018 | { | ||
5019 | u64 tmp64 = 0xffffffffffff0000ULL, val64; | ||
5020 | struct XENA_dev_config __iomem *bar0 = sp->bar0; | ||
5021 | |||
5022 | /* read mac addr */ | ||
5023 | val64 = | ||
5024 | RMAC_ADDR_CMD_MEM_RD | RMAC_ADDR_CMD_MEM_STROBE_NEW_CMD | | ||
5025 | RMAC_ADDR_CMD_MEM_OFFSET(offset); | ||
5026 | writeq(val64, &bar0->rmac_addr_cmd_mem); | ||
5027 | |||
5028 | /* Wait till command completes */ | ||
5029 | if (wait_for_cmd_complete(&bar0->rmac_addr_cmd_mem, | ||
5030 | RMAC_ADDR_CMD_MEM_STROBE_CMD_EXECUTING, | ||
5031 | S2IO_BIT_RESET)) { | ||
5032 | DBG_PRINT(INFO_DBG, "do_s2io_read_unicast_mc failed\n"); | ||
5033 | return FAILURE; | ||
5034 | } | ||
5035 | tmp64 = readq(&bar0->rmac_addr_data0_mem); | ||
5036 | return (tmp64 >> 16); | ||
5037 | } | ||
4910 | 5038 | ||
4911 | /** | 5039 | /** |
4912 | * s2io_set_mac_addr driver entry point | 5040 | * s2io_set_mac_addr driver entry point |
4913 | */ | 5041 | */ |
5042 | |||
4914 | static int s2io_set_mac_addr(struct net_device *dev, void *p) | 5043 | static int s2io_set_mac_addr(struct net_device *dev, void *p) |
4915 | { | 5044 | { |
4916 | struct sockaddr *addr = p; | 5045 | struct sockaddr *addr = p; |
@@ -4923,7 +5052,6 @@ static int s2io_set_mac_addr(struct net_device *dev, void *p) | |||
4923 | /* store the MAC address in CAM */ | 5052 | /* store the MAC address in CAM */ |
4924 | return (do_s2io_prog_unicast(dev, dev->dev_addr)); | 5053 | return (do_s2io_prog_unicast(dev, dev->dev_addr)); |
4925 | } | 5054 | } |
4926 | |||
4927 | /** | 5055 | /** |
4928 | * do_s2io_prog_unicast - Programs the Xframe mac address | 5056 | * do_s2io_prog_unicast - Programs the Xframe mac address |
4929 | * @dev : pointer to the device structure. | 5057 | * @dev : pointer to the device structure. |
@@ -4933,11 +5061,14 @@ static int s2io_set_mac_addr(struct net_device *dev, void *p) | |||
4933 | * Return value: SUCCESS on success and an appropriate (-)ve integer | 5061 | * Return value: SUCCESS on success and an appropriate (-)ve integer |
4934 | * as defined in errno.h file on failure. | 5062 | * as defined in errno.h file on failure. |
4935 | */ | 5063 | */ |
5064 | |||
4936 | static int do_s2io_prog_unicast(struct net_device *dev, u8 *addr) | 5065 | static int do_s2io_prog_unicast(struct net_device *dev, u8 *addr) |
4937 | { | 5066 | { |
4938 | struct s2io_nic *sp = dev->priv; | 5067 | struct s2io_nic *sp = dev->priv; |
4939 | register u64 mac_addr = 0, perm_addr = 0; | 5068 | register u64 mac_addr = 0, perm_addr = 0; |
4940 | int i; | 5069 | int i; |
5070 | u64 tmp64; | ||
5071 | struct config_param *config = &sp->config; | ||
4941 | 5072 | ||
4942 | /* | 5073 | /* |
4943 | * Set the new MAC address as the new unicast filter and reflect this | 5074 | * Set the new MAC address as the new unicast filter and reflect this |
@@ -4955,9 +5086,26 @@ static int do_s2io_prog_unicast(struct net_device *dev, u8 *addr) | |||
4955 | if (mac_addr == perm_addr) | 5086 | if (mac_addr == perm_addr) |
4956 | return SUCCESS; | 5087 | return SUCCESS; |
4957 | 5088 | ||
5089 | /* check if the mac already preset in CAM */ | ||
5090 | for (i = 1; i < config->max_mac_addr; i++) { | ||
5091 | tmp64 = do_s2io_read_unicast_mc(sp, i); | ||
5092 | if (tmp64 == S2IO_DISABLE_MAC_ENTRY) /* CAM entry is empty */ | ||
5093 | break; | ||
5094 | |||
5095 | if (tmp64 == mac_addr) { | ||
5096 | DBG_PRINT(INFO_DBG, | ||
5097 | "MAC addr:0x%llx already present in CAM\n", | ||
5098 | (unsigned long long)mac_addr); | ||
5099 | return SUCCESS; | ||
5100 | } | ||
5101 | } | ||
5102 | if (i == config->max_mac_addr) { | ||
5103 | DBG_PRINT(ERR_DBG, "CAM full no space left for Unicast MAC\n"); | ||
5104 | return FAILURE; | ||
5105 | } | ||
4958 | /* Update the internal structure with this new mac address */ | 5106 | /* Update the internal structure with this new mac address */ |
4959 | do_s2io_copy_mac_addr(sp, 0, mac_addr); | 5107 | do_s2io_copy_mac_addr(sp, i, mac_addr); |
4960 | return (do_s2io_add_unicast(sp, mac_addr, 0)); | 5108 | return (do_s2io_add_mac(sp, mac_addr, i)); |
4961 | } | 5109 | } |
4962 | 5110 | ||
4963 | /** | 5111 | /** |
@@ -7651,7 +7799,7 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) | |||
7651 | */ | 7799 | */ |
7652 | bar0 = sp->bar0; | 7800 | bar0 = sp->bar0; |
7653 | val64 = RMAC_ADDR_CMD_MEM_RD | RMAC_ADDR_CMD_MEM_STROBE_NEW_CMD | | 7801 | val64 = RMAC_ADDR_CMD_MEM_RD | RMAC_ADDR_CMD_MEM_STROBE_NEW_CMD | |
7654 | RMAC_ADDR_CMD_MEM_OFFSET(0 + MAC_MAC_ADDR_START_OFFSET); | 7802 | RMAC_ADDR_CMD_MEM_OFFSET(0 + S2IO_MAC_ADDR_START_OFFSET); |
7655 | writeq(val64, &bar0->rmac_addr_cmd_mem); | 7803 | writeq(val64, &bar0->rmac_addr_cmd_mem); |
7656 | wait_for_cmd_complete(&bar0->rmac_addr_cmd_mem, | 7804 | wait_for_cmd_complete(&bar0->rmac_addr_cmd_mem, |
7657 | RMAC_ADDR_CMD_MEM_STROBE_CMD_EXECUTING, S2IO_BIT_RESET); | 7805 | RMAC_ADDR_CMD_MEM_STROBE_CMD_EXECUTING, S2IO_BIT_RESET); |
@@ -7671,6 +7819,20 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) | |||
7671 | memcpy(dev->dev_addr, sp->def_mac_addr, ETH_ALEN); | 7819 | memcpy(dev->dev_addr, sp->def_mac_addr, ETH_ALEN); |
7672 | memcpy(dev->perm_addr, dev->dev_addr, ETH_ALEN); | 7820 | memcpy(dev->perm_addr, dev->dev_addr, ETH_ALEN); |
7673 | 7821 | ||
7822 | /* initialize number of multicast & unicast MAC entries variables */ | ||
7823 | if (sp->device_type == XFRAME_I_DEVICE) { | ||
7824 | config->max_mc_addr = S2IO_XENA_MAX_MC_ADDRESSES; | ||
7825 | config->max_mac_addr = S2IO_XENA_MAX_MAC_ADDRESSES; | ||
7826 | config->mc_start_offset = S2IO_XENA_MC_ADDR_START_OFFSET; | ||
7827 | } else if (sp->device_type == XFRAME_II_DEVICE) { | ||
7828 | config->max_mc_addr = S2IO_HERC_MAX_MC_ADDRESSES; | ||
7829 | config->max_mac_addr = S2IO_HERC_MAX_MAC_ADDRESSES; | ||
7830 | config->mc_start_offset = S2IO_HERC_MC_ADDR_START_OFFSET; | ||
7831 | } | ||
7832 | |||
7833 | /* store mac addresses from CAM to s2io_nic structure */ | ||
7834 | do_s2io_store_unicast_mc(sp); | ||
7835 | |||
7674 | /* Store the values of the MSIX table in the s2io_nic structure */ | 7836 | /* Store the values of the MSIX table in the s2io_nic structure */ |
7675 | store_xmsi_data(sp); | 7837 | store_xmsi_data(sp); |
7676 | /* reset Nic and bring it to known state */ | 7838 | /* reset Nic and bring it to known state */ |
diff --git a/drivers/net/s2io.h b/drivers/net/s2io.h index cc1797a071aa..b944a948f19d 100644 --- a/drivers/net/s2io.h +++ b/drivers/net/s2io.h | |||
@@ -31,6 +31,7 @@ | |||
31 | #define SUCCESS 0 | 31 | #define SUCCESS 0 |
32 | #define FAILURE -1 | 32 | #define FAILURE -1 |
33 | #define S2IO_MINUS_ONE 0xFFFFFFFFFFFFFFFFULL | 33 | #define S2IO_MINUS_ONE 0xFFFFFFFFFFFFFFFFULL |
34 | #define S2IO_DISABLE_MAC_ENTRY 0xFFFFFFFFFFFFULL | ||
34 | #define S2IO_MAX_PCI_CONFIG_SPACE_REINIT 100 | 35 | #define S2IO_MAX_PCI_CONFIG_SPACE_REINIT 100 |
35 | #define S2IO_BIT_RESET 1 | 36 | #define S2IO_BIT_RESET 1 |
36 | #define S2IO_BIT_SET 2 | 37 | #define S2IO_BIT_SET 2 |
@@ -458,6 +459,9 @@ struct config_param { | |||
458 | #define MAX_MTU_JUMBO (MAX_PYLD_JUMBO+18) | 459 | #define MAX_MTU_JUMBO (MAX_PYLD_JUMBO+18) |
459 | #define MAX_MTU_JUMBO_VLAN (MAX_PYLD_JUMBO+22) | 460 | #define MAX_MTU_JUMBO_VLAN (MAX_PYLD_JUMBO+22) |
460 | u16 bus_speed; | 461 | u16 bus_speed; |
462 | int max_mc_addr; /* xena=64 herc=256 */ | ||
463 | int max_mac_addr; /* xena=16 herc=64 */ | ||
464 | int mc_start_offset; /* xena=16 herc=64 */ | ||
461 | }; | 465 | }; |
462 | 466 | ||
463 | /* Structure representing MAC Addrs */ | 467 | /* Structure representing MAC Addrs */ |
@@ -826,7 +830,7 @@ struct s2io_nic { | |||
826 | #define MAX_MAC_SUPPORTED 16 | 830 | #define MAX_MAC_SUPPORTED 16 |
827 | #define MAX_SUPPORTED_MULTICASTS MAX_MAC_SUPPORTED | 831 | #define MAX_SUPPORTED_MULTICASTS MAX_MAC_SUPPORTED |
828 | 832 | ||
829 | struct mac_addr def_mac_addr[MAX_MAC_SUPPORTED]; | 833 | struct mac_addr def_mac_addr[256]; |
830 | 834 | ||
831 | struct net_device_stats stats; | 835 | struct net_device_stats stats; |
832 | int high_dma_flag; | 836 | int high_dma_flag; |
@@ -853,7 +857,7 @@ struct s2io_nic { | |||
853 | #define MAX_ADDRS_SUPPORTED 64 | 857 | #define MAX_ADDRS_SUPPORTED 64 |
854 | u16 usr_addr_count; | 858 | u16 usr_addr_count; |
855 | u16 mc_addr_count; | 859 | u16 mc_addr_count; |
856 | struct usr_addr usr_addrs[MAX_ADDRS_SUPPORTED]; | 860 | struct usr_addr usr_addrs[256]; |
857 | 861 | ||
858 | u16 m_cast_flg; | 862 | u16 m_cast_flg; |
859 | u16 all_multi_pos; | 863 | u16 all_multi_pos; |
@@ -1066,6 +1070,12 @@ static int s2io_add_isr(struct s2io_nic * sp); | |||
1066 | static void s2io_rem_isr(struct s2io_nic * sp); | 1070 | static void s2io_rem_isr(struct s2io_nic * sp); |
1067 | 1071 | ||
1068 | static void restore_xmsi_data(struct s2io_nic *nic); | 1072 | static void restore_xmsi_data(struct s2io_nic *nic); |
1073 | static void do_s2io_store_unicast_mc(struct s2io_nic *sp); | ||
1074 | static void do_s2io_restore_unicast_mc(struct s2io_nic *sp); | ||
1075 | static u64 do_s2io_read_unicast_mc(struct s2io_nic *sp, int offset); | ||
1076 | static int do_s2io_add_mc(struct s2io_nic *sp, u8 *addr); | ||
1077 | static int do_s2io_add_mac(struct s2io_nic *sp, u64 addr, int offset); | ||
1078 | static int do_s2io_delete_unicast_mc(struct s2io_nic *sp, u64 addr); | ||
1069 | 1079 | ||
1070 | static int | 1080 | static int |
1071 | s2io_club_tcp_session(u8 *buffer, u8 **tcp, u32 *tcp_len, struct lro **lro, | 1081 | s2io_club_tcp_session(u8 *buffer, u8 **tcp, u32 *tcp_len, struct lro **lro, |