diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/net/wireless/b43legacy/dma.c | 66 |
1 files changed, 51 insertions, 15 deletions
diff --git a/drivers/net/wireless/b43legacy/dma.c b/drivers/net/wireless/b43legacy/dma.c index eb0243a22691..fb6819e40f38 100644 --- a/drivers/net/wireless/b43legacy/dma.c +++ b/drivers/net/wireless/b43legacy/dma.c | |||
@@ -859,6 +859,18 @@ static u64 supported_dma_mask(struct b43legacy_wldev *dev) | |||
859 | return DMA_30BIT_MASK; | 859 | return DMA_30BIT_MASK; |
860 | } | 860 | } |
861 | 861 | ||
862 | static enum b43legacy_dmatype dma_mask_to_engine_type(u64 dmamask) | ||
863 | { | ||
864 | if (dmamask == DMA_30BIT_MASK) | ||
865 | return B43legacy_DMA_30BIT; | ||
866 | if (dmamask == DMA_32BIT_MASK) | ||
867 | return B43legacy_DMA_32BIT; | ||
868 | if (dmamask == DMA_64BIT_MASK) | ||
869 | return B43legacy_DMA_64BIT; | ||
870 | B43legacy_WARN_ON(1); | ||
871 | return B43legacy_DMA_30BIT; | ||
872 | } | ||
873 | |||
862 | /* Main initialization function. */ | 874 | /* Main initialization function. */ |
863 | static | 875 | static |
864 | struct b43legacy_dmaring *b43legacy_setup_dmaring(struct b43legacy_wldev *dev, | 876 | struct b43legacy_dmaring *b43legacy_setup_dmaring(struct b43legacy_wldev *dev, |
@@ -1018,6 +1030,43 @@ void b43legacy_dma_free(struct b43legacy_wldev *dev) | |||
1018 | dma->tx_ring0 = NULL; | 1030 | dma->tx_ring0 = NULL; |
1019 | } | 1031 | } |
1020 | 1032 | ||
1033 | static int b43legacy_dma_set_mask(struct b43legacy_wldev *dev, u64 mask) | ||
1034 | { | ||
1035 | u64 orig_mask = mask; | ||
1036 | bool fallback = 0; | ||
1037 | int err; | ||
1038 | |||
1039 | /* Try to set the DMA mask. If it fails, try falling back to a | ||
1040 | * lower mask, as we can always also support a lower one. */ | ||
1041 | while (1) { | ||
1042 | err = ssb_dma_set_mask(dev->dev, mask); | ||
1043 | if (!err) | ||
1044 | break; | ||
1045 | if (mask == DMA_64BIT_MASK) { | ||
1046 | mask = DMA_32BIT_MASK; | ||
1047 | fallback = 1; | ||
1048 | continue; | ||
1049 | } | ||
1050 | if (mask == DMA_32BIT_MASK) { | ||
1051 | mask = DMA_30BIT_MASK; | ||
1052 | fallback = 1; | ||
1053 | continue; | ||
1054 | } | ||
1055 | b43legacyerr(dev->wl, "The machine/kernel does not support " | ||
1056 | "the required %u-bit DMA mask\n", | ||
1057 | (unsigned int)dma_mask_to_engine_type(orig_mask)); | ||
1058 | return -EOPNOTSUPP; | ||
1059 | } | ||
1060 | if (fallback) { | ||
1061 | b43legacyinfo(dev->wl, "DMA mask fallback from %u-bit to %u-" | ||
1062 | "bit\n", | ||
1063 | (unsigned int)dma_mask_to_engine_type(orig_mask), | ||
1064 | (unsigned int)dma_mask_to_engine_type(mask)); | ||
1065 | } | ||
1066 | |||
1067 | return 0; | ||
1068 | } | ||
1069 | |||
1021 | int b43legacy_dma_init(struct b43legacy_wldev *dev) | 1070 | int b43legacy_dma_init(struct b43legacy_wldev *dev) |
1022 | { | 1071 | { |
1023 | struct b43legacy_dma *dma = &dev->dma; | 1072 | struct b43legacy_dma *dma = &dev->dma; |
@@ -1027,21 +1076,8 @@ int b43legacy_dma_init(struct b43legacy_wldev *dev) | |||
1027 | enum b43legacy_dmatype type; | 1076 | enum b43legacy_dmatype type; |
1028 | 1077 | ||
1029 | dmamask = supported_dma_mask(dev); | 1078 | dmamask = supported_dma_mask(dev); |
1030 | switch (dmamask) { | 1079 | type = dma_mask_to_engine_type(dmamask); |
1031 | default: | 1080 | err = b43legacy_dma_set_mask(dev, dmamask); |
1032 | B43legacy_WARN_ON(1); | ||
1033 | case DMA_30BIT_MASK: | ||
1034 | type = B43legacy_DMA_30BIT; | ||
1035 | break; | ||
1036 | case DMA_32BIT_MASK: | ||
1037 | type = B43legacy_DMA_32BIT; | ||
1038 | break; | ||
1039 | case DMA_64BIT_MASK: | ||
1040 | type = B43legacy_DMA_64BIT; | ||
1041 | break; | ||
1042 | } | ||
1043 | |||
1044 | err = ssb_dma_set_mask(dev->dev, dmamask); | ||
1045 | if (err) { | 1081 | if (err) { |
1046 | #ifdef CONFIG_B43LEGACY_PIO | 1082 | #ifdef CONFIG_B43LEGACY_PIO |
1047 | b43legacywarn(dev->wl, "DMA for this device not supported. " | 1083 | b43legacywarn(dev->wl, "DMA for this device not supported. " |